这两种语法有什么区别?

时间:2012-08-08 07:23:20

标签: c

为什么

(a?b:c)=5;

中的

表示

时需要左值

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

完全没问题?这两者有什么区别?

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

我无法理解的是:如果我们写b=5*(&b)=5会有什么不同?

1 个答案:

答案 0 :(得分:6)

  

如果我们写b = 5或*(& b)= 5?

,会有什么不同

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

但是,你的问题似乎忽略了真正的问题:为什么它在第二种情况下工作,而不是第一种情况。这与C中的表达式以及如何处理它们有关。

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

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

但是,表达式(a + b) rvalue表达式,而不是左值。有充分的理由;你不能再(a + b) = 30;(5 + 10) = 30;

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

现在,让我们看看第二种情况。我们知道?:会导致rvalue表达式。现在,这解释了表达式的分类是什么,但表达式结果的类型呢?好吧,假设bc都是int s,(a?b:c)类型也是int

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

如果您有int*,并且使用*运算符取消引用它,您会得到什么?您将获得int类型的 左值表达式 。由于(a?&b:&c)int*类型的右值表达式,如果取消引用它,您将得到类型为int的左值表达式。该左值将引用bc,具体取决于a的内容。

简而言之,它的工作原理如下:

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

*ptr = 5;

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