C语言 数组被视为常量指针,所以我们不能改变指针的值,但可以改变数组中的单个元素



数组被视为常量指针,所以我们不能改变指针的值,我无法弄清楚让我们假设——

  a[5]="hello";
  a="hai"; // I Know This not possible but why if below a[0]='a' is possible?
  a[0]='a' ;//this is possible because a is store in stack memory.

现在来看看指针

 char *a="hello";
  a="hai"; //i know this is possible because string are store in code section which is read only memory then why it is changed?  
  a[0]='a' //Not possible  because it is store in stack and string is store in code section if above a="hai" is possible then why a[0]='a' is not possible?

我是新来的,我已经被封锁了2次,所以请帮助我理解这个概念

假设如下声明:

char arr[6] = "hello";
char *ap    = "hello";

这是一个可能的内存映射,显示了这些声明的结果(所有的地址都是凭空捏造的,不代表任何现实世界的架构):

Item            Address        0x00 0x01 0x02 0x03
----            -------        ---- ---- ---- ----
"hello"         0x00008000      'h'  'e'  'l'  'l'
"hai"           0x00008004      'o' 0x00  'h'  'a'
                0x00008008      'i' 0x00 0x?? 0x??
                ...
arr             0x82340000      'h'  'e'  'l'  'l'
                0x82340004      'o'  0x00 0x?? 0x??
ap              0x82340008      0x00 0x00 0x80 0x00

字符串字面值"hello"存储为char的6元素数组,静态存储时间为地址0x0008000。字符串字面值"hai"存储为char的4元素数组,静态存储时间为地址0x00080006。字符串字面值的内容可以存储在内存的只读部分(取决于平台)。试图修改字符串文字内容的行为是undefined;该代码被认为是错误的,但不要求编译器以任何特定的方式处理这种情况。您可能会遇到段错误,或者更改根本不会应用,或者更改将按照您的期望应用。我假设源代码中字符串字面值的多个实例将映射到内存中的单个实例(这是通常的情况)。

除非它是sizeof或一元&操作符的操作数,或者是在声明中用于初始化另一个数组的字符串字面值,否则类型为"T的n元素数组"的表达式将被转换("衰减")为类型为"指向T的指针"的表达式,表达式的值将是数组的第一个元素的地址。结果指针是一个不可修改的左值。

宣言

char arr[6] = "hello";

arr声明为具有自动范围的char的6元素数组,并将字符串字面值"hello"内容复制到其中。您可以随意修改arr[0]arr[5]的值,因此您可以写入

a[0] = 'a';

但是不能写像

这样的东西
arr = "hai";

因为虽然表达式arr"hai"都被如上所述转换为指针值,但arr 不是指针变量;除了数组元素本身之外,没有与arr相关的存储空间,因此没有地方给"hai" (0x00008006)的结果赋值。

宣言

char *ap    = "hello";

ap声明为指向char的指针,并将表达式"hello"的结果赋值给它。在这种情况下,字符串字面值不是sizeof或一元&操作符的操作数,而且它不是被用来初始化数组的内容,因此它被转换为指针表达式,它的值是数组的第一个元素的地址,或0x0008000

这几乎是与arr相反的镜像;你不能更新ap[0]ap[5]的内容,但是你可以ap赋一个新的指针值,所以

ap = "hai";

。这样做之后,您的内存映射将看起来像

Item            Address        0x00 0x01 0x02 0x03
----            -------        ---- ---- ---- ----
"hello"         0x00008000      'h'  'e'  'l'  'l'
"hai"           0x00008004      'o' 0x00  'h'  'a'
                0x00008008      'i' 0x00 0x?? 0x??
                ...
arr             0x82340000      'a'  'e'  'l'  'l'
                0x82340004      'o'  0x00 0x?? 0x??
ap              0x82340008      0x00 0x00 0x80 0x06

数组被视为常量指针

不,它不是这样对待的。数组被视为…一个数组。

a="hai"; // I Know This not possible but why

因为语言定义这么说(更准确地说,因为数组不是可修改的左值)。它这样说是因为它没有意义。

你关于"栈"one_answers"代码"的评论是不相关的;数组中对象的可修改性并不取决于它们的存储位置。这是一个实现细节

最新更新