为什么这个C代码的输出应该是"no"?
Why should the output of this C code be "no"?
我遇到了这个问题。
#include <stdio.h>
int main(void) {
// your code goes here
unsigned int i = 23;
signed char c = -23;
if (i > c)
printf("yes");
else
printf("no");
return 0;
}
我无法理解为什么这段代码的输出是 no
。
有人可以帮助我理解在 C 中 int
和 char
之间进行比较时比较运算符的工作原理吗?
您正在比较 unsigned int
和 signed char
。这种比较的语义是违反直觉的:大多数涉及 signed
和 unsigned
操作数的二元运算都是在无符号操作数上执行的,在将有符号值转换为无符号值之后(如果两个操作数具有相同的大小晋升)。以下是步骤:
signed char
值被提升为具有相同值 -23
的 int
。
- 比较
int
和unsigned int
,共同的类型是C标准定义的unsigned int
。
int
转换为 unsigned int
,值为 UINT_MAX - 23
,一个非常大的数字。
- 对
unsigned int
个值进行比较:23
是较小的值,比较结果为 false。
- 计算
else
分支,打印no
。
更糟糕的是,如果 c
被定义为 long
,结果将取决于 long
和 int
是否具有相同的大小或不是。在 Windows 上,它会打印 no
,而在 64 位 Linux 上,它会打印 yes
.
切勿在比较中混用有符号和无符号值。启用编译器警告以防止此类错误(-Wall
或 -Weverything
)。您不妨使用 -Werror
将所有这些警告设为致命警告,以完全避免这种命运多舛的代码。
如需完整参考,请阅读 6.3 Conversions 下 C 标准 (C11) 的以下部分:
- 整数提升 在 6.3.1.1 布尔值、字符和整数.
中进行了解释
- 操作数转换详见6.3.1.8 常用算术转换.
您可以从工作组网站下载最新的C11标准草案:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
我遇到了这个问题。
#include <stdio.h>
int main(void) {
// your code goes here
unsigned int i = 23;
signed char c = -23;
if (i > c)
printf("yes");
else
printf("no");
return 0;
}
我无法理解为什么这段代码的输出是 no
。
有人可以帮助我理解在 C 中 int
和 char
之间进行比较时比较运算符的工作原理吗?
您正在比较 unsigned int
和 signed char
。这种比较的语义是违反直觉的:大多数涉及 signed
和 unsigned
操作数的二元运算都是在无符号操作数上执行的,在将有符号值转换为无符号值之后(如果两个操作数具有相同的大小晋升)。以下是步骤:
signed char
值被提升为具有相同值-23
的int
。- 比较
int
和unsigned int
,共同的类型是C标准定义的unsigned int
。 int
转换为unsigned int
,值为UINT_MAX - 23
,一个非常大的数字。- 对
unsigned int
个值进行比较:23
是较小的值,比较结果为 false。 - 计算
else
分支,打印no
。
更糟糕的是,如果 c
被定义为 long
,结果将取决于 long
和 int
是否具有相同的大小或不是。在 Windows 上,它会打印 no
,而在 64 位 Linux 上,它会打印 yes
.
切勿在比较中混用有符号和无符号值。启用编译器警告以防止此类错误(-Wall
或 -Weverything
)。您不妨使用 -Werror
将所有这些警告设为致命警告,以完全避免这种命运多舛的代码。
如需完整参考,请阅读 6.3 Conversions 下 C 标准 (C11) 的以下部分:
- 整数提升 在 6.3.1.1 布尔值、字符和整数. 中进行了解释
- 操作数转换详见6.3.1.8 常用算术转换.
您可以从工作组网站下载最新的C11标准草案:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf