C++ 兴起的背景
在机器学习开始兴起的时候,人们使用Python和Java的比较多,但随着大数据时代的到来和人工智能的发展。在真实的产品开发中,使用C++的人越来越多,C++的优势得以凸显,主要是因为性能,因为我们知道训练需要做大量的运算,希望直接控制cpu,C++之所以强大、包罗万象,在于它的灵活性,我们可以自由的操作指针和内存。这是Python、Java、JavaScript无法比拟的。还有,异构运算,人们不仅需要操作CPU,在大数据时代,需要协同GPU做并行计算和性能调优。所以,之前的文章我们用Python,是因为它简单易用,适合做学习和研究,但在真正的产品实践中,我们主要使用C和C++,因此,为了让大家能够平滑过渡,我们分几篇文章讲一讲C++,没学过也没关系,今天讲C++基础语法,后面分几节课讲讲C++里面的一些坑,和C++ 11、C++14、C++17,也就是现代C++里面的新语法和用法。
如何利用Xcode新建C++ 项目
打开Xcode,依次点击工具栏:File/New/Project,会看到如下界面,选择Command Line Tool ,点击Next.
给个工程名字,语言选C++,点击Next即可完成。
C++ 基础语法
本篇内容概要
1. 基本类型 int double float string 等;
2. 类型转换、数值类型转 string,string转数值类型;
std::to_string
std::stof
std::stod
std::stoi
3. 标准输出 std::cout
std::endl
printf
4. while do/while for 循环
5. 数组的基本用法
6. 基本内存管理(声明类、分配对象、指针、delete)
基本类型定义
// 以前用int,现代C++我们推荐使用int32_t定义int类型
int32_t a = 1;
double_t b = 1.1;
float_t c = 1.1;
std:: string str = "this is a string";
std:: cout << a << b << c << str << "\n";
// Prints 11.11.1this is a string
类型转换
数值类型 ——> string
std:: string str2 = std::to_string(a);
std:: string str3 = std::to_string(b);
std:: string str4 = std::to_string(c);
// 标准输出
std:: cout<< "this is an output string:" << str2 << str3 << str4 << std::endl;
// Prints this is an output string:11.1000001.100000
string ——> 数值类型
int32_t d = std::stoi(str2); // stoi:string to int
std::cout << "string to int:" << d << std::endl;
// Prints string to int:1
Note
不像Python、JavaScript它们是弱类型的编程语言,C++是强类型的编程语言,我们把字符串转化为数字或将数字转化为字符串都需要做额外的工作,C++为什么会这么做,它天生是一门强类型的语言; 另外确保C++执行的效率,它的类型定义在程序编译的时候就已经固化在里面了,它不像Java或C Sharp 这样的编程语言,很多时候可以在运行时做一些动态的转换。
循环语句
先写最基本的,一些带有迭代器的高级循环后面写容器的时候再说。
for 语句
for (int32_t i = 0; i < 5; i++) {
printf("%d\n",i);
}
// Prints
0
1
2
3
4
while 循环
int32_t sum = 10;
int32_t j = 5;
while (sum > j) {
j++;
std::cout << j << std::endl;
}
// Prints
6
7
8
9
10
do/while 循环
int32_t m = 10;
int32_t n = 5;
do {
n++;
std::cout << n << std::endl;
} while (m > n);
// Prints
6
7
8
9
10
数组的基本用法
数组的两种声明方式
int32_t array[5] = {1,2,3,4,5}; // 方法1
int32_t * array2 = new int32_t[5]; // 方法2,指针
这两种声明方式有什么不同
第二种声明方式我们使用了C++当中的指针概念,并且向系统申请了5个4字节32位的内存。这涉及到栈和堆的概念了,stack and heap are important to C++。
如图:
我向堆申请了5块4字节的内存,并且我在栈上定义了一个指针类型的数组变量array2,并将它的指针指向五块连续内存的首地址。
向数组内添加元素
for (int32_t i = 0; i < 5; i++) {
array2[i] = i;
std:: cout << array2[i] << std::endl;
}
// Prints
0
1
2
3
4
二维数组
需要定义两个维度,并需要两层for循环来控制。
// array3 [4][5]
// for
// for
基本内存管理
刚刚我们定义array2的时候申请了内存,不用的时候需要释放掉。
delete [] array2;
Note
内存释放,C++里面需要程序员自己管理内存,自己申请的内存自己用完释放掉,否则,会产生内存泄漏,甚至更严重的问题,如果不释放,内存将被永久占用。那如果我是多线程,又加锁又同步的,我怎么知道什么时候该释放呢,这就涉及到智能指针,后面再讲智能指针怎么帮我们管理可分配的内存。
综合代码实现
本节是前面各节用例的综合展示,以文件的形式展示了类的创建、函数的调用、包的代入及相关注释等。
main.cpp
file codes
#include <iostream>
/* 字符串类型推荐大家导入<string>,还有其他方法我们后面在说,
它的命名空间是std::,它来自STL:Standard template library,
标准库里面包含了一些容器的集合,链表、数组、map(key value键值对)等
*/
#include <string>
// 为了保险起见,建议大家包含以下两个头文件,这样程序会更完整、更可靠一些,保证在不同编译环境下能编译通过
#include <cstdint> // 含int类型定义
#include <cmath> // 含double_t float_t 引用
void function() {
// 基本类型定义
int32_t a = 1; // 以前用int,现代C++我们推荐使用int32_t定义类型
double_t b = 1.1;
float_t c = 1.1;
std:: string str = "this is a string";
std:: cout << a << b << c << str << "\n";
// 类型转换
// 数值类型 --> String
std:: string str2 = std::to_string(a);
std:: string str3 = std::to_string(b);
std:: string str4 = std::to_string(c);
// 标准输出
std:: cout<< "this is an output string:" << str2 << str3 << str4 << std::endl;
// string --> 数值类型
int32_t d = std::stoi(str2); // stoi:string to int
std::cout << "string to int:" << d << std::endl;
/* 不像Python、JavaScript它们是弱类型的编程语言,C++
是强类型的编程语言,我们把字符串转化为数字或将数字转化为字符串
都需要做额外的工作,C++为什么会这么做,它天生是一门强类型的语言;
另外确保C++执行的效率,它的类型定义在程序编译的时候就已经固化在
里面了,它不像Java或C Sharp 这样的编程语言,很多时候可以在运行时
做一些动态的转换。
*/
return;
}
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "Hello, World!\n";
// 函数调用
function();
// 循环语句:一些带有迭代器的高级循环后面讲容器的时候在说。
// for
for (int32_t i = 0; i < 10; i++) {
printf("%d\n",i);
}
// wihie
int32_t sum = 10;
int32_t j = 5;
while (sum > j) {
j++;
std::cout << j << std::endl;
}
// do while
int32_t m = 10;
int32_t n = 5;
do {
n++;
std::cout << n << std::endl;
} while (m > n);
// 数组基本用法--数组声明
// 这两种定义方式有什么不同,这就涉及到栈和堆的概念了
// stack, heap are important to C++
int32_t array[5] = {1,2,3,4,5}; // 方法1
int32_t * array2 = new int32_t[5]; // 方法2,指针
// append element to array2.
for (int32_t i = 0; i < 5; i++) {
array2[i] = i;
std:: cout << array2[i] << std::endl;
}
// 二维数组
// array3 [4][5]
// for
// for
/* 内存释放,C++里面需要程序员自己管理内存,自己申请的内存自己用完释放掉,
否则,会产生内存泄漏,甚至更严重的问题,如果不释放,内存将被永久占用。那如果
我是多线程,又加锁又同步的,我怎么知道什么时候该释放呢,这就涉及到智能指针,后面再讲智能指针怎么帮我们管理可分配的内存。
*/
// array2 由于我们申请了内存,需要释放掉。
delete [] array2;
return 0;
}