9_const和volatile分析

关键词:const只读变量、const变量的本质、const修饰函数参数和返回值、volatile

1. const只读变量

  • const修饰的变量是只读的,本质还是变量
  • const修饰的局部变量在上分配空间
  • const修饰的全局变量在全局数据区分配空间
  • const只在编译期有用,在运行期无用
  • const修饰的变量不是真正的常量,它只是告诉编译器变量不能出现在赋值符号的左边
  • 在现代C语言编译器中(如gcc编译器将const修饰的变量存储在只读存储区),修改const全局变量会导致程序崩溃
  • 标准C语言编译器不会将const修饰的全局变量存储于只读存储区中,而是存储于可修改的全局数据区,其值依然可以改变

2. const变量的本质

#include <stdio.h>

const int g_i = 2;

int main()
{
    const int i = 1;
    
    int* p = (int*)(&i);
    
    printf("i = %d\n", i);
    
    *p = 3;
    
    printf("i = %d\n", i);
    
    p = (int*)(&g_i);
    
    printf("g_i = %d\n", g_i);
    
    *p = 4; // gcc编译器将const修饰的全局变量存储于只读存储区,修改只读存储区的值会发生段错误
    
    printf("g_i = %d\n", g_i);

    return 0;
}

输出结果:

i = 1
i = 3
g_i = 2
段错误
  • C语言中的const使得变量具有只读属性
  • 现代C编译器中的const将具有全局生命周期的变量存储于只读存储区
  • const不能定义真正意义上的常量

3. const修饰函数参数和返回值【重点】

  • const修饰函数参数表示在函数体内不希望改变参数的值
  • const修饰函数返回值表示返回值不可改变多用于返回指针的情形

小贴士:C语言中的字符串字面量存储于只读存储区中,在程序中需要使用const char*指针

#include <stdio.h>

const char* f(const int i)
{
    return "Delphi Tang";
}

int main()
{
    const char* pc = (f(0));
    
    printf("%s\n", pc);
    
//  pc[6] = '_';    // error: assignment of read-only location ‘*(pc + 6u)’
    
    printf("%s\n", pc);

    return 0;
}

总结:C语言中的字符串字面量存储于只读存储区中,不能对字符串字面量做修改。

4. 深藏不露的volatile

  • volatile可理解为“编译器警告指示字”
  • volatile告诉编译器必须每次去内存中取变量值
  • volatile主要修饰可能被多个线程访问的变量
  • volatile也可以修饰可能被未知因素改变的变量

5. 有关const volatile int i = 0问题:变量i具有什么特性?编译器如何处理这个变量?

变量i的类型为int,同时被constvolatile修饰,因此变量i是一个只读变量,不能出现在赋值符号的左边,编译器每次都需要到内存中取i的值,不会做任何的优化。

6. 小结

  • const使得变量具有只读属性
  • const不能定义真正意义上的常量
  • const具有全局生命周期的变量存储于只读存储区
  • volatile强制编译器减少优化,必须每次从内存中取值

声明:此文章为本人在学习狄泰软件学院《C语言深度解析》所做的笔记,文章中包含狄泰软件资料内容一切版权归狄泰软件所有!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容