c语言 - 为什么分配给下标数组而分配给取消引用的指针算术表达式 - 不行?



Kernighan &里奇第二版说:

索引和指针运算之间的对应关系非常密切。根据定义,数组类型的变量或表达式的值是数组元素0的地址。因此在赋值
之后pa = &a[0];

paa的值相同。由于数组的名称是初始元素位置的同义词,因此赋值pa=&a[0]也可以写成
pa = a;

更令人惊讶的是,至少乍一看,对a[i]的引用也可以写成*(a+i).在计算a[i]时,C立即将其转换为a[i];这两种形式是等价的。应用运算符&对于这个等价的两个部分,可以得出and也是相同的:a+ii在a之后的第一个元素的地址。作为硬币的另一面,如果pa是一个指针,表达式可以带下标使用它;pa[i]*(pa+i)相同。简而言之,一个数组-索引表达式相当于一个写为指针和偏移量的表达式。

看完这篇文章后,我希望这两个程序的工作方式是一样的:

/* Program 1 */
#include <stdio.h>

int main()
{
    char arr[] = "hello";
    arr[0] = 'H';
    printf("%sn", arr);
}
/* Program 2 */
#include <stdio.h>

int main()
{
    char *arr = "hello";
    arr[0] = 'H';
    printf("%sn", arr);
}

但是只有第一个是有效的。第二个我得到分割错误。

为什么?请参考权威资料

当你定义和初始化数组时,所有的数组都是在可修改内存中分配的(通常是堆栈),所以你可以按你想要的方式修改数组。

当你使用字符串字面值时,编译器会给你一个指向只读以零结尾的char数组的指针。试图修改这个数组(在第二个例子中就是这样做的)会导致未定义的行为

与指针运算无关。这是因为在第二个程序中:

char *arr = "hello";

arr指向一个不能修改的字符串字面值

这是因为第一个代码片段中的arrchar数组,可以修改,而在第二个代码片段中,它是一个字符串文字,不受更改。

字符串字面值可能存储在内存的只读区,修改它将调用未定义的行为。

K&R (5.5字符指针和函数):

这两个定义之间有一个重要的区别:

char amessage[] = "now is the time";   /* an array */
char *pmessage = "now is the time";    /* a pointer */

amessage是一个数组,它的大小刚好可以容纳和初始化它的′′。单个字符数组内的值可以被更改,但amessage将始终引用相同的存储空间。另一方面,pmessage是指针,初始化为指向字符串常量;指针可以。随后被修改为指向其他地方,但是的结果是

最新更新