- C++与C的区别
- 字面上: C++完全兼容C语言, 只要是合法的C语言程序在C++中都是可以直接运行的。多的++表示C++中扩充了很多新的特性出来:数据类型、关键字等等。
- 思想上:C语言是一种面向过程的结构化程序设计语言;C++是一种面向对象的编程语言!在C++中万物兼对象!
C也有在面向对象,例如结构体,只不过面向对象不够彻底
面向过程:注重的是过程, 只有过程对了才有可能得到正确的结果
面向对象:注重的是结果,不关注过程是怎么实现的只要结果正确就好!
西红柿炒蛋:
面向过程:从买菜到做出来,都要按步骤一步一步的来
面向对象:直接点一份外卖,坐等着吃就可以了
C++:编程语言更接近实际生活,更接近自然界的发展规律! 一切事物都是对象。
- 编译器是不一样: gcc g++
- 源文件: .c .cpp
C++应用:
- Qt --用户图形界面 全部都是用C++实现
- 人工智能----图形图像处理 opencv
- 游戏开发
C++中的新特性:
学习思路:
是什么? 什么时候在哪里用?为什么? 怎么用?
3W1H
- 命名空间
解决什么问题?
在C语言中,在同一个作用域内是不允许出现同名的变量、函数、自定义的数据类型!
思考:
在实际生活中,一个校区能否出现同名的人?一个班级能都出现同名的学生?
是允许有这种情况发生!
如何区分呢? 给加上一个归属,来区分不同的变量、函数、自定义的数据类型!
解决命名冲突的问题
是什么样子的?
格式: namespace 命名空间的名字
{
变量; 函数; 自定义的数据类型
};
命名空间分为:自定义的命名空间 标准的命名空间
怎么用?
//命名空间里面内容的访问:
//格式: 《1》 命名空间的名字::成员 ===》相当老师在办公室叫某个学生
《2》 using namespace 命名空间的名字; 直接使用 ===》相当于老师进入班级中叫学生
- 标准输入输出流
在C里面有标准的输入输出的库函数: printf、scanf函数,在C++中一样是可以使用!
C++中也有提供属于它自己的输入输出 流 stream
什么是流: 以字节为单位、方向一致的连续不断的就是流!
输入流:
格式:cin>> 变量;
输出流:
格式: cout<< 变量 <<endl;
使用:
引入头文件: #include <iostream>
标准的命名空间: using namespace std;
好处: 格式简单,使用方便
代码验证:
- 引用类型
是C++中特有的一个数据类型
解决问题:
- 弱化指针 ,原来能用指针实现的,现在都可以替换成引用类型。
int a = 0;
int *p = &a; //定义变量,系统要给它分配内存空间,当函数调用结束后,空间会被释放掉。
- 减少临时空间的分配,那是因为定义一个引用类型是不需要分配内存空间,引用是特殊的类型,它是用来给变量起别名!
什么是引用:
就是给变量起别名 相当于给变量重写起个小名,它和变量指向的是同一块内存空间!
定义格式:
数据类型 &引用名字 = 变量名; //引用一定要进行初始化,给谁起别名,一定要说清楚!
案例:两数交换
注意:const修饰的变量,值是不可修改的----可以理解成是常量
- 定义常量的时候,可以用const去修饰变量
- 函数参数设计上,会把参数用const去修饰,目的是在使用的过程中,希望这个参数的值不要发生变化,可以保证数据的安全性。
高频面试题目:指针与引用的区别?
是什么? 特点有哪些? 应用场景?
- 指针是用来保存地址的;引用是给变量起别名的
- 指针变量定义的时候会分配内存空间;引用并不会分配空间
- 指针变量可以给初始化也可以不初始化,但是为了避免野指针,建议初始化为NULL;引用一定要进行初始化;
- 指针变量指向的地址是可以变化的;引用一旦给一个变量起了别名,是不可以再给其他的变量起别名了!所以使用引用比使用指针更安全
- 都可以应用在函数参数设计上!优先选择引用做参数!
- 函数重载
两数求和,设计函数:
int add(int a, int b){}
double add(double a, double b){}
char add(char a, char b){}…
解决问题:函数功能相似,函数参数不同,函数名命名困难的一组函数。
函数重载定义:函数名相同,功能相似,参数不同(参数的个数不同、参数类型不用、参数类型的顺序不用),与返回值类型无关的一组函数构成重载!
函数调用的原理:
每一个函数在内存中都有一块内存空间。
根据函数名找到对应的代码块去执行,执行完之后返回到调用的地方,继续往下执行!
因为函数名指的就是函数的地址,也是函数的入口!
同一个.c文件,用gcc编译和g++编译,发现使用gcc编译,函数名没有发生变化;使用g++编译,函数名发生变化,进行了重命名(根据函数名长度以及函数参数类型、个数进行重命名)。
函数名不用了,函数对应的地址也就不一样了,那么调用的时候执行的就是不同的函数体!
总结函数重载的原理:
使用g++进行编译的时候,会对函数名根据函数名长度、参数类型以及参数个数进行重命名。函数名不同,对应的函数在内存中的地址也就不一样,执行不同的函数体!
- 参数默认值
参数默认值: 就是在函数定义的时候给形参赋一个初始值
注意:
- 当函数参数有默认值的时候,调用函数的时候可以传参也可以不传参;如果有传参,就按传进来的数据参与函数内部操作,如果没有传参,按默认值参与函数内部操作!
- 在函数重载的情况下,当函数参数有默认值的时候,要注意二义性的产生
- 在函数重载的情况下,如果只有参数个数不同的情况下,可以通过给函数参数默认值减少代码冗余,只要写一个函数就可以实现多个函数存在的问题!
- 参数默认值给的顺序必须从右向左;因为参数匹配的顺序是从左向右的
- 当函数声明和函数定义同时存在的时候,参数的默认值只能在一个地方出现。在函数声明的时候给默认值即可!
- 如何在C++中引入C的库
在C++中引入C的标准库: #include <>即可;那么要引入C中自定义的库,怎么处理?
自己制作一个C的库, 静态库
分析原因:
静态库是gcc编译的;gcc编译的时候函数名没有发生变化,仍然是fun1和fun2;
C++中引入了C的库,用g++去编译的时候函数名发生了变化: Z4fun1i 和Z4fun2ii;已经和C库中的函数匹配不上,只能提示函数未定义!
如何解决:
既然是C的库,目标:希望在C和C++中都可以使用!
换句话来思考:
如果是gcc编译器,函数名不变
如果是g++编译器,函数名就要发生变化
第一个需要解决的就是如何判断此时的编译器是gcc还是g++?
《1》.使用宏判断
《2》.使用sizeof计算字符占的内存大小
最终的解决方案:
Extern “C” 就是告诉编译器按照C的规则去编译
- 动态空间分配
C语言中使用malloc做动态内存分配,free去做释放的!在C++中仍然可以使用malloc和free,额外新增了一种动态内存分配的方式: new运算符和delete运算符。
案例:
堆区分配一块内存空间,我要保存5个int类型的数据
New分配内存空间:
格式: 数据类型 *指针变量名 = new 数据类型;
数据类型 *指针变量名 = new 数据类型[个数];
Delete释放内存空间:
格式:
Delete 指针变量名;
Delete [] 指针变量名;