C++本质之const关键字的用法(窥探本质)

36 篇文章 4 订阅
5 篇文章 0 订阅

一、定义

const是常量的意思,被其修饰的变量不可修改

C++程序员如果看到const关键字,如果只想到是常量,这可不是良好的条件反射。const更大的魅力在于可以修饰函数参数和返回值,甚至定义函数时也可以修饰。

二、被const修饰的变量特点

  • 被修饰的普通变量无法更改其值
const int age = 10;
age = 20;//会报错
  • 字符串常量必须用const类型修饰
const char *str = "hello world";
char *str = "hello world";//会报错

1、用const修饰函数的参数

如果函数的形式参数用于输出的情况下,无论是“指针传递”还是“引用传递”都不可以使用const修饰,否则该参数将失去输出功能。

  • const只能修饰输入参数
//该函数无法运行,会报错;因为输出参数不可以用const修饰
int function(const int output, int input)
{
	input = 10;
	output = input + 10;
	return output;
}
//当输入参数被const修饰时,不影响输出参数的使用
int function(int output, const int input)
{
	output = input + 10;
	return output;
}
int main()
{
	int output=0,output1;
	output1 = function(output, 10);
	cout << output1 << endl;//输出20
	getchar();
	return 0;
}
  • 输入参数采用“指针传递”,const修饰会有什么效果呢?

如果输入参数采用“指针传递”,那么const修饰可以防止意外的改动该指针指向的内存单元,起到保护内存变量的作用

void function(char *dst, const char* src)
{
	//其中src是输入参数,dst是输出参数,如果函数体内部的语句试图更改src指向的单元,编译器将会报错
}

如果还想要保护指针本身,则可以声明指针本身为常量,防止该指针的值被更改

void function(char *dst, const char* const src)
{
	//这样不仅指针src指向的内存单元不可被更改,而且本身的值也不可被更改,
}
  • 输入参数采用“值传递”,const修饰会有什么效果呢?

如果输入参数采用“值传递”,由于函数将自动用实参的拷贝(即实参.copy)传递给形参,因此即使在函数内部修改了该参数,改变的也就是堆栈上实参的拷贝,而不是实参本身。因此实参的值并不会因为函数调用而被修改,所以一般不需要const修饰值传递参数

如果函数内部多次使用某个形参的初始值,即传入的参数值,那么在该形参前面加const修饰也就顺理成章

2、用const修饰函数的返回值

  • 如果给“指针传递”的函数返回值加const修饰符,那么函数的返回值是一种“契约型”常量,不能被直接修改的同时,必须要同类型const指针的变量接收这个返回值
const char *GetString(void)
{
//函数体
}
char *str = GetString();//“初始化”: 无法从“const char *”转换为“char *”
const char *str = GetString();//正确!!

三、const修饰变量时位置不同,效果不同

const修饰int型变量

const int age = 20;
//age = 20;就会出错,const修饰的变量不可修改,即使更改的是源数值20

下方是:const修饰int型指针变量* p1,修饰的是* p1,所以* p1是常量,不可修改,即指针指向的内存单元不可更改;但p1不是常量,是地址变量,可以修改,这是因为const没有直接修饰p1

int value = 10;
int temp = 20;
//const修饰的是*p1,所以*p1是常量,不可修改;但p1不是常量,是地址变量,可以修改
const int *p1 = &value;
*p1 = 20;//报错
p1 = &temp;//不报错

//与上方相同,变量类型和const可以位置交换,没区别
int const *p2 = &value;	
*p2 = 20;//报错
p2 = &temp;//不报错

const和int可以随意互换位置,不影响修饰的变量

下方是:const修饰int型指针变量p3,但const修饰的是p3本身(存放地址的指针),即p3这个int型指针变量不可能更改指向(也就是p3存放的地址值不可以更改)

int value = 10;
int temp = 20;
//const修饰的是p3,跟指针符号一点关系没有
int * const p3 = &value;
	
p3 = &temp;//报错,因为p3不可以更改指向
*p3 = 20;//不报错,因为没有直接修饰*p3,就可以更改指向的内容,结果value变成了20

下方表示的是,指针本身与指针指向的内容都被const修饰,所以都无法更改

//一个const修饰p4,所以p4是常量,另一个const修饰*p4,所以*p4也是常量,所以都无法修改
const int * const p4 = &value;
int const * const p5 = &value;

const int *int const * 一样,const与数据类型交换不影响

一个万年不变的点就是const修饰是其右边的内容

四、总结

  • 不希望某个值在代码其他地方改变时,可以给该变量用const变成常量,提高代码的‘健壮性’,也使得代码更加的安全
  • 值传递不需要const修饰
  • 引用传递用到const修饰的场合很多
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值