阵列衰减和修改

时间:2019-08-10 02:04:52

标签: c++ arrays

在阅读了有关C / C ++中的数组为何是不可修改的左值的一些答案之后,我仍然有些困惑。

根据接受的答案(总结如下):Why array type object is not modifiable?

  

C的编写方式应使第一个元素的地址   在计算数组表达式时进行计算。

     

这就是为什么你不能做类似的事情

int a[N], b[N];
a = b;
     

因为在这种情况下, a和b都对指针值求值;它的   相当于写3 = 4。   将第一个元素的地址存储在数组中;编译器   只需在翻译阶段1中对其进行计算即可。

这是我感到困惑的时候。

当我们有了a = b时,我觉得b应该衰减为一个指向b的第一个元素的指针值。

我认为a也会衰减到指针值,但是我不确定。

我的问题是:

a = b等同于3 = 4之类的东西吗?

会不会更像address of a = address of b

1 个答案:

答案 0 :(得分:1)

由于在最后几个问题中可衡量的程度,您对数组/指针转换的困惑似乎是由于难以理解指针本身引起的。让我们从快速总结开始。

指针基础

指针只是一个普通变量,它以其他值作为地址。换句话说,指针指向可以找到其他内容的内存地址。在通常情况下,您会想到一个包含立即值的变量,例如int a = 5;,而指针将仅保存5存储在内存中的地址。要声明指针本身并为其指定地址,可以使用一元'&'运算符获取该类型的现有对象的地址。例如,int *b = &a;获取地址a(其中5存储在内存中),并将该地址分配为指针b的值。 (b现在指向a

要引用指针所在地址的值,请使用指针名称前的一元'*'字符取消引用。例如,b拥有a的地址(例如b指向a),因此,要获取b拥有的地址的值,您只需取消引用 b,例如*b

无论对象的类型如何,指针算法都以相同的方式工作,因为指针的type控制着指针算法,例如:使用char *指针,pointer+1指向下一个字节(下一个char),对于int *指针(正常的4字节整数),pointer+1将指向指向下一个int之后的4个字节的下一个pointer。 (因此,一个指针只是一个指针。...type自动处理算术的地方)

数组是将指针转换为指针的第一个访问元素

继续进行数组指针转换,C和C ++标准都定义了如何在发生4个异常的情况下将array type转换为指针。请注意,此处的C ++标准将依赖于“基本类型”的C标准,并将在C ++标准中添加定义以在必要时扩展C标准。数组/指针转换的基本行为由C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)

提供
§ 6.3.2 Other operands
    6.3.2.1  Lvalues, arrays, and function designators
    Array pointer conversion
    (p3) Except when it is the operand of the sizeof operator, the _Alignof 
    operator, or the unary '&' operator, or is a string literal used to 
    initialize an array, an expression that has type "array of type" is 
    converted to an expression with type "pointer to type" that points to 
    the initial element of the array object and is not an lvalue.

该标准专门定义了数组在访问转换为指向第一个元素的指针时所产生的指针 不是左值。 。因此,如果您拥有数组a和数组b,则该标准本身就禁止您使用以下命令更改该指针所持有的地址:

a = b;

并且,如注释中提供的示例中所述,如果允许,将导致您失去访问a元素的能力。

C ++标准合并了C标准中定义的行为,但是随后扩展了数组/指针转换周围的定义,以解决对C中不存在的类型和对象的使用,但不会更改{{3 }}。

6.3.2.1(p3)提供:

§ 7.3.2 Array-to-pointer conversion
  1  An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” 
     can be converted to a prvalue of type “pointer to T”. The temporary 
     materialization conversion ([conv.rval]) is applied. The result is a 
     pointer to the first element of the array.

扩展是C ++标准,专门将结果指针定义为C++ Standard 7.3.2 Array-to-pointer conversion,而不是“ not a lvalue” 的C定义,并添加了“ T的未知边界数组” ”语言。

因此,在C和C ++中,在访问时,数组都将转换为指向其第一个元素的指针(受§6.3.2.1(p3)枚举的4个异常的影响),并且所得的指针无法修改或分配给另一个地址。修改的限制与普通指针的行为方式无关,而仅仅是由于C / C ++标准定义转换的方式,并且不能修改结果指针类型。 (所以简短的答案是因为标准规定您不能这样做)

仔细检查并确保它对您有意义并沉入其中。如果您仍然很模糊,请发表评论。重要的部分是理解指针本身。数组/指针转换对那些指针的处理方式的限制由标准本身决定。

相关问题