0

为什么

(a?b:c)=5;

在“C”中显示需要的左值,而

*(a?&b:&c)=5;

很好吗?两者有什么区别?

假设 a=1,对于第一种情况,它给出 b=5,第二种情况给出,*(&b)=5.`

我无法理解的是:如果我们写b=5or有什么区别*(&b)=5

4

1 回答 1

6

如果我们写 b=5 或 *(&b)=5 有什么区别?

第二个获取一个指向b然后取消引用该指针的指针,将 5 存储到获得的指针中。

但是,您的问题似乎忽略了真正的问题:为什么它在第二种情况下有效,但在第一种情况下无效。这与 C 中的表达式及其处理方式有关。

运算符的结果?:是一个值;具体来说,它是一个rvalue。松散地定义,右值是不能放在赋值左侧的值。它们之所以如此命名,是因为它们是位于赋值右侧的值。例如,表达式“5”是一个右值表达式。你不能这样做5 = 40;是胡说八道。

命名变量是左值。您可以将左值放在等式的左侧。该表达式a是一个左值表达式(假设它a是一个在范围内的变量名)。

但是,表达式(a + b)右值表达式,而不是左值。并且有充分的理由;你不能做(a + b) = 30;的比你能做的更多(5 + 10) = 30;

运算符的结果?:是一个右值表达式,就像+上面的运算符一样。这解释了为什么(a?b:c) = 5;不起作用;您正在尝试为右值表达式分配一个值。那是违法的。

现在,让我们看看第二种情况。我们知道这?:会产生一个右值表达式。现在,这就解释了表达式的分类是什么,但是表达式结果的类型呢?好吧,假设bandc都是ints,那么的类型也是。(a?b:c)int

但是,当您这样做时(a?&b:&c),此表达式的类型是int*,而不是int。它是一个指向整数的指针。它是“指向int.”的类型的右值表达式。它将返回 的地址b或 的地址c

当你有一个int*,并且你用操作符取消引用它时*,你会得到什么?你得到一个类型的左值表达式int。因为(a?&b:&c)是 type 的右值表达式int*,如果你取消引用它,你会得到一个 type 的左值表达式int。此左值将引用bc,具体取决于 的内容a

简单地说,它的工作原理完全一样:

int *ptr = NULL;
if(a)
  ptr = &b;
else
  ptr = &c;

*ptr = 5;

你得到一个指针,它可以指向任何特定的内存位置,然后你在指向的位置存储一些东西。就是这么简单。

于 2012-08-08T07:59:16.693 回答