任何变量的声明都可以使用const限定符限定。用该限定符指定的变量的值,不能被修改。如果你在source code中显示的修改这种变量,则在编译阶段会报错!但也并不是说用const修饰的变量完全无法修改,是否能够修改还要依情况而定!下面通过两个例子来说明这个问题!
void main(void)
{
char buf[4];
const int a =0;
a = 2;
}
对上述代码进行编译,你会发现在编译阶段会报错,导致不能生成可执行文件!这说明如果你在源码中直接显示的修改const变量,编译器会检测到你在试图修改一个const变量而报出一种语法错误。但是否说明const变量就无法修改呢?我们来看一下下面这个例子的运行结果!
void main(void)
{
char buf[4];
const int a = 0;
buf[4] = 97;
printf("The char of the a is %d\n", a);
}
编译、运行后,发现a的值被修改成了97。在代码中并未进行显示的修改a变量,而是隐式的修改了a的值,我们知道在函数体内的声明中,对于buf数组只是申请了4个元素,而buf[4] = 97;语句造成了数组的访问越界,恰好buf[]与a都是存储在栈区,所以buf[4]正好访问到了a变量!
那是否我们隐式的修改const 变量,在所有的情况下都是可以的呢?我们通过下面的例子来看一下这个问题。
const char words = ‘a’;
char test_words = 'b';
char *pstring = "Hello World";
char string[] = {'H', 'e', 'l', 'l', 'o'};
void main(void)
{
char *pwords = &words;
*pwords = 'b';
printf("The char of the words variable is %c\n", words);
}
编译、运行,你会发现它在编译阶段是能够通过的,这说明,编译器并不会认为对于const变量的地址的获取为非法的,但是程序在运行过程中会报出segmentation fault的错误!这说明在运行阶段发现其不可修改性!但为什么在此例中const变量的值不能修改了呢!我们通过读取各个变量地址的方法来获取相应信息!
void main()
{
printf("The address of the words variable is %x", &words);
printf("The address of the test_words variable is %x", &test_words);
printf("The address of the pstring variable is %x", pstring);
printf("The address of the string variable is %x", string);
}
运行结果如下
The address of the words variable is 400840
The address of the test_words variable is 6010be
The address of the pstring variable is 400841
The address of the string variable is 601040
我们可以看到,words变量和pstring变量所指的地址是临近的,说明这words和“Hello World”存储在同一个段中,而我们知道字符串是储存在文字常量区的,是只读属性的,所以words也应该为只读,所以在程序中如果试图修改它,则会报错!而在第二个程序中,const变量是存在栈区的,所以是可以修改的!