要回答这个问题,我相信还有一些其他的问题需要回答。
为什么 C 语言中有一个?:
运算符,为什么它比if-else
?
据我所知,没有人能够回答这个问题,而不仅仅是陈述自己的主观意见。K&R 2.11 指出
“条件表达式通常会导致代码简洁。”
然后他们用这条线来说明这一点
printf("%6d%c", a[i], (i%10==9 || i==n-1) ? '\n' : ' ');
这是他们自己主观的、模糊的意见。就个人而言,我相信
printf("%6d", a[i]);
if(i%10==9 || i==n-1)
printf("\n");
else
printf(" ");
更清晰,因为我可以在 10 秒内阅读和理解该代码,而不是 1 分钟阅读和理解 K&R 版本。此外,我的代码将整数打印与不相关的格式分开。但当然,这是我的主观意见,没有明显的对错。
至于官方消息,C99 基本原理版本 5.10、6.5.15 并没有真正提到为什么需要 ?: 运算符。它主要只是说明操作员的行为在新标准中有所改变:
对条件运算符的中间操作数的句法限制已经放宽,不仅包括逻辑或表达式:一些现存的实现已经采用了这种做法。
条件运算符表达式的类型可以是 void、结构或联合;大多数其他运算符不处理此类类型。然而,在指针和整数之间平衡类型的规则已经收紧,因为现在只有常量 0 可以可移植地强制转换为指针。
因此,如果有人想对 struct 或 union 类型执行算术运算,那么 ?: 应该比 if-else 更方便。我认为这没有明显的好处,但至少它是运营商存在的一些理由。
下一个问题将是:
为什么?:
GCC 编译器中的操作数有编译器扩展?
这里提到了这个问题的答案:
当它变得有用时,第一个操作数确实或可能(如果它是宏参数)包含副作用。然后在中间重复操作数将执行两次副作用。省略中间操作数会使用已经计算的值,而不会产生重新计算的不良影响。
所以这个 GCC 扩展与可读性或语言一致性无关,它只是为了避免不必要的副作用而添加的。
然后尝试回答原始问题:
为什么GCC的三元扩展不支持赋值?
可能是因为在赋值条件中访问左值通常不会产生任何不需要的副作用。x = x ? : 2;
如果将 x 声明为 a,则只会产生不需要的副作用volatile
- 读取 volatile 变量是一种副作用。所以我能看到的唯一实际用途x ?:= 2;
是防止某人在同一个条件表达式中访问同一个 volatile 变量两次。
这是一个非常狭窄且价值有限的特征。在某些特殊的嵌入式系统案例中,它可能会很有用,您可以在要求苛刻的实时系统中读取硬件寄存器……除此之外,我认为它没有任何用处。
除了传统和主观编码风格偏好之外,我也找不到任何官方或规范来源说明 ?: 运算符本身的任何用途。