缺省参数:是指是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。
(1)全缺省参数:
int sum(int a = 10, int b = 20) { return a + b; }即形参的所有参数均给以缺省值。
(2)半缺省参数:
int sum(int a , int b = 20) { return a + b; }即形参中部分参数赋以缺省值。
int sum(int a,int b=20) { return a+b; }(1)半缺省参数必须从右往左依次来给出,不能隔着赋给形参缺省值。 例如:
int sum(int a=10,int b)//错误 { return a+b; }(2)声明时可以给形参缺省值,定义处也可以给形参缺省值,但是只能在声明或定义时赋给形参缺省值,不能声明和定义同时给出。 (3)缺省值必须是常量或者全局变量。
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数提升程序运行的效率。 普通函数: 内联函数:
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
int Add(int left, int right) { return left+right; } double Add(double left, double right) { return left+right; } long Add(long left, long right) { return left+right; } int main() { Add(10, 20); Add(10.0, 20.0); Add(10L, 20L); return 0; }const修饰的变量不能在作为左值,并且初始化完成后值不能被修改。
1. C语言中被const所修饰的,可以不用初始化,但是不叫常量,叫做常 变量,其不能作为左值被修改。 2. C++中被const所修饰的必须初始化,为常量。 3. const的编译方式不同: C语言中,const就是当作一个变量来编译生成指令的。 C++中,所有出现const常量的地方,都被常量的初始化值替换掉了,并且初始化值必须为立即数。
注意:如果const右边没有接指针运算符*的话,cosnt是不参与类型的 例如: int * const p = &a;//int*<===int* const后无指针*,不参与类型
int main() { int b = 20; const int a = b;//此时已经退化成常变量,因为初始化值不是立即数,是一个变量。 const int a = 20; b = 30;//错误,被cosnt修饰的变量不能作为左值 int arr[b] = {}; int* p = (int*)&a;//已经把b内存中的值改掉了 *p = 30; printf("%d %d %d\n", a, *p, *(&a));//在编译阶段const修饰的变量就已经被初始化的值替换了 const int a = 10; int* p = &a;//错误,不能把常量的地址泄露给普通指针 const int* p = &a;//正确 int a = 0; int* p = &a; const int** q = &p;//错误的,const int **<===int ** /* const int * *q = &p; 错误的原因: 如果const int * *q = &p是正确的,则: *q<=>p; //*q即为p的地址 因为*q只能接收const int类型变量的地址: 所以有定义:const int b = 20; 对于*q来说,他的类型是const int*类型 而&b的类型也是const int*类型,所有有如下代码: *q = &b <=> p = &b;//即把常量b的地址赋给了一个普通指针p, 所以const int* *q=&p是错误的 */ //可以修改为: int a = 0; const int* p = &a; const int** q = &p; //或者 int a = 0; int* p = &a; const int* const* q = &p; return 0; }引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
类型& 引用变量名(对象名) = 引用实体
int a=10; int& ra=a;//int类型的引用,ra是a的别名,即引用 ra=100;//修改引用ra的值,a的值也随之改变可以给一个变量定义多个引用,改变其中一个引用或者变量的值,所有引用和变量的值均发生改变。
引用在定义的时候必须对其进行初始化;引用类型必须和引用实体是同种类型的;引用引用一旦引用一个实体,再不能引用其他实体。引用可以看作是一个const指针,指向不能变,所指内存中的内容可变。
int a=10; int b=20; int& ra=a; int& ra1;//错误,引用在定义时必须进行初始化 char& ra=a;//错误,引用ra和实体a的类型不同 int& ra=b;//此时a和ra的值将都会被改成201.做函数参数
void Swap(int& a,int& b) { int tmp=a; a=b; b=tmp; }2.做函数返回值
int& SelfAdd(int& a) { a++; return a; } int main() { int a=1; int& ra=SelfAdd(a); return 0; }注意:返回变量的生命周期要大于函数的生命周期,否则,会返回一个随机值。 例如:
int& SelfAdd(int a)//将其改成int& SelfAdd(int& a),就正确了 { a++; return a; } int main() { int a=1; int& ra=SelfAdd(a); return 0; }输出结果为随机值,因为函数形参a的生命周期只在该函数中,调用结束,形参a则交还系统,所以返回随机值。
可以减少拷贝,提高代码的效率。 引用和指针的区别:在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间;在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。
此处仅做简单介绍,后续文章中会有详细描述。 new用于开辟内存,delete用于释放空间。
new和malloc的区别、delete和free的区别; new不仅可以做内存开辟,还可以做内存的初始化操作; malloc开辟内存失败,是通过返回值和nullptr作比较;而new开辟内存失败是通过抛出bad_alloc类型的异常来判断; malloc和free,都是c的库函数; new和delete都是运算符;new有多少种 int *p1=new int(20);//抛出异常的new int *p2=new (nothrow) int;//不抛出异常的new const int *p3=new cosnt int(40);//堆上开辟一个常量空间并初始化为40 int *p4=new(某地址) int(50);定位newC++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译期会将auto替换为变量实际的类型;变量的实际类型通过初始化表达式确定。
注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环