const关键字之前我也只是简单的认为它是定义一个不能修改的变量值,但是看书的话才发现远远不仅如此。
const定义一个只读变量
- const修饰的变量是只读的,本质还是变量
- const修饰的局部变量仍然是在栈上分配,可以通过指针修改其值(注意:在clang编译器上,用指针修改不会报错但是并不会修改其值,而在gcc上就会修改它的值)
int main(int argc, char const *argv[])
{
const int a = 10;
//a = 11;
printf("%d\n", a);
int* p;
p = (int*)&a;
*p = 5;
printf("%d\n", a);
return 0;
}
在clang上,值并不会被修改
在gcc上就会被改变
- ?const修饰的全局变量在全局数据区分配空间
- ?c编译器中的const将具有全局生命周期的变量存储与只读存储区(⚠️注意:具有全局生命周期的变量除了全局变量还有static关键字修饰的变量),所以,不能通过指针修改他们的值
事例:
#include<stdio.h>
const int g_array[5] = {0}; //其内存在只读存储区中,不能通过指针对其值进行修改
void modify(int *p,int v)
{
*p = v;
}
int main(int argc, char const *argv[])
{
int const i = 0; //i还是在栈上分配的,可以通过指针来对它的值进行修改
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]);
return 0;
}
gcc上编译:
由此我们可以看出const不能定义真正意义上的常量,它只是告诉编译器,该变量不能出现在赋值符号的左边
- ?const修饰的参数和函数返回值
- const修饰函数参数表示在函数体内不希望改变参数的值
- const修饰函数返回值表示返回值不可改变,多用于返回值指针的情形
小tips:
c语言中的字符串字面量存储于制度存储区,在程序中需要const char* 指针
#include<stdio.h>
const char* f (const int i)
{
i = 5; //error
return "hello!";
}
int main(int argc, char const *argv[])
{
char* pc = f(0); //应该为const char*
printf("%s\n", pc);
pc[6] = '_'; //error!
printf("%s\n", pc);
return 0;
}