名称C++来自C语言中的递增运算符++,该运算符将变量加1。名称C++表明,它是C的扩充版本。——《C++ Primer Plus》。

​ 相较于C语言C++提供了更多的高级特性,使其功能更强大,也更复杂。本文总结了一些C++相较于C语言不同的特性。相较于面向过程编程,OPP更强调数据。

1 C++文件扩展名

​ C++文件在不同系统上支持的扩展名不同,具体支持类型如下。

2 I/O库

​ C++使用I/O库iostream,该库位于命名空间std中。C++的头文件没有扩展名.h,C语言的有文件可以去掉扩展名并且在文件名前加上c,也可以变成C++中的头文件。但是使用#include <iostream>时需要确定命名空间。命名空间用于划分程序结构,不同命名空间中可以存在同名函数。C++编译器中类、函数和变量等标准组件都放在命名空间std中。

#include <iostream>
#include <cmath>
using namespace std;    

​ 或者使用::符号来指定不同命名空间

std::cout << "hello" <<endl;

2.1 cout 关键词

​ 使用cout关键词进行输出消息,<< 表示将变量发送给coutendl(endLine)表示重启一行

cout << "hello" << endl;

2.2 cin 关键词

cin关键词用于输入信息,符号>><<表示数据流向。cin使用空格、制表符、换行符(space \t \n)来确定输入字符串的结束位置。

cin类提供了一系列函数用于输入,其中cin.getlinecin.get来读取一行输入。cin.getline读取后会将换行符(\n)丢弃,而cin.get会保留换行符。

cin >> var;
cin.getline(name,len);//指定输入的数组名以及数组长度
cin.get(name,len);//输入参数同getline
cin.get();//cin.get不跟参数则会读取下一个字符

3 数据处理

​ 在变量后面跟上后缀可以表示变量的类型

  • long:l或L
  • 无符号整型:u或者U
  • 对于宽字符wchar_t 类型可用使用L做前缀表示,L"tall"

3.1 auto关键字(c++ 11)

​ 初始化变量时,使用auto变量,编译器将变量类型设置为和初始值一样。

3.2 数组初始化(c++11)

  • 初始化数组是可以省略=int arr[4] {1,2,3,4};
  • {}不包括任何内容则初始化为0,int arr[4] {};//初始化为0

3.3 string类

string作为一种表示字符串的数据类型,使用上比char类型的数组简单。使用string类需要包含头文件stringstring类型可以直接将字符串声明为一个类型,而不是一个字符数组。可以把string看作一个数据类型。

#include <iostream>
#include <string>
using namespace std;    

string str1 = {"Cest la vie"};
string str2 = str1;//string类型可以直接赋值
string str3 = str1 + str2;//string类型可以直接使用+号进行拼接
str1 += str1;//同样可以进行自加操作
int len = str1.size()//string类内置了size函数来确定字符串长度

3.4 原始字符串(c++11)

​ 在原始(raw)字符串中字符串仅仅表示其本身,例如\n不表示换行符而是其本身。原始字符串使用前缀R以及"()"表示。

cout << R"(Kim "abs" \n "\n")" <<eldl;
//当原始字符串中需要包含括号时可以自定义标识符
cout << R"+*(Kim "abs" (\n) "\n")+*" <<eldl;

3.5 结构体

​ c++中结构体作为变量类型时可以省略struct关键字

struct numSet 
{
    int a;
    char b;
    float c;
};

//以下两种写法都可
struct numSet exp;
numSet exp;
exp = {1, 'a', 2.33}//赋值可以省略变量名,按照顺序赋值即可。

#### 3.6 new和delete 内存分配与回收

​ c++中使用new关键字来进行内存分配,使用delete关键字进行内存回收。new的使用语法如下typeName* pointer = new typeNamenew返回分配内存的地址。对于大型数据可以使用new来创建动态数组,通用格式如下typeName * pointer = new typeName[size]

int* pt = new int;//为int型指针pt分配sizeof(int)大小的指针
delete pt;//回收分配的内存空间
//new 和 delete需要成对出现避免内存泄露

int* psome = new int [10]//创建长度为10的int型数组
delete [] psome;//释放动态数组

对于newdelete的使用要遵循以下规则:

  • 不要使用delete来销毁非new分配的内存
  • 不要使用delete来销毁同一块内存两次
  • 使用new []建立动态数组,则要使用delete []来释放
  • 使用new []为一个实体分配内存,则要使用delete来释放
  • 对空指针使用delete是安全的

4 数组的替代品

4.1 vector 模板类

vector类是一种动态数组,实现了数据追加、插入等功能,可以作为动态数组的替代品。使用vector需要包含头文件<vector>,其通用声明语法是vector<typeName> vt(size)

#include <vector>    
using namespace std;

vector<int> vt(8);

4.2 array 模板类(c++11)

vector类功能强大但是速度稍慢,c++11推出了array类,array类固定长度,使用栈来存储,效率与数组相同,使用array类需要包含头文件<array>,其通用声明语法是array<typeName, size> arr,其中size只能是常量。

#include <array>    
using namespace std;

array<int, 8> ar;

数组、vector、array都可以使用标准数组表示法来访问其成员

5 循环

c++11提供了一种基于范围的循环方式。

double prices[5] = {1.2, 2.3, 3.2, 4.4, 5.3};
for (double x : prices)//x从prices中第一个元素循环到最后一个元素
    cout << x <<endl;

6 函数

6.1 函数指针

  • c++中函数指针的定义方式如下data_types (*func_pointer)(argList);
  • c++中函数指针数组的定义如下data_types (*func_pointer)[3] (argList);
  • c++中可以使用typedef来简化函数指针类型的定义
  typedef data_types(*pFunc) (argList)
  pFunc p1 = f1;

6.2 内联函数

​ 使用内联函数可以提高c++程序运行速度,编译器使用函数的代码替换掉相应的函数调用。内联函数的运行速度会快于函数调用,但是会消耗更多内存。使用内联函数需要在函数声明或定义时加上inline前缀。

inline double square(double x);

6.3 引用变量

​ 相较于C语言,c++新增了一种变量类型引用变量,引用是对一个已定义变量的别名。在函数调用中若将引用变量作为参数,则函数将直接使用该变量,而不是其副本。引用变量的通用格式如下typeName & var,其中&作为引用标量的标志。

int rat;
int & rodent = rat;//rat和rodent指向同一个变量