C语言作为结构化和模块化语言能够得心应手的处理小规模的程序,但是当一个问题需要高度抽象和建模时,C语言便力不从心,c++语言便在贝尔实验室被bs博士创造出来,其最初的名字为 c with class ,后来更名为c++,其含义为在完全兼容c的基础上,扩展了c的语法,增加了面向对象的特性,加入了STL 等。
1 c++ 对C 的扩展
1.1 类型检查更加严格
const 常量在c 语言中可通过指针对其修改,在C语言中人们称const 不是真正的常量,而是一个只读变量,但在c++中常量变成了真正的常量,例:
const int a = 10;
int* pa = &a;
在c++编译环境中,会提示 初始化”: 无法从“const int *”转换为“int *” 的 错误。
1.2 布尔类型
c++中加入了真正的 bool 类型, 其值为 true 或者 false
1.3 枚举类型
在C语言中枚举本质是一个整形,而在c++中则变成可真正的枚举, 定义的枚举变量只能用枚举中的元素初始化
1.4 cin cout 流对象
cin cout 的格式化控制 ----- 需要加入头文件 #include <iomanip>
setprecision(n) 用于设置有效位数
setw(n) 用于设置域宽
setfill(“char”) 设置 填充字符
setiosflags(ios::left) 左对齐 setiosflags(ios::right) 右对齐
1.4 函数重载
前期对此知识点有过接触,这里简单重温一下
重载规则:函数名相同, 参数个数、 类型、参数顺序不同可构成重载,注意 返回类型不能决定重载
函数重载匹配的规则:严格按照参数匹配,有则调用。参数的隐式转换也可以寻求重载 匹配但有时会引发重载的二义性 ambiguous 例如 int对于 long double两种函数入参
类型,则会编译出现二意性错误。
重载的底层实现: 底层采用 倾轧(name manling)的技术,相同函数名但不同的入参其在底层函数名并不相同。由于c++ 完全兼容c 语言,可以使用extern "C" 的方法,
在源文件和头文件避免函数被倾轧,使得c++代码兼容C语言风格。
1.5 操作符重载(operator overload)
c++中认为 操作符便是函数,函数便可以重载,(其实c++中并不是所有的操作符都可以重载),我们看一个经典的例子:
Complex operator+(Complex a, Complex b)
{
Complex ret;
ret.real = a.real + b.real;
ret.image = a.image + b.image;
return ret;
}
此函数便实现了 + 操作符 在复数运算中的重载;在 计算 Complex 类型变量的加法时便可以直接使用 + 操作符;
1.6 c++中的默认参数
默认参数一般在声明处使用就可以,默认参数的使用规则:
默认参数在函数参数列表中要从右到左使用,不可以跳跃。
默认参数函数不可以和函数重载同时使用,否则容易引发二义性错误
1.7 c++中的引用
c++ 中引入了应用的概念,其为变量的别名,在使用时不会开辟内存空间,即本质是一个声明。关于应用这里有几点需要说明:
1 引用不会占用内存,其地址与其引用的变量有相同的地址,且类型与原变量类型保持一致。
2 引用在声明的同时必须初始化,且一经初始化便不可更改。可以对引用再次引用,使一个变量能够具有多个别名。例:
int a = 10;
int& ra = a;
int& raa = ra;
3 引用多用在 函数的形参中,这样可以代替原来C语言中的 指针形参。 在这里 引用的本质是指针,是对裸露的内存地址做了一次包装,所以这里如果在对引用取地址就变得没有意义,违背了程序设计者的初衷。所以这里便又得出了一个使用规则,这里作为第四条总结一下。
4 可以定义指针的引用但不可以定义引用的指针。这里还有一个变体规则,可以定义数组的引用,但不可以定义引用的数组。例如
int arr[2] = {0,1};
int (&rarr)[2] = arr;
这样来声明一个数组的引用是没有问题的,但是下面
int & rarr[2] = {0,1};
这样来声明引用的数组是非法的,其本质,是使用的引用的引用。ps 数组可以看作一个指针。
最后总结一下,说一千道一万,引用和指针有一个很大的区别,指针的指针合法,引用的引用非法。