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强制编译器减少优化,必须每次从内存中取值
狄泰软件学院课堂笔记
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。