C:char指针和数组之间的区别
这个问题在这里已经有了答案:
诚然,但这是一个微妙的差异。 基本上,前者:
char amessage[] = "now is the time";
定义一个数组,其成员位于当前作用域的堆栈空间中,而:
char *pmessage = "now is the time";
定义一个位于当前作用域堆栈空间的指针,但是引用其他地方的内存(在这里,“现在是时间”存储在其他地方,通常是一个字符串表)。
另请注意,由于属于第二个定义(显式指针)的数据未存储在当前作用域的堆栈空间中,因此未精确指定它将存储在何处,因此不应修改。
编辑:正如Mark,GMan和Pavel所指出的那样,当这两个变量中的任何一个使用操作符地址时,也会有所不同。 例如,&pmessage返回一个类型为char **的指针,或者一个指向chars的指针,而&amessage返回一个类型为char(*)[16]的指针,或者一个指向16个chars数组的指针一个char **需要被解除引用两次,像litb指出的那样)。
这是一个假设的内存映射,显示了两个声明的结果:
0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07
0x00008000: 'n' 'o' 'w' ' ' 'i' 's' ' ' 't'
0x00008008: 'h' 'e' ' ' 't' 'i' 'm' 'e' ' '
...
amessage:
0x00500000: 'n' 'o' 'w' ' ' 'i' 's' ' ' 't'
0x00500008: 'h' 'e' ' ' 't' 'i' 'm' 'e' ' '
pmessage:
0x00500010: 0x00 0x00 0x80 0x00
字符串文字“now is the time”被存储为内存地址为0x00008000的char元素的16元素数组。 该内存可能不可写; 最好假设它不是。 你不应该试图修改字符串文字的内容。
声明
char amessage[] = "now is the time";
在内存地址0x00500000处分配一个16元素的char数组,并将字符串文本的内容复制到它。 这个内存是可写的; 您可以将消息的内容更改为您心中的内容:
strcpy(amessage, "the time is now");
声明
char *pmessage = "now is the time";
分配一个指向内存地址为0x00500010的char的单个指针,并将字符串文本的地址复制到它。
由于pmessage指向字符串文字,因此不应将其用作需要修改字符串内容的函数的参数:
strcpy(amessage, pmessage); /* OKAY */
strcpy(pmessage, amessage); /* NOT OKAY */
strtok(amessage, " "); /* OKAY */
strtok(pmessage, " "); /* NOT OKAY */
scanf("%15s", amessage); /* OKAY */
scanf("%15s", pmessage); /* NOT OKAY */
等等。 如果您将pmessage更改为指向消息:
pmessage = amessage;
那么它可以在任何地方使用,可以使用消息。
一个数组包含元素。 一个指针指向它们。
首先是一种简短的说法
char amessage[16];
amessage[0] = 'n';
amessage[1] = 'o';
...
amessage[15] = ' ';
也就是说,它是一个包含所有字符的数组。 特殊初始化会为您进行初始化,并自动确定它的大小。 数组元素是可修改的 - 您可以覆盖它中的字符。
第二种形式是一个指针,只是指向字符。 它不直接存储字符。 由于该数组是一个字符串文字,因此无法将指针写入指向的位置
char *pmessage = "now is the time";
*pmessage = 'p'; /* undefined behavior! */
这段代码可能会在你的盒子上崩溃。 但它可以做任何喜欢的事情,因为它的行为是不确定的。
链接地址: http://www.djcxy.com/p/72141.html