C 为什么对下标数组的赋值有效以及对解引用指针算术表达式的赋值-不';T

C 为什么对下标数组的赋值有效以及对解引用指针算术表达式的赋值-不';T,c,arrays,pointers,pointer-arithmetic,C,Arrays,Pointers,Pointer Arithmetic,Kernighan&Ritchie第二版说: 索引和指针算法之间的对应关系非常密切。根据定义,数组类型的变量或表达式的值是数组元素零的地址。因此,在分配之后 pa=&a[0] pa和a具有相同的值。由于数组的名称是初始元素位置的同义词,赋值pa=&a[0]也可以写成 pa=a 更令人惊讶的是,至少乍一看,对a[i]的引用也可以写成*(a+i)。在评估a[i]时,C会立即将其转换为a[i];这两种形式是等价的。将运算符&应用于此等价的两个部分,可以得出和也是相同的:a+i是a之外的第i个元素的地址

Kernighan&Ritchie第二版说:

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

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

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

读完这篇文章后,我希望这两个程序的工作原理相同:

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


int main()
{
    char arr[] = "hello";
    arr[0] = 'H';
    printf("%s\n", arr);

}

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


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

}
/*程序1*/
#包括
int main()
{
char arr[]=“你好”;
arr[0]='H';
printf(“%s\n”,arr);
}
/*方案2*/
#包括
int main()
{
char*arr=“你好”;
arr[0]='H';
printf(“%s\n”,arr);
}
但只有第一个是有效的。对于第二个,我得到了分段错误


为什么??请参考权威来源。

这是因为第一个代码段中的
arr
是一个
char
数组,可以修改,而第二个代码段中的是一个字符串文本,不受更改


字符串文字可能存储在内存的只读部分,修改它将调用未定义的行为

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


字符串文字可能存储在内存的只读部分,修改它将调用未定义的行为

它与指针运算无关。因为在第二个节目中:

char *arr = "hello";

arr
指向无法修改的字符串文字。

它与指针算术无关。因为在第二个节目中:

char *arr = "hello";

arr
指向一个不能修改的字符串文字。

定义和初始化数组时,所有数组都分配在可修改内存(通常是堆栈)中,因此您可以按任何方式修改数组


当您使用字符串文字时,编译器将给您一个指向
char
的只读零终止数组的指针。试图修改此数组(在第二个示例中是这样做的)会导致未定义的行为。

定义和初始化数组时,所有数组都分配在可修改内存(通常是堆栈)中,因此您可以按任何方式修改数组

当您使用字符串文字时,编译器将给您一个指向
char
的只读零终止数组的指针。试图修改此数组(您在第二个示例中这样做)会导致未定义的行为。

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

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

char amessage[] = "now is the time";   /* an array */
char *pmessage = "now is the time";    /* a pointer */
amessage
是一个数组,刚好可以容纳 字符和初始化它的
'\0'
。个性 数组内的信息可能会更改,但
a消息将始终引用
相同的存储空间另一方面,
pmessage
是一个指针, 初始化为指向字符串常量
;指针可能会 随后可以修改为指向其他位置,但结果为 如果试图修改字符串内容,则未定义。

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

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

char amessage[] = "now is the time";   /* an array */
char *pmessage = "now is the time";    /* a pointer */
amessage
是一个数组,刚好可以容纳 字符和初始化它的
'\0'
。个性 数组内的信息可能会更改,但
a消息将始终引用
相同的存储空间另一方面,
pmessage
是一个指针, 初始化为指向字符串常量
;指针可能会 随后可以修改为指向其他位置,但结果为 如果试图修改字符串内容,则未定义。


什么是“字符串文字”?它的存储方式与char数组不同?@GillBates在这里
“hello”
是。如果您需要正式定义,请阅读C116.4.5字符串文字。什么是“字符串文字”?它的存储方式与char数组不同?@GillBates在这里
“hello”
是。如果您需要正式定义,请阅读C116.4.5字符串文本。Oops!我需要换一下眼镜。哎呀!我需要更换眼镜。
char-arr[]
不是
a[I]
的例子。你引用的文章所说的变化,例如将
arr[0]
改为
*(arr+0)
char-arr[]
不是
a[i]
的例子。你引用的文章所说的变化,例如将
arr[0]
更改为
*(arr+0)