我正在学习C编程语言,并且在理解指针,数组和只读存储器之间的微小差异时遇到了困难。 我正在使用以下示例:
char *myCards = "JQK";
根据我的理解,这行代码完成的是它在内存的只读段中创建一个空终止字符串,可通过char指针myCards
。 这意味着我能够编译以下内容,但由于字符串的不变性而会收到错误:
*myCards = 'A';
我试图使用一组int来实现类似的function; 但是,如果可能的话,我完全不确定如何创建这个数组并将其放在内存的只读部分。
我知道我可以使用const
关键字并创建一个数组,如下所示:
const int myInts[] = {3, 6, 1, 2, 3, 8, 4, 1, 7, 2};
但是,我可以在此数组初始化后直接执行以下操作:
printf("First element of array: %in", myInts[0]); int *myIntsPtr = myInts; *myIntsPtr = 15; printf("First element of array: %in", myInts[0]);
我能够通过创建指向它的指针来改变数组的第一个元素,这意味着该数组永远不会被放入只读存储器中。
基本上我一直试图弄清楚我如何能够声明这个int数组,以便它在只读存储器中类似于"JQK"
。 任何见解都有帮助。 谢谢。
好的,首先要了解这一点,重要的是要知道C中的const
不需要对只读内存做任何事情。 对于C,没有部分这样的东西。 const
只是一个契约,它表达的意图是事物确实是不变的。 这意味着编译器/链接器可以将数据放在只读部分,因为程序员保证它不会改变。 但它没有必要 。
其次,字符串文字转换为一个常量的char
数组,其中0
隐式附加。 请参阅Peter Schneider在这里的注释:它不是正式的 const(因此编译器不会在你使用非const指针时警告你),但它应该是。
结合这个,下面的代码在我的系统上使用gd在Linux amd64上进行段错误,因为gcc
确实将数组放在只读部分:
#include const int myInts[] = {3, 6, 1, 2, 3, 8, 4, 1, 7, 2}; int main(void) { printf("First element of array: %in", myInts[0]); int *myIntsPtr = myInts; *myIntsPtr = *(myIntsPtr + 1); printf("First element of array: %in", myInts[0]); return 0; }
请注意,在您使用非const指针指向const数组的行中还有一个编译器警告。
顺便说一下,如果用gcc
声明函数内部的数组,那么相同的代码就可以工作,因为那样,数组本身就是在堆栈上创建的。 你仍然得到警告,代码仍然是错误的。 这是C在这里如何实现的技术细节 。 与字符串文字的区别在于它是一个匿名对象(char数组没有标识符),并且在任何情况下都具有静态存储持续时间。
编辑以解释字符串文字的作用:以下代码是等效的:
int main(void) { const char *foo = "bar"; }
和
const char ihavenoname_1[] = {'b', 'a', 'r', 0}; int main(void) { const char *foo = ihavenoname_1; }
所以,简短的故事,如果你想让gcc
将数据放在一个只读部分,请用静态存储持续时间(在函数之外)声明它为const
。 其他编译器可能表现不同。
我同意菲利克斯帕尔曼。 函数中的数组存储在堆栈中,即使它是const,也可以使用适当的强制转换来修改它。 这是我用MS-VC ++(ebp是堆栈指针)所得到的:
const int test [ 5 ] = { 0, 1, 2, 3, 4 }; 00309598 mov dword ptr [ebp-1Ch],0 0030959F mov dword ptr [ebp-18h],1 003095A6 mov dword ptr [ebp-14h],2 003095AD mov dword ptr [ebp-10h],3 003095B4 mov dword ptr [ebp-0Ch],4 ( ( int* ) test ) [ 1 ] = 0; 003095BB mov dword ptr [ebp-18h],0
现在,在函数中定义数组,但这次是static const
,或者将其定义为const
全局变量……我们对两个测试都有相同的结果:数组现在在数据段中(使用地址而不是比ebp)但仍然可以修改:
static const int test [ 5 ] = { 0, 1, 2, 3, 4 }; ( ( int* ) test ) [ 1 ] = 0; 01449598 mov dword ptr [test+4 (145ECACh)],0
使用gcc,您将拥有只读内存中的数据,但正如Felix所说,它并不保证:例如,如果您使用MS-VC,您仍然可以修改它。
以上就是c/c++开发分享C中的指针数组和只读存储器相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/559570.html