C语言学习笔记--const 和 volatile关键字

Posted CrazyDiode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言学习笔记--const 和 volatile关键字相关的知识,希望对你有一定的参考价值。

1.const关键字

(1)const 修饰的变量是只读的,它不是真正的常量,本质还是变量,只是告诉编译器不能出现在赋值号左边!

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

(3)const 修饰的全局变量在全局数据区分配空间(vc、gcc 会将其放入常量区,bcc 放入全局数据区)

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

#include <stdio.h>
const int g_cc = 2;//bcc 下存储在全局数据区,可修改。
//vc、gcc 将其存储在常量区,不可修改
int main()
{
    const int cc = 1;//存储在栈中
    int* p = (int*)&cc;
    printf("cc = %d\n", cc);
    *p = 3;
    printf("cc = %d\n", cc);
    p = (int*)&g_cc;printf("g_cc = %d\n", g_cc);
    *p = 4; //bcc 编译器下没问题,vc\gcc 下会出错。
    printf("g_cc = %d\n", g_cc);
    return 0;
}

C 语言中的 const 使得变量具有只读属性,但是其只在编译期间有效,在运行期间是无效的,所以可以使用指针的方式间接的去修改它的值,有一点需要注意的是现代 C 编译器(如 Vc、gcc)中的 const 将具有全局生命周期(如全局变量,static 属性的变量)存储于只读存储区,修改该变量时将导致程序崩溃。

#include <stdio.h>
const int g_array[5] = {0};
void modify(int* p, int v)
{
    *p = v;
}
int main()
{
    int const i = 0;//相当于 const int i=0;
    const static int j = 0;
    int const array[5] = {0}; //相当于 const int array[5]={0};
    modify((int*)&i, 1);  
    modify((int*)&j, 2);  //error
    modify((int*)&array[0], 3);
    modify((int*)&g_array[0], 4); //error
    printf("i = %d\n", i);
    printf("j = %d\n", j);
    printf("array[0] = %d\n", array[0]);printf("g_array[0] = %d\n", g_array[0]);
    return 0;
}

const关键字可以用来修饰函数参数和返回值

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

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

#include <stdio.h>
int main(){
    const char* s= "I like programming!"; //存储于只读存读区
}

const 修饰函数参数与返回值

#include <stdio.h>
const char* f(const int i)
{
    i = 5;//错误,i 不能作为左值
    return "I like programming!";
}
int main()
{
    char* pc = f(0); //警告,f 的返回值为 const char*
    printf("%s\n", pc);
    pc[1] = _; //错误,试图修改只读存储区中的数据
    printf("%s\n", pc);
    return 0;
}

2.volatile关键字

(1)volatile 可理解为“编译器警告指示字”

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

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

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

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

int obj = 10
int a = 0;
int b = 0;
a = obj;
sleep(10);
b = obj;

编译器在编译的时候发现obj没有被当成左值使用,因此会“聪明”的将obj直接替换成10,而把a和b都赋值为10.

 

 

以上是关于C语言学习笔记--const 和 volatile关键字的主要内容,如果未能解决你的问题,请参考以下文章

C之 const 和 volatile

精通C语言ANSI C 类型限定符const,volatile,restrict,_Atomic

精通C语言ANSI C 类型限定符const,volatile,restrict,_Atomic

C语言中auto,register,static,const,volatile的区别

C语言关键字-const static volatile

C++基础知识的学习笔记