zoukankan      html  css  js  c++  java
  • 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
    ", cc);
    12     
    13     *p = 3;
    14     
    15     printf("cc = %d
    ", cc);
    16     
    17     p = (int*)&g_cc;
    18     
    19     printf("g_cc = %d
    ", g_cc);
    20     
    21     *p = 4;
    22     
    23     printf("g_cc = %d
    ", 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
    ", i);
    22     printf("j = %d
    ", j);
    23     printf("array[0] = %d
    ", array[0]);
    24     printf("g_array[0] = %d
    ", 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
    ", pc);
    15     
    16     pc[6] = '_';
    17     
    18     printf("%s
    ", 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强制编译器减少优化,必须每次到内存中取值

  • 相关阅读:
    python测试开发django(27)--发送html格式邮件
    python测试开发django(26)--发送邮件send_mail
    python测试开发django(25)--表单提交之post修改密码
    python测试开发django(24)--表单提交之post登录案例
    python测试开发django(23)--表单提交之post注册案例
    python测试开发django(22)--表单提交之get请求
    [模拟] Codefroces 1175B Catch Overflow!
    [gcd,灵感] Codeforces 1200C Round Corridor
    [最短路,floyd] Codeforces 1204C Anna, Svyatoslav and Maps
    [最短路,最大流最小割定理] 2019 Multi-University Training Contest 1 Path
  • 原文地址:https://www.cnblogs.com/lemaden/p/10123347.html
Copyright © 2011-2022 走看看