C语言中,常量=const?

来源:互联网 发布:论当代网络暴力 编辑:程序博客网 时间:2024/04/30 17:42

首先这个问题的答案是错误的,不过从某种意义上来说是对的,为什么这么说?

  1.常量

  C语言中常量大致分为整型数常量、浮点数常量、字符常量、字符串常量、枚举常量、常量表达式。这些每个常量的概念就不细说了。显然这些常量是存储在Flash(ROM)中的,和代码放在一起。

  2.const

  const类型限定符的确切的意义是“只读”注意是只读而不是常量。

  (1)const修饰全局变量

  被const修饰的全局变量是彻底的“只读”,任何方法都不能修改它,指针也不行,个人认为算是常量。

  (2)const修饰局部变量

  被const修饰的局部变量依然存放于“栈区”,而它的“只读”属性是不彻底的,我们可以通过指针修改它,这在叫常量就不合适了。

  我在这就列出上面2种情况,就是想说明const和常量是不能画等号的。

  以上仅是我个人理解,若有错误请大家指正。


下面代码先测试(1)const修饰全局变量的情况:

#include <stdio.h>const int b = 3; int main(){int *ptr_b = &b;*ptr_b = 4;printf("b = %d\n", b);}
编译时只会出现警告:const_test.c(7) : warning C4090: 'initializing' : different 'const' qualifiers

运行后程序出错崩溃。const修饰的全局变量确实无法修改。


再测试(2)const修饰局部变量的情况:

#include <stdio.h>int main(){const int a = 1;int *ptr_a = &a;*ptr_a = 2;printf("a = %d\n", a);}
同样编译时出现警告:const_test.c(9) : warning C4090: 'initializing' : different 'const' qualifiers

运行程序:

这说明const修饰局部变量确实可以用指针修改。

上面仅仅是从表面的现象进行解释的,其实真正原因在于:源文件经过预编译、编译、汇编、链接4部最终形成可执行程序(下面以Linux的可执行文件格式elf为例说明)。

elf文件是分段的:

              .text代码段,

              .data数据段(存储已经初始化了的全局变量和初始化了的静态变量),.

               bss段(未初始化的全局变量和未初始化的静态变量,实际上在elf中并没有bss段的实际数据,因为未初始化的静态变量和全局变量都是0,所以就不必存储了),

              .rodata只读数据段(这里才是存放的真正的常量,比如字符串,数字,const的全局变量),其他一些段就暂时不说了。

而我们定义的const局部变量在什么地方存储呢?相信大家已经猜出来了,就是在栈里,而栈是可读可写的,我们给局部变量加上const只不过是告诉了编译器是const(算是自欺欺人的一种行为),而真正运行的时候const局部变量是在栈中存放的,当然可以修改。

顺便提一下在C++中的情况:C++编译器检查类型匹配比较严格,如果还像上面一样写的话,直接回编译提示出错说类型无法转化。如果想编译通过应该用类型强制转换一下,如

        int *ptr_a = (int *)&a;

        int *ptr_b = (int *)&b;                                                                                                                                  
不过结果依然是是局部的const变量依然可以修改,全局的const变量无法修改。

0 0
原创粉丝点击