为什么
(a?b:c)=5;
在“C”中显示需要的左值,而
*(a?&b:&c)=5;
很好吗?两者有什么区别?
假设 a=1,对于第一种情况,它给出 b=5,第二种情况给出,*(&b)=5
.`
我无法理解的是:如果我们写b=5
or有什么区别*(&b)=5
?
为什么
(a?b:c)=5;
在“C”中显示需要的左值,而
*(a?&b:&c)=5;
很好吗?两者有什么区别?
假设 a=1,对于第一种情况,它给出 b=5,第二种情况给出,*(&b)=5
.`
我无法理解的是:如果我们写b=5
or有什么区别*(&b)=5
?
如果我们写 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;
不起作用;您正在尝试为右值表达式分配一个值。那是违法的。
现在,让我们看看第二种情况。我们知道这?:
会产生一个右值表达式。现在,这就解释了表达式的分类是什么,但是表达式结果的类型呢?好吧,假设b
andc
都是int
s,那么的类型也是。(a?b:c)
int
但是,当您这样做时(a?&b:&c)
,此表达式的类型是int*
,而不是int
。它是一个指向整数的指针。它是“指向int
.”的类型的右值表达式。它将返回 的地址b
或 的地址c
。
当你有一个int*
,并且你用操作符取消引用它时*
,你会得到什么?你得到一个类型的左值表达式int
。因为(a?&b:&c)
是 type 的右值表达式int*
,如果你取消引用它,你会得到一个 type 的左值表达式int
。此左值将引用b
或c
,具体取决于 的内容a
。
简单地说,它的工作原理完全一样:
int *ptr = NULL;
if(a)
ptr = &b;
else
ptr = &c;
*ptr = 5;
你得到一个指针,它可以指向任何特定的内存位置,然后你在指向的位置存储一些东西。就是这么简单。