为什么有符号char的值大于无符号int

  • 本文关键字:大于 无符号 int char 符号 c
  • 更新时间 :
  • 英文 :

#include <stdio.h>
int main() {
unsigned int i = 23;
signed char c = -23;
if (i<c)
puts("TRUE");
return 0;
}

为什么下面程序的输出是TRUE,尽管我使用了可以存储-128到127的签名字符。

您的i < c比较有两种不同类型的操作数,因此类型较小(秩较低(的操作数将转换为另一种类型。在这种情况下,由于-23不能表示为unsigned int;通常的算术转换;根据本(草案(C11标准的以下摘录中的第2段,它最终的值将大大大于+23(实际上是UINT_MAX + 1 - 23(:

6.3.1.3有符号和无符号整数

1将具有整数类型的值转换为_Bool以外的其他整数类型时,如果该值可以用新类型表示,则该值不变
2否则,如果新类型是无符号的,则值由重复地加或减一个以上的最大值可以用新类型表示,直到值在新类型
3否则,将对新类型进行签名价值无法在其中体现;结果是实现定义的或实现定义的信号提出

您可以通过将c分配给一个单独的unsigned int并打印其值来查看此转换的实际操作,如以下代码所示。假设一个32位的unsigned int,您可能会看到一个值4294967273(实际上,它大于23(。

#include <stdio.h>
int main()
{
unsigned int i = 23;
signed char c = -23;
unsigned int uc = c; // Add a diagnostic line ...
printf("%un", uc);  // ... and show the value being used in the comparison
if (i < c) {
printf("TRUE");
}
return 0;
}

注意:这里两个变量(ic(的相对大小有点像转移注意力;即使您将c声明为signed int c = -23;,由于常规算术转换(链接由Jonathan Leffler的评论提供(,您仍然会得到相同的结果——请注意,signed int不能表示unsigned int的所有可能值,因此最后一个"空心"项目符号将发挥作用。

为了进行比较,最小的变量(char,8位(必须提升到较大变量(整数,32位(的大小和有符号性。但这样一来,-23就变成了4294967273。这远远超过23。

如果将c签名的整数进行比较,则符号提升不会导致任何更改,并且测试的行为符合预期。

最新更新