C关键字之const

0. 明确本质:只读变量

const修饰的为变量,表示该变量为只读不是常量
const修饰的对象仍为变量,属性为只读。

//ANSI C
const int ArraySize = 100;
//int a[ArraySize];//error

ANSI C中数组声明的维数限定为常量。上述定义中用const修饰ArraySize,但是ArraySize本质仍为变量,所以编译会报错。
:在c++中可以

1. const 与 变量

const int MaxLen = 10;
int const MaxLen = 10;
  • 以上两种写法效果相同;
  • MaxLen为只读变量,任何对MaxLen赋值语句均非法,即使赋值与原值相同;
  • 通过指针修改用const修饰的变量
    // ENV: vmware, ubuntu18.04.1,gcc version 7.4.0 
    const int MaxPeak[2] = {10,20};
    const int *p = MaxPeak;
    int *pp = (int*)MaxPeak;
    p++;//pass
    //MaxPeak =20;//can't pass
    //*p = 20;//can't pass
    *pp = 20;//when pp is a local variable,pass; when pp is a global variable, can't pass;
    
    const只对他修饰的变量MaxLen限制为只读,未对指向其的指针进行限制。

2. const 与 指针

const char *p;// p is a pointer points to constant char;
char const *p;// p is a pointer points to constant char;
char* const p;// p is a constant pointer points to char;
const char * const p; //p is a constant pointer points to constant char;

从右向左结合法,由*分开。

3. const 与 函数

当函数参数为指针时,如果不希望通过 指针形参 修改 指针指向的变量 时,可以用const限定。

  • 提示函数编写者:此变量不能改变。
  • 告诉函数使用者:此变量不会改变变量值,可以放心使用。
size_t strlen ( const char * str );
int strcmp ( const char * str1, const char * str2 );
char * strcat ( char * destination, const char * source );
char * strcpy ( char * destination, const char * source );
int system (const char* command);
int puts ( const char * str );
int printf ( const char * format, ... );

4. const作用

  • 定义只读变量,参看与define区别。
  • 编译器进行类型检查,尊重变量定义,增加程序的健壮性可读性

5. 注意
参考链接:https://blog.csdn.net/qq_37414405/article/details/89010143

  • 用const修饰的局部变量在栈上分配空间全局变量在全局数据区分配空间
  • 用const修饰的全局变量的生命周期为全局生命周期。具有全局生命周期的变量除了全局变量外, 还有static修饰的变量;
  • 当使用gcc编译器时,当使用类型强制转换时,可以通过指针改变const修饰的局部变量
  • 不能使用指针修改用const修饰的全局变量。用const修饰的全局变量存储在只读存储区。
  • ACSI C中字符串字面量存储在只读存储区;

6.const在c和c++中的不同
参考链接:https://blog.csdn.net/weixin_42445727/article/details/94440156?utm_source=distribute.pc_relevant.none-task

int main()
{
	const int a = 10;
	int *p = (int*)&a; 
	printf("a = %d\n", a);
	*p = 11;
	printf("a = %d\n", a);
 
	return 0;
}

C中的输出结果是10 、11
C++中两次的输出结果都是10

解释

C++编译器对const常量的处理

C++编译过程中若发现使用常量则直接以符号表中的值替换
编译过程中若发现对const使用了extern或者&操作符,则给对应的常量分配存储空间(兼容C)

结论
C语言中的const变量

C语言中const变量是只读变量,有自己的存储空间

C++中的const常量

可能分配存储空间,也可能不分配存储空间
当const常量为全局,并且需要在其它文件中使用
当使用&操作符取const常量的地址

7. const和非const的转换
参考链接:http://c.biancheng.net/view/2041.html)

const char *str1 = "hello, world!";
char *str2=str1;//warning or error

如果将 str1 赋值给另外一个未被 const 修饰的指针变量 str2,就有可能发生危险。因为通过 str1 不能修改数据,而赋值后通过 str2 能够修改数据了,意义发生了转变,所以编译器不提倡这种行为,会给出错误或警告。反过来是可以的,编译器允许将char *类型的数据赋值给const char *类型的变量

这种限制很容易理解,char *指向的数据有读取和写入权限,而const char *指向的数据只有读取权限,降低数据的权限不会带来任何问题,但提升数据的权限就有可能发生危险。

C语言标准库中很多函数的参数都被 const 限制了,但我们在以前的编码过程中并没有注意这个问题,经常将非 const 类型的数据传递给 const 类型的形参,这样做从未引发任何副作用,原因就是上面讲到的,将非 const 类型转换为 const 类型是允许的。

8. const与define区别
参考链接:https://www.cnblogs.com/jason-linux/p/10603257.html

#define PI 3.14159 //常量宏
const double Pi=3.14159; //此时并未将Pi放入RAM中 ......
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
  • define在预处理阶段展开,const在编译阶段进行检查。
  • define定义的宏没有类型,不做类型检查,const进行类型检查。
  • define在代码中使用多少次,就展开多少次,不会分配内存。

9. 其他参考
Dan Saks关于const的论述:参考链接
有关于const有助于编译器优化代码问题: 参考链接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值