引用与默认参数
const
引用
默认参数
const
关键词,引用的使用以及函数的默认参数。
const
C++中使用const来修饰变量,使其成为常量,所谓常量,就是只能在初始化时给定值,后续不支持再次修改其值。
要做到这个效果,除了在内存的语义上做限定使得内存的WRES
中的只读属性设置为1外,const更多的是从编译器的层面来做限制,言外之意可以通过指针强转等方式绕过常量的限制,但这往往破坏了设计准则,带来潜在风险。
const
能修饰所有的数据类型,并且是严格的修饰
#include <iostream>
struct Node{
int value;
};
int main(){
const int a = 11;
//a = 12; 编译期报错
const struct Node node = {11};
//node.value = 12;编译期报错
return 0;
}
const
修饰指针,与const
所处位置有关
总的原则是,const
只影响其右侧最近的类型
#include <iostream>
int main(){
int value = 11;
//const修饰int*,因此指针为常量,无法通过指针pvalue修改值
const int *pvalue = &value;
//const修饰int*,因此指针为常量,无法通过指针pvalue修改值
int const *pvalue2 = &value;
/*
*pvalue = 12;
*pvalue2 = 12; 编译器报错*/
//const修饰int,因此变量pvalue3为常量,不能再指向其他地址
int *const pvalue3 = &value;
//const既修饰int*,也修饰了int,因此既无法通过指针变量修改值,也无法重新指向其他地址
const int *const pvalue4 = &value;
return 0;
}
关于const
指针的强转
#include <iostream>
void func(const int *arr,int count){
//arr[0] = 11;编译期错误
//*(arr+0) = 11;编译期错误
*(int*)(arr+0) = 11;//顺利通过
}
int main(){
int a = 11;
const *pa = &a;
//*pa = 12; 无法直接通过这种形式修改变量a,编译器做了语法层面的限制
*(int*)pa = 12;//但是可以通过强制转换类型的方式绕开限制
return 0;
}
引用
C语言的指针既带来了方便也带来了风险,指针对内存的操作权限是无限制的,因此往往会带来不少的隐藏风险(如野指针等)。因此在C++中,推出了指针的限制版本,引用。既具备指针对内存操作的优势,而又做了一些使用上的限制,大大减少了风险。
#include <iostream>
void swap(int &a,int &b){
int tmp = a;
a = b;
b = tmp;
}
int main(){
//在定义指针时,可以不初始化,语法上并没有限制,而这个野指针就带了了风险。
int *pa;
int a = 11;
pa = &a;
*pa = 12;//需要通过取地址赋&以及*星号搭配使用
//定义引用时,必须初始化,并且后续无法更改。
int &refA = a;
int v = 13;
refA = v;//这只不过是对引用在赋值13而已,此时变量a的值是13
int aa = 22,bb = 33;
swap(aa,bb);//正常交换
return 0;
}
任何数据类型都可以被引用,但是,引用无法被引用。存在指针的指针,但是不存在引用的引用。
这样就再一次限制了引用的出错机会
#include <iostream>
int main(){
int a = 11;
int *pa = &a;
int* &rPa = pa;//指针类型引用
*rPa = 12;
cout<<a<<endl;//输出12
int &ra = a;
//int &&raa = ra; 编译期报错,不支持
return 0;
}
const
引用
#include <iostream>
struct Node{
int value1;
int value2;
};
int main(){
Node node = {11,12};
const Node &rNode = node;
//rNode.value = 13;编译期报错
return 0;
}
实质上,引用的本质还是指针,不过是受限的指针
函数的默认参数
C++支持给函数的形参提供默认值,大大提高了函数的灵活性
#include <iostream>
void func(int a,int b = 12){
cout<<a<<" "<<b<<endl;
}
//默认参数只有从右往左提供 void demo(int a = 11,int b,int c = 12);这是错误的❌
void func2(int a,int b,int c = 11){
//do something
}
//当函数的声明与实现分离是,默认参数只能写在函数的声明中
void func3(int a,int b = 12);
int main(){
func(11);//输出11 12
func(11,22)//输出11 22
return 0;
}
void func3(int a,int b){
//do something....
}
一览众山小
posted on 2021-12-28 09:28 shadow_fan 阅读(237) 评论(0) 编辑 收藏 举报