第9课-const和volatile分析

30次阅读

共计 1618 个字符,预计需要花费 5 分钟才能阅读完成。

const 只读变量
·const 修饰的变量是只读的,本质还是变量
·const 修饰的局部变量在栈上分配空间
·const 修饰的全局变量在全局数据区分配空间
·const 只在编译期有用,在运行期无用

const 修饰的变量不是真的变量,它只是告诉编译器该变量不能出现在赋值符号的左边

const 全局变量的分歧
注意:
标准 C 语言编译器不会将 const 修饰的全局变量存储于只读存储区中,而是存储于可修改的全局数据区,其值依然可以改变。如果存储在只读存储区就会报错。

const 的变量本质例子 9 -1:

include “stdio.h”

const int g_cc = 2;
int main()
{

const int cc = 1;
int *p = (int)&cc;
printf("%d\n",cc);
*p = 3;
printf("%d\n", cc);
printf("g_cc = %d\n", g_cc);
p = (int*)&g_cc;
*p = 4;
printf("g_cc = %d\n", g_cc);
return 0;

}
输出结果:
1
3
g_cc = 2

输出结果根据编译器进行输出,不同的编译器对 const 变量赋值地址的输出是不一样的。

const 的本质:
·C 语言中的 const 使得变量具有只读属性
·现代 C 语言编译器中的 const 将具有全局生命周期的变量存储于只读存储区
const 不能定义真正意义上的常量。

例子 9 -2:

include”stdio.h”

const int g_array[5] = {0};

void modify(int*p,int v)
{

*p = v;

}
int main()
{

const int i = 0;             //const 与 int 没有先后顺序
const static int j = 0;      // 因为 j 为全局变量,但是经过 static 修饰之后,变为具有全局变量性质,用 const 修饰全局变量是不允许修改的
int const array[5] = {0};

modify((int *)&i, 1);           //ok
//modify((int *)&j, 2);           //error
modify((int *)&array[0], 3);   //ok
//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]);

}
输出结果:
i = 1
j = 0
array[0] = 3
g_array[0] = 0

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

const 修饰函数参数与返回值 9 -3.c

include “stdio.h”

const char *f(const int i)
{
// i = 5; // 因为 i 被 const 修饰,所以 i 为常量,不能做左值

return "zhangyingli";

}
int main()
{

const char *pc = f(0);   // 因为函数 f 为 const char 类型的,所以定义指针也得是 const char 型
printf("%s\n",pc);

pc[6] = '_';     //error   *pc 为 const 类型的不能重新赋值

printf("%s\n",pc);
return 0;

}
输出结果:
报错

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


定义一个只读的 int 类型的变量,并且编译器每次都去内存中取值,不做优化

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

狄泰软件学院课堂笔记

正文完
 0