C 以下代码段的输出是什么?为什么? #包括 #包括 typedef无符号整数U32; int main(){ U32 var=-1; printf(“var=%u\n”,var); 如果(变量!=-1) { printf(“\n我不是-1\n”); } 其他的 { printf(“我是-1,变量:%u\n”,变量); } }
此处“-1”应转换为无符号的C 以下代码段的输出是什么?为什么? #包括 #包括 typedef无符号整数U32; int main(){ U32 var=-1; printf(“var=%u\n”,var); 如果(变量!=-1) { printf(“\n我不是-1\n”); } 其他的 { printf(“我是-1,变量:%u\n”,变量); } },c,implicit-conversion,arithmetic-expressions,C,Implicit Conversion,Arithmetic Expressions,此处“-1”应转换为无符号的int,并应分配给var。然后在条件下,如果条件,则不应等于-1。但是它进入了else语句。在这个语句中 #include <stdio.h> #include <stdlib.h> typedef unsigned int U32; int main() { U32 var = -1; printf("var = %u\n", var); if(var != -1) {
int
,并应分配给var
。然后在条件下,如果条件,则不应等于-1。但是它进入了else
语句。在这个语句中
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int U32;
int main() {
U32 var = -1;
printf("var = %u\n", var);
if(var != -1)
{
printf("\n I'm not -1\n");
}
else
{
printf("I'm -1 and Var :%u\n", var);
}
}
编译器需要确定操作数的公共类型。这个过程被称为通常的算术转换。
来自C标准(6.5.9相等运算符)
4如果两个操作数都有算术类型,则使用通常的算术类型
正在执行转换
与常用算术转换相关(C标准,6.3.1.8常用算术转换)
否则,如果具有无符号整数类型的操作数具有秩
大于或等于另一个操作数类型的秩,then
带符号整数类型的操作数转换为
无符号整数类型的操作数。
因此,根据if语句表达式中的引号,具有int类型的整型常量-1
被转换为无符号int类型,即变量var
的类型,因为int类型和无符号int类型具有相同的秩,而变量var
具有无符号int类型
结果,该条件产生false。一个int
,无论是有符号还是无符号
,都由一系列位表示,如
B1B2…Bn
在哪里
毕∈ {0;1}
现在,最大的表示符号unsigned
int
如下所示
if(var != -1)
但是,作为有符号值,-1表示为
1111...1
也
所以1111…1==1111…1是真的。转换为无符号
不会改变任何值,它会改变给定值的感知方式。在内存表示方面,2^(32-1)和-1实际上是同一个家伙,穿着不同的衣服。请注意,所有整数常量,如1
都有一个类型。假设U32
是unsigned int
,那么:
- 在
U32 var=-1的情况下代码>(赋值),类型为int
的右操作数转换为左操作数的类型
- 在
if(var!=-1)
的情况下,-1
操作数按照通常的算术转换从类型int
转换为无符号int
,详情如下:
在这两种情况下,都会发生有符号到无符号的转换,并且这种转换根据6.3.1.3进行了明确定义:
否则,如果新类型是无符号的,则通过重复添加或
比新类型中可以表示的最大值多减去一个
直到值在新类型的范围内
这意味着在上述两种情况下,将生成相同的无符号值0xffffff
。为什么您认为第二个-1
也不会被转换?编译器会警告您有符号/无符号比较不匹配?您还应该得到一个警告。但是它会继续进行,我不确定这有多重要,因为这里最重要的是如何进行整数转换。例如,(long-long)-1==(unsigned long-long)-1
始终为真,但(long-long)-1==(unsigned int)-1
始终为假。在其上加一个显式的U
后缀可能会更清楚,并使编译器警告静音。@JL2210什么意思<代码>-1U
只会给你不同类型的警告。它会给你什么警告?@JL2210使用一元负号和无符号操作数等。编译器不需要为此发出警告,尽管我相信有些编译器会发出警告。静态分析仪肯定会这样做。无论如何,毫无疑问,带有无符号操作数的一元减号是非常可疑的代码。
1111...1