C到C++的扩展2

C++对C的加强—输入与输出
cin:对象(变量)>>输入流(可能出现垃圾)
cout:对象(变量) <<输出流 [有缓冲区,类型是行缓冲区,要加“\n”]
cerr:输出(错误信息) [无缓冲区,不是行缓冲,因为是错误信息,要输出来]
cout VS cerr:输出正常打印信息用cout,异常信息用cerr
clog:输出(日志信息) [无缓冲区]
cerr和clog怎么使用?答:把这两个方向做重定向
缓冲区
缓冲区:在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区
\n ,endl(刷新缓冲区并加入“\n”)
作用:输出调试中确保输出
C++对C的加强—实用性加强
for语句升级
for语句升级:解决循环变量浪费空间的问题/节省空间

for(int i=0;i<100;i++)
{

}

新类型bool
新类型 bool:提高可读性(关系运算和逻辑运算的结果只有两种—真和假,0表示假,非0表示真)

bool flag = false;
while(flag == true)
{

}

条件表达式/三目运算符
条件表达式:可以将返回值作为左值(表达式的返回值中一定不能包含常量);优化处理
C++支持,C不支持(取地址再取值)
关键字的升级
关键字:static const register extern typedef inline register
1.register
作用:将修饰变量尽可能保存到CPU内部寄存中,从而省去从内部抓取数据的时间,从而提高运行效率
注意事项
a.只能修饰局部变量,不能修饰函数和全局变量
b.register修饰的变量不能再用&获取该变量的地址
c.register修饰的变量一定是CPU所接受的数据类型
使用场景:频繁访问的变量
升级:如果使用&获取一个register修饰变量的地址,那么就将该变量保存到内存中
2.const:(离谁近,谁不能改,右侧)
作用:修饰变量,该变量为只读变量;修饰指针,不能通过该指针修改指向内存空间的值
升级:const修饰的变量就是常量
注意事项:const指针 对 const指针(变量)
使用场景:修饰函数形参,保证函数实参在函数执行过程中不被修改
在这里插入图片描述

3.volatile
防止编译器优化(将变量优化到寄存器中(寄存器存在边际效用))
使用场景:访问硬件时,所使用的全局变量
4.typedef:
语法作用:给数据类型重命名;
工程应用:提高代码可读性、移植性;提高编程效率
升级:启用新的关键字 using
优化内容:using类型重命名
typedef存在一个问题/注意事项:重命名函数指针时,可读性差
函数名命名规则:解决的是函数功能可读性,无法解决形参的可读性(函数名:指针常量,保存函数入口地址)
5.auto
作用:自动变量[在函数结束之后解放空间]
升级:做类型推导,高效编程

auto p=5;
auto p1='a';
auto p2="hello world";

auto p_func = add;

return 0;

傻瓜式替换:宏无法定义复杂的函数
类型升级
传值 VS 传地址
a. 传实参变量名,只能使用实参的值,不能修改
b.传实参变量地址,既能使用也能修改实参变量的值
c.当需要修改实参变量的值,传实参变量的地址
d.当只使用实参变量的值,传实参变量名
C++对C的加强—引用r_a

1.最大的作用就是解决函数指针传参和返回值问题
作用:给变量起别名,操作别名相当于操作这个变量
引用的作用:函数的形参和返回值
注意事项:定义引用必须绑定变量;一旦绑定一个变量就不能再绑定其他变量(定义必须初始化) 使用场景:函数形参,返回值
引用作为函数形参:解决传值和传地址问题
引用作为函数返回值
不要返回局部变量的地址或者指针
函数调用做返回值:修改返回值!!!
常引用:只能使用不能修改其绑定的值
2. 左值引用:能够赋值(修改),能取地址[只能绑定左值] int&
右值引用:不能赋值(修改),不能取地址[只能绑定右值] int&& (对象移动:解决对象拷贝问题)
移动构造函数 移动拷贝赋值运算符重载
左对左,右对右
引用 VS 指针
1、指针是变量,引用时别名,引用解决函数传参传地址选择问题
2、引用指针都占内存(引用编译阶段确立,并非隐藏)
3、指针有多级指针,引用有左值引用和右值引用
4、指针不安全,容易造成内存泄漏,引用不会
引用是否占用额外内存空间?YES 编译器优化:不将这个空间展示给开发人员,不能操作这段空间 “新的数据类型”
C++对C的加强—动态内存分配(new,delete)
动态管理内存方式(C++升级):malloc(分配内存) free(释放内存 )
区别:
1、malloc free是函数 new delate是运算符
2、malloc free按照字节为单位分配 new delate按照类型为单位
3、malloc free不能初始化分配空间,只能手动初始化 new delate可初始化
(关于初始化:最好手动初始化!默认初始化都是0)
4.malloc free返回NULL new delate如果分配失败会产生异常
new 底层调用的是malloc delate 底层调用的是free
new malloc:频繁分配小内存会导致内存产生碎片,同时会增加开销;池化技术:内存池!!!!
关于多维数组的分配:规则多维数组(int (*p)[3][3])、不规则的多维数组(int **arary);
宏函数:省去函数传参、返回、释放等一系列操作
自定义函数:形参需要分配空间
一维数组ptr
ptr:一维数组首元素的地址 ptr+1,,,1
&ptr:一维数组的地址 &ptr+1,,,100
*(&ptr)=ptr;对一维数组的地址取值等于一维数组首元素的地址
二维数组ktr
ktr:二维数组的首个一维数组的地址;
&ktr:二维数组的地址
*ktr:二维数组的首个一维数组的首元素的地址
**ktr:二维数组的首个一维数组的首元素的值
*(&ktr)=ktr:对二维数组取值等于二维数组中首个一维数组的地址
三维数组str
str:三维数组中首个二维数组的地址;
&str:三维数组的地址;
*str:三维数组中首个二维数组的首个一维数组的地址
**str:三维数组中首个二维数组的首个一维数组的首个元素的地址;
***str:三维数组中首个二维数组的首个一维数组的首个元素的值 ;
指针数组实际上还是一个一维数组,只不过里面保存的是指针;
wtr:首个元素的地址
[扩展1]如何给多维数组分配空间
二维数组的动态创建,例如申请存放二维数组 int a[5][6]的内存空间。

int**a=new int8[5]
for(int i=0;i<5;++i)
{
a[i]=new int[6];
}

使用delete进行内存释放,只要将顺序反过来就行了

for(int i-0;i<5;i++)
{
delete[]a[i];
}
delete[]a;

[扩展2]如何创建三维数组

int***a=new int**[5];
//空间申请
for(int i=0;i<5;++i)
{
a[i]=new int8[6];
for(intj=0;j<6;++j)
    {
    a[i][j]=new int[7];
    }
}
//空间释放
for(int i=0;i<5;++i)
{
for(int j=0;j<6;++j)
    {
    delete[]a[i][j];
    }
    delete[]a[i];
}
delete[]a;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值