标签:c语言 帮助 语言 info 通过 erro 报错 取值 接下来
注意:const修饰的变量不是真的常量,他只是告诉编译器该变量不能出现在赋值符号的左边
程序实例1:
1 #include <stdio.h> 2 3 const int g_cc = 2; 4 5 int main() 6 { 7 const int cc = 1; 8 9 int* p = (int*)&cc; 10 11 printf("cc = %d\n", cc); 12 13 *p = 3; 14 15 printf("cc = %d\n", cc); 16 17 p = (int*)&g_cc; 18 19 printf("g_cc = %d\n", g_cc); 20 21 *p = 4; //error 22 23 printf("g_cc = %d\n", g_cc); 24 25 return 0; 26 }
这段代码说明,const修饰的局部变量可以使用指针修改,但是const修饰全局变量不可以通过指针进行修改,第21行代码试图修改const修饰全局变量,由于我使用的codeblocks,是一款现代编译器,所以编译阶段会报错,删掉21行代码程序就可以正常运行
程序示例2:
1 #include <stdio.h> 2 3 const int g_array[5] = {0}; 4 5 void modify(int* p, int v) 6 { 7 *p = v; 8 } 9 10 int main() 11 { 12 int const i = 0; 13 const static int j = 0; 14 int const array[5] = {0}; 15 16 modify((int*)&i, 1); // ok 17 modify((int*)&j, 2); // error 18 modify((int*)&array[0], 3); // ok 19 modify((int*)&g_array[0], 4); // error 20 21 printf("i = %d\n", i); 22 printf("j = %d\n", j); 23 printf("array[0] = %d\n", array[0]); 24 printf("g_array[0] = %d\n", g_array[0]); 25 26 return 0; 27 }
第3行和第13行声明了用const修饰的具有全局生命周期的变量,所以在试图用指针来修改他们的值的时候,编译器会报错
程序实例3:
1 #include <stdio.h> 2 3 const char* f(const int i) 4 { 5 i = 5; 6 7 return "Delphi Tang"; 8 } 9 10 int main() 11 { 12 char* pc = f(0); 13 14 printf("%s\n", pc); 15 16 pc[6] = ‘_‘; 17 18 printf("%s\n", pc); 19 20 return 0; 21 }
这段代码是错误的,但是我们来剖析一下,首先编译的时候第5行会出错,我们注释掉,接下来再编译,在12行会给出一个警告,我们用一个char *类型来接受了一个字面值常量,因为只是警告,所以我们可以运行一下,最后运行的时候还是出错了,因为第16行尝试修改了一个字面值常量
示例程序4:
int boj = 10; //编译器在编译的时候发现obj int a=0; int b=0; a= obj; //“聪明“的编译器不会到内存中去找obj对应的值,而是直接替换为10 sleep(100); //在另一个线程里面可能已经改变了obj的值 b= obj; //这个时候编译器还是自作聪明的用10来代替obj,而不去内存中去找obj对应的值
这段代码只是一个小的片段,但是已经可以帮助我们理解有的时候编译器的自作聪明可能会导致某些bugconst volatile int i = 0;但是如果在定义一个变量的时候我们加上volatile属性,编译器每次就会去内存中去找到变量对应的值。
标签:c语言 帮助 语言 info 通过 erro 报错 取值 接下来
原文地址:https://www.cnblogs.com/luojianyi/p/9222112.html