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

时间:2014-10-29 06:23:00

标签: c conditional-operator

int a=2, b=22;
a>b?a:b=222;

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

int *i, *j, a=2,b=222;
i = &a;
j = &b;
a>b?i:j=&a;

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

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

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

修改    错误是error: lvalue required as left operand of assignment

2 个答案:

答案 0 :(得分: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;
}

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 */

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

SomeType answer;
!answer = 42;

答案 1 :(得分:-1)

int a=2, b=22;
a>b?a:b=222;

我在GCC版本4.8.1中运行了您的上述代码 它工作得很好。  然后我将其更改为以下将清除您的视图。

#include <stdio.h>
main()
{
  int a=2, b=22;
  printf("answer: %d",a>b?a:b=222 );
}

它产生以下输出

回答:222

a>b?a:b=222;
上面的

可以写成

(a>b)?a:(b=222);

当我们运行它时,首先将222分配给变量b,然后执行?:运算符。