为什么我的条件运算符给我一个错误?

Gib*_*bbs 8 c conditional-operator

int a=2, b=22;
a>b?a:b=222;
Run Code Online (Sandbox Code Playgroud)

这段代码给了我一个错误.我认为这是因为条件运算符返回值ab基于条件的值,因此该值不能用作Lvalue.就我而言,22 = 222,所以这是一个错误.

int *i, *j, a=2,b=222;
i = &a;
j = &b;
a>b?i:j=&a;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,编译器也会抛出错误.根据我的假设,与前一种情况一样,这里返回值为ij.所以0x123 =&a; [让0x123是存储在j中的地址].无效吗?

此时,我进行了搜索.我尝试过0x123 = &a;,但编译器仍然会抛出错误.我想编译器不允许我出于安全原因修改内存位置.

请让我知道我的所有假设都是有效的,并告诉我如果允许程序员操作内存位置会发生什么安全错误.我假设内存位置可能包含不应修改的值.

编辑 错误是error: lvalue required as left operand of assignment.

ric*_*ici 12

这是一个语法错误.使用地址没问题:

#include <stdio.h>
int main() {
  int a=2,b=4;
  *(b>2 ? &a : &b) = 7;
  printf("a = %d; b = %d\n", a, b);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

C语法不允许?:在赋值运算符的左侧使用表达式.上面的版本在语法上是正确的,因为赋值左侧的表达式是带有括号参数的解除引用表达式.

通过指针分配的唯一方法是使用*ptr = val;.指针的计算方式无关紧要,只要它是指向右侧类型的有效指针即可.它甚至可以是常量 - 但是转换为指针 - 如果你有某种方式知道常量是有效的地址:*(int*)(0x124) = 42;.但是你总是需要dereference运算符来指示你通过指针进行分配.


详细的语法解释:

有两个相关的语法产品,它们证明了C和C++之间在原始表达方面的区别('a> b?a:b = 222`)

在C中,我们有(§§6.5.15-16):(强调添加)


    conditional-expression:
        logical-OR-expression
        logical-OR-expression ? expression : conditional-expression

    assignment-expression:
        conditional-expression
        unary-expression assignment-operator assignment-expression

在C++中,等效产品(§§5.16-17):(强调添加)


    conditional-expression:
        logical-or-expression
        logical-or-expression ? expression : assignment-expression

    assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator initializer-clause
        throw-expression

请注意,在C中,赋值运算符之前唯一可以出现的是一元表达式,因此像条件表达式这样复杂的东西需要在括号中.此外,条件表达式的右侧操作数必须是条件表达式,这意味着赋值表达式无效.

相比之下,在C++中,赋值表达式中赋值的操作数可以是逻辑或表达式,这仍然意味着条件表达式无效,但允许其他可能性(其中许多可能仅在运算符重载时有用) ).但是C++ 条件表达式 可以赋值表达式作为其最右边的操作数.

所以在C中,a>b?a:b=222是一个语法错误.任何生产都无法生产expression.但是在C++中,相同的表达式是合法的,条件运算符的最右边的操作数是b=222; 换句话说,它是一样的a>b?a:(b=222).

需要注意的是,仅仅因为表达式符合语言的语法并不意味着表达式是合法的.赋值运算符的左侧必须是"可修改的左值".因此,以下语法正确的表达式都不合法:

int x;
-x = 3;  /* lhs is not an lvalue */

const int cx = 3;
cx = 4;  /* lhs is not modifiable */
Run Code Online (Sandbox Code Playgroud)

在C++中,如果SomeType::operator!(int)返回引用,这个可能是合法的:

SomeType answer;
!answer = 42;
Run Code Online (Sandbox Code Playgroud)

  • @TheParamagneticCroissant:由于语法错误,它永远不会出现语义错误.(但是,如果你修复语法错误,你必须处理语义错误.) (3认同)