1.1、整型变量初始化可以直接用 { } 赋值
1.2、数组、指针同样可以使用初始化列表方案
1.3、注意:一般不用 int a( ) 来定义、初始化a变量,因为在这里会和定义函数int a( ) 形参冲突;而int b{ } 是可以使用的,会自动初始化b为0
———————————————————————————————————————————
2、C++的输入输出2.1、使用cin.getlin(str,20)可以给字符串中直接输入空格,换行符“ 回车键 ”作为结束标记
2.2、使用” # “作为结束标记
———————————————————————————————————————————
3、const和指针(重点)3.1、const在C和C++中的区别:
const在c中以变量性为主;在c++中以常量性为主
3.2、const 放在 * 号前,修饰的是指向性,也就是修饰*P,不能解引用,但是P自身保存的地址可以改变
比如:
int a = 10 ,b = 20;
const int* P =a;
这里我们可以让P = &b,但是不能通过*P = 100 来改变a的
3.3、const放在* 号后,修饰的是变量名(变量自身具有了常性),那P的指向就可以改变,可以使用解引用,但是P保存的地址是不能改变的
const放在* 号后,不能更改地址
const放在* 号后,可以通过*p修改a变量的值
3.4、* 号的前后都有const,那P、*P都不能被改变
3.5、安全性
3.6、指针之间的相互赋值
———————————————————————————————————————————
4、补充:1、c语言中,scanf()函数的安全性判断解决(scanf_s()):
将目标的大小由程序员指定
2、判断是编译器是C++还是C,通过编译器自带的宏 _cplusplus 来判断
———————————————————————————————————————————
5、引用引用就是“别名”的概念
5.1、特点:
1、定义“引用”,必须要进行初始化
2、没有空引用
3、引用没有二级引用
5.2、引用作为形参代替指针
在c语言中,一般情况下,我们要交换两个变量的值,需要借助交换函数swpe(),通过“传指针,解引用”达到交换的目的
但是在c++里面,我们可以通过“引用”来实现交换,在swpe()函数这里,我们将函数的参数设为要交换的变量的别名。例如要交换变量int a,int b的值,swpe()函数的参数,我们分别可以设为int & x,int & y,函数内部直接借助临时变量交换x、y的值即可
5.3、引用和const
const 必须放在 & 的左边,表示常引用(放在&右边会修饰变量名,而被系统忽略,所以不会修饰&)
由于是常引用,所以c只能读取a的值,不能修改a的值,但是可以通过改变b的值来修改a的值大小
注意:
对于常变量a,我们不能通过普通引用x去引用a,否则就是说明我们可以通过修改普通引用x来改变常变量a的值,所以要用常引用y去引用a
5.4、const引用是万能引用:
const引用可以引用:变量、常变量、字面常量
const引用在引用字面常量的时候实际上是:在底层定义了临时量tmp,接着让Z调用tmp,而不是直接引用字面常量10。引用字面常量10的时候,实际上引用的是tmp,10没有地址空间
5.5、右值引用概念左值:在C11标准的概念中,有取地址的能力,比如变量a可以取地址,和变量类型无关
右值:不可以取地址
左值引用
右值引用
int && r = 10;这个是所谓的右值引用
和常引用的相同点:都是在底层定义一个tmp变量保存右值10
不同点:我们的常引用不能+=10来改变字面常量10,但是右值引用可以让r+=10,是对临时量tmp += 10
5.6、其他引用形式 5.6.1、引用和数组
1、别名影响数组元素的值
2、引用整个数组。格式:int(&cr)[5] = ar;
5.6.2、数组我们称为组合类型:由类型和大小组成
int &ar [5]
不能编译通过,数组元素给到下标,就得开辟空间,但是这里&取别名是不需要开辟空间的
int (&br)[5]
给整个数取别名,例如:int (&br)[5] = ar;这里br是数组ar的别名,这个数组是int类型,有5个元素
int *P [5]
指针数组:从右向左,有5个元素,p的每一个元素是整型类型的指针
int (*s)[5]
数组指针:指针s要指向元素个数为5的整型数组
5.6.3、引用和指针我们可以对一个指针变量ip进行引用,即int *& s = ip;
理解:对指针ip先取别名 &s,然后这个别名是int * 类型
代码分析:
1、s是对指针ip的引用,即别名。s = &b 改变s的指向,也就是改变ip的指向;
2、const int *& s1 = ip,是对指针ip进行取别名,并且s1设置为常性指针,那就是说不能通过 *s1 来改变a的地址,但是 *ip是可以的
3、int* const& s2 = ip,是对指针ip取别名,const修饰变量名ip,可以解引用,不能修改地址
能用引用,绝不用指针
这里形参对x,y取别名,实际交换函数里面是x和y在进行交换
野指针:
空指针:
失效指针:
5.7指针和引用的区别: 5.7.1、指针和引用的区别1-9从语法角度上看区别,10是汇编层面上的区别
1、从语法规则上讲,指针变量存储某个实例(变量或对象)的地址,而引用是某个实例的别名。
2、程序为指针变量分配内存区域(指针分配4字节);而不为引用分配内存区域(仅仅取外号)
3、解引用是指针使用时要在前加“ * ”;引用可以直接使用
4***、指针变量的值(指针的指向)可以发生改变,存储不同实例(比如变量a、b)的地址;引用在定义时就被初始化(也就是它就指定是某个变量的外号,这个变量的地址是确定的),之后无法改变(不能是其他实例的引用)。
5、指针变量的值可以为空(NULL,nullptr);但是没有空引用(引用前必须定义好某个变量)。
6、指针变量作为形参时需要测试它的合法性(判空NULL);引用不需要判空;
7、对指针变量使用“ sizeof ”得到的是指针变量的大小(4字节),对引用变量使用“ sizeo f”得到的是变量的大小(由变量类型决定)。
8、理论上指针的级数没有限制;但引用只有一级。即不存在引用的引用,但可以有指针的指针(二级指针、三级指针)
9、++引用(直接反应到实体) 和 ++指针的效果不一样。对引用的操作直接反应到所引用的实体(变量或对象);
知识引申: 数组中,(*p)++是:先取p对应的值,然后对p的值再加1;*p++是:先取i、p对应的值,然后p地址加1个单元格
10、从汇编层次理解引用与指针变量的区别(从汇编层面看,引用就是指针,是一个自身为常性的指针)
5.7.2、指针和引用的相同点:
绝不可以对函数中的局部变量以引用或指针方式返回,因为函数调用(会先开辟空间)结束之后,栈帧回收,那局部变量就会失效,但是值还存在,有可能打印的时候,这个值是可以正常打印的,但是如果我们再次调用某个函数,对这个栈帧进行操作,那原先这个位置的值就会被清理掉
要返回地址时候此标识符名字对应的实体生存期不受函数生存期影响,就可以返回地址。比如:定义的全局变量,或者static int a静态变量(在 .data区),或者是由指针进入形参,指针返回,或者以引用进、以引用出的方
5.8、如何使用引用
对于结构体类型,传参数时候,优先使用传引用方式(分析结构体占用内存);对于内置类型,函数调用传参数的时候,优先使用传值型(从底层汇编代码分析)
———————————————————————————————————————————
6、inline函数
———————————————————————————————————————————
7、缺省函数C++可以使用缺省函数,但是C语言不可以
函数在定义的时候,可以指定形参的值为默认值;函数调用的时候,如果给到全部的参数,那就以给到的实参传递给形参,如果没有给实参,那形参就按照默认的值来进行操作
缺省函数特点:
1、函数的缺省值有可能是常量值、int()、int{ }、也有可能是函数调用,还有可能是类型的调用
2、函数缺省值在给定的时候,要从右向左去给到(但是给实参的时候要从左向右给到)
3、在多文件情况下,一般我们都只给函数的声明中给到缺省参数的默认值就行,而不能在函数定义中给到(多文件:比如有 .h头文件、.cpp函数实现文件、main.cpp测试文件)
4、缺省参数也可以使用指针形式,但是不能让形参作为另外一个形参的默认值
5、函数在声明的时候可以省略”形参名“
———————————————————————————————————————————
8、函数重载 8.1、函数重载的概念在C++中可以为两个或两个以上的函数提供相同的函数名称,只要参数类型不同,或参数类型相同而参数的个数不同,称为函数重载。
在C语言中函数名称不能一样,如果一样会发生函数名的重定义
在C++中识别函数,不仅通过函数名识别,还要通过参数表(参数类型,参数个数)进行识别,参数名称不作为识别依据,例如两个类似的函数在定义的时候,其中一个函数的参数有包含默认值,这个时候是不作为识别依据的。
8.2函数重载的各类变化
8.2.1、返回值不能作为识别依据。两个参数名、参数相同,但是返回类型不同,会被标记为编译错误:函数的重复声明。
8.2.2、参数名不能作为识别依据。参数表进行比较的时候,和参数名称无关
8.2.3、如果在两个函数的参数表中,只有缺省实参不同,也不能作为函数重载的依据。则第二个声明被视为第一个的重复声明。
8.2.4、typedef也不能作为函数重载的依据
8.2.5、C++ const(常性)、volatile(易变关键字)
当一个形参类型有const或volatile 修饰时,如果形参是按值传递方式定义,那么在识别函数声明是否相同时,并不考虑const和 volatile 修饰符,也就是说const或volatile并不能作为函数重载的依据
但是如果按照指针方式定义,或者按照引用方式定义的话,那么进行参数传递的话是可以作为函数重载依据的
8.2.6、函数调用的二义性
第二个func()函数含有缺省参数,所以主函数中func(12)在调用的时候,上面两个函数都可以进行调用,所以就会产生二义性
重载函数的时候,不要轻易使用缺省值,以免函数调用产生二义性
参数int*p 和const in*p在函数重载中,可以作为识别依据,因为不能通过*b改变b的值
引用在重载中也可以进行识别
直型别也作为重载的依据
c语言为什么不能进行函数重载,而C++可以进行函数重载?
答案:关于名字粉碎技术,在编译中会对函数名进行另外的修饰
C语言的名字修饰规则非常简单,_cdecl是C/C++的缺省调用方式,调用约定函数名字前面添加了下划线前缀。
C++的名字修饰足够复杂
auto的原理就是根据后面的值,来自己推测前面的类型是什么。
auto的作用就是为了简化变量初始化,如果这个变量有一个很长很长的初始化类型,就可以用auto代替。
如何判断编译器是C还是C++?
在编译器下有个宏:_cplusplus,检测这个宏存在与否



