网站建设产品中心,哈尔滨网站建设有限公司,做图片可以卖给那些网站,360网站制作潍坊文章目录1 const的分析2 const本质的分析实验2.1 代码案例分析3 const修饰函数参数和返回值时的情况3.1 代码案例分析4 总结1 const的分析
不管是C语言还是C语言#xff0c;const都是一个非常重要的关键字。今天这篇文章着重学习记录C语言中的const。C语言中稍有不同。
在C语… 文章目录1 const的分析2 const本质的分析实验2.1 代码案例分析3 const修饰函数参数和返回值时的情况3.1 代码案例分析4 总结 1 const的分析
不管是C语言还是C语言const都是一个非常重要的关键字。今天这篇文章着重学习记录C语言中的const。C语言中稍有不同。
在C语言中
const修饰的变量是只读的本质上还是变量。注意不是常量。const修饰的变量如果是局部非静态变量则该变量存储在栈上const修饰的变量如果是全局变量则该变量一定是存储在全局的数据区.dataconst修饰的变量在程序编译期就得出了相应的属性在运行期间该const关键字没有作用 注意const修饰的变量不是真正的常量。它只是告诉编译器它修饰的变量不能出现在赋值符号的左边。后面我们会知道const修饰的局部变量是可以通过指针改变的但是const修饰的全局变量是不可以改变的当然这是现代C编译器标准C编译器编译的还是可以修改。后面会有说明 在现代C语言编译器中修改const修饰的变量会导致程序段错误。程序崩溃。因为现代C语言编译器会将const修饰的变量储存在只读存储区.rodata。
但是在标准C语言编译器中不会将const修饰的变量储存在只读存储区。而是储存在可修改的全局数据区.data所以它的值依然可以改变。只要通过指针找到它的地址就可以改变它的值。
比如下面的代码放到比较老的BCC编译器中编译与在vs2017中编译效果肯定是不同的。由于没有安装BCC编译器且代码逻辑比较简单实验部分读者可以自己做实验
#include stdio.hconst int g_cc 2;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;printf(g_cc %d\n, g_cc);return 0;
}2 const本质的分析实验
其实上面的内容就已经说了const的本质。
C语言中的const使得变量具有只读属性现代C语言编译器中将const修饰的具有全局生命周期的变量包括全局变量和局部静态变量储存在.rodata区。 const 不能定义真正意义上的常量 2.1 代码案例分析
9-2-lyy.c
#include stdio.hconst int g_array[5] {0};void modify(int* p, int v)
{*p v;
}int main()
{int const i 0;const static int j 0;int const array[5] {0};modify((int*)i, 1); // ok// modify((int*)j, 2); // errormodify((int*)array[0], 3); // ok// modify((int*)g_array[0], 4); // errorprintf(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;
}在现代C语言编译器中进行编译运行吗上述代码是可以运行成功的。证明了局部const变量是可以通过指针修改的。同时上述代码的第17和19行如果不注释掉程序的就无法运行会产生段错误。这也说明了全局变量和局部静态变量如果被const修饰的话编译器会将其修饰的变量放到.rodata区这个区的内容是不允许被改变的通过指针也无法改变。
3 const修饰函数参数和返回值时的情况
const修饰函数参数表示在函数体内不希望修改该参数的值const修饰函数的返回值表示返回值不可改变。多用于函数返回值为指针的情形。 注意C语言中的字符串字面量存储于.rodata区在程序中需要使用const char* 指针修饰字符串。 如 3.1 代码案例分析
代码9-3-lyy.c
#include stdio.hconst char* f(const int i){//i 5;return LyyLearn_C;
}
int main(){char* pc f(0);printf(pc %s\n, pc);pc[3] _;printf(pc %s\n, pc);return 0;
}上述代码编译后编译有警告运行会产生错误因为pc所指向的内存为.rodata区。不能修改.rodata区里面的内容。第16行会导致程序产生段错误。当然第5行注释的代码会导致程序编译出错。
4 总结
const使得变量具有只读属性const不能定义真正意义上的常量const将具有全局生命周期的变量包括const全局变量const局部静态变量储存在具有只读属性的.rodata区中。不能通过指针法修改该区域中的变量标准C编译器与现代C编译器稍有不同标准C编译器不会将const修饰的具有全局生命周期的变量储存在.rodata区中所以可以通过指针修改该变量。 一般来说我们使用的都是现代C编译器