1

如果我unsigned在三元运算符条件下只使用类型,这些unsigned变量会自动转换为signed类型吗?

简单的例子:

unsigned int prevTickSeconds = 48;
unsigned int currentTickSeconds = 5; 

unsigned int secondsLeft = (currentTickSeconds - prevTickSeconds ) ?
                            currentTickSeconds - prevTickSeconds :
                            60 - prevTickSeconds + currentTickSeconds;  

(currentTickSeconds > prevTickSeconds)如本例所示,此构造能否正常工作?三元运算符中的条件是否会自动执行类型转换?

4

3 回答 3

5

不,没有这样的转换,因为所有类型都是unsigned int,并且会有“下溢”。

笔记:

60 - prevTickSeconds + currentTickSeconds

currentTickSeconds - prevTickSeconds当且仅当is时才会执行0

于 2012-11-08T07:56:35.350 回答
1

为了让事情按照你想要的方式进行,你需要明确地告诉编译器它应该处理 singns,如下所示:

unsigned int prevTickSeconds = 48U;
unsigned int currentTickSeconds = 5U; 

unsigned int secondsLeft = (((int) currentTickSeconds - (int) prevTickSeconds) > 0)
    ? currentTickSeconds - prevTickSeconds 
    : 60 - prevTickSeconds + currentTickSeconds;  

或者,为了更高效,您可能想引入一个中间signed值:

unsigned int prevTickSeconds = 48U;
unsigned int currentTickSeconds = 5U; 
unsigned int secondsLeft = 0U;

{
  signed int deltaSeconds = currentTickSeconds;
  deltaSeconds -= prevTickSeconds;

  secondsLeft = (deltaSeconds > 0)
      ? deltaSeconds  
      : 60 - deltaSeconds;  
}
于 2012-11-08T08:10:27.390 回答
1

C 不关心你的算法,也不知道你的变量是否会下溢,也不知道下溢是有意的还是偶然的。无符号整数的下溢/上溢是明确定义的行为,因此在这种情况下,编译器会很乐意按照您的指示去做:创建下溢。


一些细节:

unsigned int secondsLeft =  (currentTickSeconds - prevTickSeconds ) ?
                            currentTickSeconds - prevTickSeconds :
                            60 - prevTickSeconds + currentTickSeconds;  

如果我们用它们对应的类型替换这个表达式中的所有变量,我们得到:

unsigned int = (unsigned int - unsigned int) ?
                unsigned int - unsigned int :              
                int - unsigned int + unsigned int;

C 关心的只是它的隐式类型提升规则。此表达式中有两条这样的规则:常规平衡(通常的算术转换)和 ?: 运算符的特殊平衡规则。

平衡规则规定,如果两个相同大小的整数是表达式的操作数,其中一个是无符号的,则有符号操作数将转换为无符号操作数。

unsigned int = (unsigned int - unsigned int) ?     // no conversion needed
                unsigned int - unsigned int :      // no conversion needed
                (int - unsigned int)               // convert the int to unsigned int
                 + unsigned int;  // we get unsigned + unsigned, no conversion needed

然后将结果存储在一个无符号整数中。

然而,C 中有一个特殊的(奇怪的)规则,与条件运算符 ?: 相关。第二个操作数和第三个操作数是平衡的,就好像它们是同一表达式的运算符一样。因此,如果您有这种情况:

1 ? (signed int)x : (unsigned int)y;

那么结果将始终是无符号整数。这是因为 x 和 y 被视为同一操作的一部分,即使 y 从未在代码中使用。这可能会产生微妙的错误,在我看来,完全避免使用 ?: 操作符就足够了。

于 2012-11-08T08:29:13.327 回答