1)C++简介
C++是C语言的扩展,因此C++是C语言的超集,任何有效的C程序都是有效的C++程序,C++可以使用已有的C程序库。
C++在C语言上增加了面向对象编程和泛型编程的支持。
2)可移植性和标准
ANSI在1998年制定出了一个国际标准,不仅描述了已有的C++特性,还对语言进行了扩展,增加了异常、运行阶段类型识别(RTTI)、模板和标准模板库(STL)。
3)面向过程和面向对象
面向过程的核心思想是:功能分解,自顶向下,逐层细化 (程序=数据结构+算法)
面向对象(OOP):使用多个相互独立的代码模块,每个模块提供特定功能,易于开发维护和升级,算法和数据结构看成一个整体,任何对象都有一定的属性和操作。 (程序=对象+对象)
4)面向对象的三大特性:封装、继承、多态。
1)双冒号:作用域运算符
作用域有就近原则,::为全局作用域,后面加变量名会输出全局变量的值。
2)命名空间namespace使用:namespace主要用来解决命名冲突的问题
命名空间下可以放变量 函数 结构体 类;
命名空间必须定义在全局作用域下;
命名空间可以嵌套命名空间;
命名空间是开放的,可以随时往原来的命名空间中增加内容;
无名/匿名命名空间相当于静态变量,只能在当前文件内使用;
命名空间可以起别名。
3)using声明和using编译指令
写了using声明之后,表明局部变量的命名空间,要避免和局部变量的二义性问题。
如果用using打开多个房间,也要注意二义性的问题。
1)全局变量检测增强
- #include
- using namespace std;
-
- int a;
- int a = 10;
-
- int main() {
- return 0;
- }
这种全局变量的声明方法在C语言中不会被检测出来,在C++中会被判定为重定义错误。
2)函数检测增强
- #include
- using namespace std;
-
- int getS(w, h) {
- }
-
- void test02() {
- getS(10,10,10);
- }
-
- int main() {
- return 0;
- }
这种函数写法,getS没写明返回值以及参数类型,test02中函数调用参数不匹配,在C语言不会被检测出来,C++语言生成失败。
3)类型转换检测增强
- #include
- using namespace std;
-
- void test03() {
- //在C语言中void*可以被任何类型代替
- char* p = malloc(sizeof(64)); //malloc返回值为void*
- }
-
- int main() {
- return 0;
- }
void*在C语言中可以被任何类型代替,在C++须进行强转,char* p = (char*)malloc(sizeof(64))。
4)struct增强
- #include
- using namespace std;
-
- struct Person() {
- int age;
- void plusAge() {age++;}; //C语言中不能加函数
- }
-
- void test04() {
- Person p1; //C语言使用时前面必须加struct
- p1.age = 10;
- p1.plusAge();
- cout << p1.age << endl;
- }
-
- int main() {
- return 0;
- }
C语言中struct不能加函数,C++中可以加函数;C语言使用时必须加入struct关键字。
5)bool类型增强
C语言中没有bool类型,C++中提供了bool类型,所有非零值都转换为1。
6)三目运算符增强
-
- void test06() {
- int a = 20;
- int b = 10;
- cout << "ret = " << (a>b?a:b) << endl;
- }
直接写(a>b?a:b) = 100,C语言报错,C++将a赋值为10,三目运算符C返回的是数值,C++返回的是变量。C语言中如果要返回变量要加取地址符*(a > b ? &a : &b) = 100。
7)const增强
- void test07() {
- const int b = 20;
- int *p = (int*)&b;
- *p = 200;
- }
全局区域的const是受到保护的,都不可更改。
C语言中局部变量const修饰的变量会给b分配内存,可以通过指针进行修改,为伪常量,不能用于初始化数组;C++中const不会给b分配内存,不能被修改,为真正常量,可以初始化数组。
C语言中const默认是外部链接,C++中const默认是内部链接。
8)const分配内存的情况
const取地址时会分配一个临时内存,改变的是临时内存的值,而不是常量的。
- int tmp = b;
- int *p = (int *)&tmp;
如果const前面加了extern作用域设为全局,就会给const分配内存。
用普通变量初始化const变量,会给const分配内存。分配了内存的变量都可以用指针进行修改。
自定义数据类型加const也会分配内存。比如定义结构体Person并声明const Person p1,会给p1分配内存。
9)尽量用const代替define(宏定义)
const有类型,可进行编译器安全类型检查,define没有类型,不可进行类型检查;
const有作用域,define不重视作用域,默认从定义处到文件尾,如果定义在作用域下的有效常量,define就不适用。
1)引用的基本语法
引用是C++对C的重要扩充,在C/C++中指针的作用是一样的,但是在C++中增加了另外一种函数传递地址的途径,就是引用传递。
- void test() {
- int a = 20;
-
- //&写在等号左侧表示引用,写在等号右侧表示取地址
- int &b = a; //b对a进行引用
-
- b = 100; //此时a也被修改为20
- }
-
引用必须初始化,不能只写int &b;引用初始化后不可修改。
2)对数组建立引用
- void test() {
- int arr[10];
- for(int i = 0; i<10; i++) {
- arr[i] = i;
- }
-
- //对数组进行引用
- int (&pArr[10]) = arr;
-
- //第二种方法给数组起别名
- typdef int (array)[10];
- array &pArr2 = arr;
- }
3)参数的传递方式
参数的传递方式有值传递、地址传递、引用传递。
- void mySwap(int a, int b) { //值传递
- int tmp = a;
- a = b;
- b = tmp;
- }
-
- void test() {
- int a = 10;
- int b = 20;
- mySwap(a, b);
- }
以上方法进行参数传递时,并没有改变test里面a和b的数值,只有mySwap里的数进行了互换,常用于不改变原值,只要返回值的情况,如果要对原来的值进行互换,需要地址传递,或者引用传递。
- void mySwap(int *a, int *b) {
- int tmp = *a;
- *a = *b;
- *b = tmp;
- }
-
- void test() {
- int a = 10;
- int b = 20;
- mySwap(&a, &b);
- }
4)引用的注意事项
引用必须要引一块合法的内存空间,比如 int &a = 10不合法;
不要返回一个局部变量的引用,局部变量在函数结束后生命周期就会结束;
想要返回局部变量的引用需要在局部变量前加上static,将其保存住;
如果函数的返回值是引用,那么这个函数调用可以作为左值;
5)引用的本质
引用的本质在C++内部实现是一个指针常量。
6)指针的引用
利用指针的引用开辟空间。
- struct Person() {
- int age;
- }
-
- void allocatMemory(Person* &p) {
- p = (Person*) malloc(sizeof(Person));
- p->age = 20;
- }
-
- void test() {
- Person* p = NULL;
- alloctMemory(p);
- cout << "P的年龄" << p->age << endl;
- }
7)常量引用
const int &ref = 10;
前面加入const后,编译器会处理为const tmp= 10; const int &ref = tmp;此时不会被判定为引用了不合法的内存,此时ref的值可以用过指针进行修改。
- int *p = (int*)&ref;
- *p = 100;
常量引用的使用场景通常是用来修饰形参为只读。
- void showValue(int &val) {
- //如果只想显示内容,而不修改内容,就用const修饰
- val += 100;
- }
-
- void test() {
- int a = 10;
- showValue(a);
- }
PS:
1.阻塞功能:system("pause")
2.返回正常退出:return EXIT_SUCCESS,EXIT_SUCCESS是一个宏,它的值就是0