C语言-const和volatile深度分析

1、const只读变量

  const修饰的变量是只读的。本质还是变量

  const修饰的局部变量在栈上分配空间

  const修饰的全局变量在全局数据区分配空间

  const只在编译期有用,在运行期无用

  const修饰的变量不是真的变量,它只是告诉

  编译器该变量能出现在赋值符号的左边
实例一.cpp:

  

 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;
22     
23     printf("g_cc = %d\n", g_cc);
24     
25     return 0;
26 }

从上面的代码我们发现,const并不是真正意义上的常量,而只是read-only

提示:GCC编译器如果编译上面的代码,在第21行代码会发生段错误,因为GCC编译器会把const全局数据放置在只读存储区,不能再修改。

但const仍然不能定义真正的意义上的常量。

实例二.cpp

 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 }

2.const修饰函数参数和返回值 

  -const修饰函数参数表示在函数体内不希望改变参数的值

  -const修饰函数返回值表示返回值不可改变,多用于返回指针的情形

小贴士:

  -C语言中的字符串字面量存储于只读存储区

  -在程序中需要使用  const char* 指针

实例3.cpp

 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行和第16行将会报错,这里不再讲述。

3.volatile分析

volatile可理解为“编译器警告提示符

            volatile告诉编译器必须每次去内存中取变量值

            volatile主要修饰可能被多个线程访问的变量

            volatile也可以修饰可能被未知因数更改的变量

 1   int obj = 10;  
 2       
 3     int a = 0;  
 4     int b = 0;  
 5       
 6     a = obj;  
 7       
 8     Sleep(100);  
 9       
10     b = obj;  

 编译器在编译的时候发现obj没有被当成左值使用,

            因此会“聪明”的直接将obj替换成10,而把a和b都赋值为10。(优化)

            volatile主要用于多线程编程环境和嵌入式开发领域

            此时若改变obj的值,a和b又如何???

            volatile int obj = 10后,a和b又如何??

有趣的问题

const volatile int i = 0;

             - 变量 i 具有什么样的特性?

             - 编译器如何处理这个变量? 

正解:  每次用i都会到内存取i的值,i不能出现在赋值符号左边

小结:

   const使得变量具有只读属

                const不能定义真正意义上的常量

                const将具有全局生命期的变量存储于只读存储区

                volatile强制编译器减少优化,必须每次到内存中取值

 

posted @ 2018-12-15 14:40  lemaden  阅读(1106)  评论(0编辑  收藏  举报