表达式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)
实际上,您需要了解如何以及何时允许操作员。我们来一一看看。
\n\n引用自C11,
++,后缀增量,章节 \xc2\xa76.5.2.3
\n后缀递增或递减运算符的操作数应具有原子、限定、\n 或非限定实数或指针类型,并且应是可修改的左值。
\n
+,加法运算符,章节 \xc2\xa76.5.6
\n对于加法,两个操作数都应具有算术类型,或者一个操作数应是指向完整对象类型的指针,而另一个操作数应具有整数类型。(递增相当于加 1。)
\n
*, 乘法运算符,章节 \xc2\xa76.5.5
\n每个操作数都应具有算术类型。[...]
\n
现在,在你的使用中
\n\nx++;-->x不是可修改的左值,它是“数组类型”。这会导致错误。x+1;--> 满足要求,请参阅数组衰减注释,因此有效。x*2; -->x不是算术类型(它是指针类型),因此无效。附加说明:(都是我的强调)
\n\n“可修改的左值:”
\n\n引用章节\xc2\xa76.3.2.1,
\n\n\n左值是一个可能指定对象的表达式(具有除 void 之外的对象类型);[...]可修改的左值是 不具有数组类型、不具有不完整类型、不具有 const 限定类型的左值,并且如果它是结构体或联合,则不具有具有 const 限定类型的任何成员(递归地包括所有包含的聚合或联合的任何成员或元素)。
\n
“算术类型:”
\n\n引用\xc2\xa76.2.5,
\n\n\n整数类型和浮点类型统称为算术类型。[...]
\n
“阵法衰变:”
\n\n引用\xc2\xa76.3.2.1,
\n\n\n除非它是运算
\nsizeof符、_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 为数组对象的初始元素,并且不是左值。[...]
这三个说法中
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)
是非法的。