C语言中连个类型限定符:const和volatile。用来对以下的类型说明符进行限定:void ,char ,short ,int ,long ,float ,double ,signed ,unsigned ,结构或联合,说明符,枚举说明符,类型定义名。
“类型限定符可与任何类型说明符一起使用。可以对const 对象进行初始化,但在初始化以后不能进行赋值。”《C程序语言设计(第2版.新版)》P200
看看是否如此?
Test1:访问const修饰的变量
const double global_t=70;
int main(void)
{
const double local_t=7;
local_t=10;
global_t=10;
return 0;
}
编译错误: error C2166: 左值指定 const 对象
说明:global_t位于代码区,是只读的;而local_t位于栈区的。两者经过const修饰之后都成功转变为“右指”,所以报error C2166错误。
Test2:通过指针访问const修饰的变量
const double global_t=7;
const double *global_t_p=&global_t;
int main(void)
{
const double local_t=7;
const double *local_t_p=&local_t;
*(double *)local_t_p=0;
*(double *)global_t_p=0;//error occurs
return 0;
}
编译通过,运行错误。
说明:在栈区经过const修饰过的变量的“只读”属性不彻底,可以通过指针来对其修改(再一次体现了指针的威力);但在代码区经过const修饰过的变量时真的“只读”,即使你通过指针也是改不了的,因此在C++里面建议使用const来代替define的一些简单数值宏定义,因为const有编译器来对操作进行检查,多了一层保障。
Test 3:定义指向const修饰的变量为const
const double global_t=7;
const double *const global_t_p=&global_t;
int main(void)
{
const double local_t=7;
const double *const local_t_p=&local_t;
*(double *)local_t_p=0;
*(double *)global_t_p=0;
return 0;
}
说明:与Test2一样,因为只改变指针的属性,但是现在只对指针指向的变量操作,故结果无影响。
Test4:改变经过const修饰的指针的值
const double global_t=7;
const double *const global_t_p=&global_t;
int main(void)
{
const double local_t=7;
const double *const local_t_p=&local_t;
global_t_p=local_t_p;
local_t_p=global_t_p;
return 0;
}
说明:与Test1现象一致,编译错误,原因:
指针也是变量。
送一个:
int main(void)
{
*(int *)0=0;
return 0;
}
编译通过,运行错误。
答:是的,但是可以迂回的通过指针修改经过const修饰的局部变量,因为它在栈区里面。