为什么以下数组操作是非法的?

soc*_*ath 0 c arrays

表达式x++;和x*2;被报告为非法。编译器产生错误。但是,如果x+1;没有报告错误。

谁能帮助我理解为什么特定的表达方式是非法的?或者,换句话说,为什么添加是合法的?

代码:

#include <stdio.h>
int main(void)
{ 
   int x[]={1,2,3,4,5};
   x++;
   x+1; 
   x*2;
}    
Run Code Online (Sandbox Code Playgroud)

Sou*_*osh 5

实际上,您需要了解如何以及何时允许操作员。我们来一一看看。

\n\n

引用自C11,

\n\n
    \n
  • ++,后缀增量,章节 \xc2\xa76.5.2.3

    \n\n
    \n

    后缀递增或递减运算符的操作数应具有原子、限定、\n 或非限定实数或指针类型,并且应是可修改的左值。

    \n
  • \n
  • +,加法运算符,章节 \xc2\xa76.5.6

    \n\n
    \n

    对于加法,两个操作数都应具有算术类型,或者一个操作数应是指向完整对象类型的指针,而另一个操作数应具有整数类型。(递增相当于加 1。)

    \n
  • \n
  • *, 乘法运算符,章节 \xc2\xa76.5.5

    \n\n
    \n

    每个操作数都应具有算术类型。[...]

    \n
  • \n
\n\n

现在,在你的使用中

\n\n
    \n
  • x++;-->x不是可修改的左值,它是“数组类型”。这会导致错误。
  • \n
  • x+1;--> 满足要求,请参阅数组衰减注释,因此有效。
  • \n
  • x*2; -->x不是算术类型(它是指针类型),因此无效。
  • \n
\n\n
\n\n

附加说明:(都是我的强调)

\n\n
    \n
  • “可修改的左值:”

    \n\n

    引用章节\xc2\xa76.3.2.1,

    \n\n
    \n

    左值是一个可能指定对象的表达式(具有除 void 之外的对象类型);[...]可修改的左值是 不具有数组类型、不具有不完整类型、不具有 const 限定类型的左值,并且如果它是结构体或联合,则不具有具有 const 限定类型的任何成员(递归地包括所有包含的聚合或联合的任何成员或元素)。

    \n
  • \n
  • “算术类型:”

    \n\n

    引用\xc2\xa76.2.5,

    \n\n
    \n

    整数类型和浮点类型统称为算术类型。[...]

    \n
  • \n
  • “阵法衰变:”

    \n\n

    引用\xc2\xa76.3.2.1,

    \n\n
    \n

    除非它是运算sizeof符、_Alignof运算符或一元运算&符的操作数,或者是用于初始化数组的字符串文字, \n 类型为\xe2\x80\x98\xe2\x80\x98array 的表达式类型为 \xe2\x80\x99\xe2\x80\x99 的表达式转换为类型为\xe2\x80\x98\xe2\x80\x98 的表达式,指向类型为\xe2\x80\x99\xe2\x80\x99 的指针,该指针指向\ n 为数组对象的初始元素,并且不是左值。[...]

    \n
  • \n
\n


Vla*_*cow 5

这三个说法中

x++;
x+1; 
x*2;
Run Code Online (Sandbox Code Playgroud)

只有两个语句是非法的。这个说法

x+1; 
Run Code Online (Sandbox Code Playgroud)

是正确的。在这种情况下,在表达式中,数组指示符被转换为指向其第一个元素的指针。

没有为指针定义乘法运算符。所以这个声明

x*2;
Run Code Online (Sandbox Code Playgroud)

是非法的。

数组是不可修改的左值。您不能更改数组指示符。所以这个声明

x++;
Run Code Online (Sandbox Code Playgroud)

是非法的。