void fun(){
    signed int a=-5;
    unsigned int b=-5;
    printf("the value of b is %u\n",b);
    if(a==b)
         printf("same\n");
    else
         printf("diff");
}

它是印刷:

4294967291

相同

在第二行中,有符号值转换为无符号值。 所以b的值为UINTMAX + 1 - 5 = 4294967291。

我的问题是比较操作中发生了什么。

1)是否再次转换为无符号并与b进行比较?

2)b(即无符号)是否会被转换为有符号值并自动进行比较?

3)由于int溢出,是否从unsigned转换为signed undefined?

我已阅读有关该主题的其他帖子。 我只想澄清问题2和问题3。

#1楼 票数:15 已采纳

1)是否再次转换为无符号并与b进行比较?

是。 在表达式(a == b)中,发生称为“平衡”的隐式类型转换(正式名称是“通常的算术转换”)。 平衡规则指定如果比较具有相同大小和类型的有符号和无符号操作数,则将带符号的操作数转换为无符号操作数。

2)b(即无符号)是否会被转换为有符号值并自动进行比较?

不,它永远不会转换为您的示例中的签名。

3)由于int溢出,是否从unsigned转换为signed undefined?

这就是标准所说的:(C11)

6.3.1.3有符号和无符号整数

1当具有整数类型的值转换为除_Bool之外的另一个整数类型时,如果该值可以由新类型表示,则它将保持不变。

2否则,如果新类型是无符号的,则通过重复加或减一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内。

3否则,新类型已签名且值无法在其中表示; 结果是实现定义的,或者引发实现定义的信号。

换句话说,如果编译器可以设法在上面的2)中进行转换,那么行为是明确定义的。 如果不能,则结果取决于编译器实现。

它不是未定义的行为。

#2楼 票数:1

回答:

  1. a转换为unsigned int
  2. 如果a的范围比b的签名对应范围更宽(我可以想象long long a可以做), b将被转换为带符号的类型。
  3. 如果在转换为有符号类型后无法正确表示无符号值,则您将具有实现定义的行为。 如果可以,没问题。

#3楼 票数:-2

b = -5;

这算作溢出并且是未定义的行为。 比较signedunsigned将自动提升操作数unsigned - 如果出现溢出,你会发现自己再次遇到未定义的行为.-明显错误,请参阅 下面的 [编辑]

另见http://c-faq.com/expr/preservingrules.html

[edit] 更正 - 标准确实声明在从负签名转换为无签名时应使用2补码。

  ask by hackrock translate from so

未解决问题?本站智能推荐:

2回复

为什么在C中直接将unsigned强制转换为signed会得到正确的结果? [重复]

这个问题已经在这里有了答案 : 11个月前关闭。 什么时候在C中进行指针类型之间的转换不是未定义的行为? (5个答案)
1回复

strcmp()和signed / unsigned字符

我对strcmp()感到困惑,或者更确切地说,它是如何由标准定义的。 考虑比较两个字符串,其中一个字符串包含ASCII-7范围之外的字符(0-127)。 C标准定义: int strcmp(const char * s1,const char * s2); strcmp
2回复

将“`unsigned` bitset”转换为`unsigned`时的gcc警告; 它仍然安全吗?

出于调试目的,我确实将“ unsigned bitset”类型转换为unsigned : “ unsigned ”如下所示: typedef struct { unsigned f1 : 1; unsigned f2 : 1; unsigned f
8回复

类型转换为C中的unsigned

打印-534, -534 为什么没有发生类型转换? 我预计它会是-534, 534 如果我修改代码 它不打印任何东西......毕竟a小于b ??
1回复

POINTER_SIGNED或POINTER_UNSIGNED的用例?

在Windows上的BaseTsd.h ,有两个宏: POINTER_SIGNED和POINTER_UNSIGNED ,它们分别解析为__sptr和__uptr 。 根据Microsoft的文档 ,这些指令指定“编译器如何将32位指针转换为64位指针” 。 __sptr是默认设置,它将指
2回复

是整数常量的默认类型是signed还是unsigned?

是整数常量的默认类型是signed还是unsigned? 如0x80000000,我怎样才能决定使用它作为有符号整数常量还是无任何后缀的无符号整数常量? 如果是有符号整数常量,如何解释以下情况? 输出: 以下情况可以表明我的平台使用算术按位移位,而不是逻辑按位移位:
3回复

将unsigned转换为double无符号而不会丢失精度

将整数值转换为浮点值并再次返回与原始整数值相同吗? 例如: 假设编译器没有优化浮点转换, x == z总是会计算为true吗? 我怀疑浮点转换中的任何表示错误总是会增加值。 因此,当浮点值转换回整数值时,将截断该值,该值始终导致原始整数值。 我的假设是否正确?
1回复

Unsigned 和 Signed 在同一表达式中:适用哪些规则?

我对标题中提到的问题感到困惑。 有人告诉我,在涉及两种类型变量的表达式中,有符号被转换为/解释为无符号。 但是,正如以下代码片段所示,情况并非总是如此。 代码: 结果: if 语句返回预期的 0,-20 被转换为一个非常大的无符号整数,但移位表达式返回 -10,这表明发生了算术移位而不是