数组被视为常量指针,因此我们不能更改指针值但是数组的单独元素可以更改为什么?

时间:2014-06-10 16:49:51

标签: c arrays pointers

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

  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 个答案:

答案 0 :(得分:6)

  

将数组视为常量指针

不,它没有被这样对待。数组被视为...数组。

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

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

你对#34;堆栈的评论"和#34;代码"不相关;数组中对象的可修改性不依赖于它们的存储位置。这是一个实施细节。

答案 1 :(得分:5)

假设以下声明:

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 ;代码被认为是错误的,但编译器不需要以任何特定方式处理该情况。您可能会遇到段错误,或者只是无法应用更改,或者更改将按预期应用。我假设源代码中的字符串文字的多个实例将映射到内存中的单个实例(这是通常的情况IME)。

除非它是sizeof或一元&运算符的操作数,或者是一个字符串文字用于初始化声明中的另一个数组,表达式为" N-元素数组T"将被转换("衰减")到类型为&#34的表达式;指向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