Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C整数隐式转换_C_Type Conversion_Integer - Fatal编程技术网

C整数隐式转换

C整数隐式转换,c,type-conversion,integer,C,Type Conversion,Integer,我试图理解以下转换的机制 #include <stdio.h> #include <stdint.h> int main() { int a = 0xffffffff; printf("%d", a); // prints -1 return 0; } #包括 #包括 int main(){ int a=0xffffffff; printf(“%d”,a);//prints-1 返回0; } 根据0xffff

我试图理解以下转换的机制

#include <stdio.h>
#include <stdint.h>

int main() {
    
    int a = 0xffffffff;  
    printf("%d", a); // prints -1
    return 0;
}
#包括
#包括
int main(){
int a=0xffffffff;
printf(“%d”,a);//prints-1
返回0;
}
根据
0xffffffff
的类型是
unsigned int
。这可以通过执行
printf(“%s”,0xffffffff)
轻松检查

现在,根据:

“整数提升是对任意值的隐式转换 秩小于或等于值的int[…]秩的整数类型 类型为int或无符号int。“

以及,如下文所述

“所有有符号整数类型的秩等于 对应的无符号整数类型“

因此提升适用,因为
unsigned int
的排名与
int
的排名相同

这种晋升被定义为

“If int可以表示原始类型的整个值范围 (或原始位字段的值范围),该值为 已转换为int类型。否则,该值将转换为无符号 int“


但是,这就是我不理解的,
int
不能表示
无符号int
4294967295,但它仍然转换为
int
。这种情况发生时没有任何狭窄警告。为什么会这样?

由于常量
0xffffffff
(假设
int
为32位)的类型为
无符号int
,用于初始化
int
类型的对象,这涉及从
无符号int
int
的转换

C标准第6.3.1.3节描述了整数类型之间的转换:

1当整数类型的值转换为除
\u Bool
以外的其他整数类型时,如果该值可以用新的 类型,它是不变的

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

3否则,新类型是有符号的,不能在其中表示值;要么结果是实现定义的 或者引发实施定义的信号

第3款适用于本案。所讨论的值不在目标类型的范围内,并且目标已签名。因此,将发生实现定义的转换

如果您使用gcc使用
-Wconversion
标志进行编译,它将向您发出警告:

x1.c:6:5:警告:将无符号常量值转换为负整数[-Wsign conversion]
int a=0xffffffff;
此外:

这可以通过执行
printf(“%s”,0xffffffff)来轻松检查

这是因为
%s
格式说明符需要一个指向以null结尾的字符串的
字符*
。您要传递的值不是此类型,并且可能不是有效的内存地址


整数提升在这里也不适用,因为没有比
int
unsigned int
低秩类型的表达式,因为常量
0xffffff
(假设
int
为32位)具有类型
unsigned int
,用于初始化
int
类型的对象,这涉及从
unsigned int
int
的转换

C标准第6.3.1.3节描述了整数类型之间的转换:

1当整数类型的值转换为除
\u Bool
以外的其他整数类型时,如果该值可以用新的 类型,它是不变的

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

3否则,新类型是有符号的,不能在其中表示值;要么结果是实现定义的 或者引发实施定义的信号

第3款适用于本案。所讨论的值不在目标类型的范围内,并且目标已签名。因此,将发生实现定义的转换

如果您使用gcc使用
-Wconversion
标志进行编译,它将向您发出警告:

x1.c:6:5:警告:将无符号常量值转换为负整数[-Wsign conversion]
int a=0xffffffff;
此外:

这可以通过执行
printf(“%s”,0xffffffff)来轻松检查

这是因为
%s
格式说明符需要一个指向以null结尾的字符串的
字符*
。您要传递的值不是此类型,并且可能不是有效的内存地址


整数提升在这里也不适用,因为没有比
int
unsigned int
低秩的表达式。问题是,您正在转换(不是您,而是编译器代表您)一个无符号数(值
0xffffffff
)转换为超出其有效值范围的有符号int
(您正试图将
4294967296
转换为
int
,但
int
仅涵盖
-2147483648
+2147483647
)因此您得到未定义的行为

根据您使用的编译器(和体系结构),您可以获得不同的值,甚至由于溢出而产生异常。我猜你的编译器使用了2的补码,它只是将这个数字重新解释为它的等价二进制表示形式,即
-1
-1
在内部表示为四个字节
0xff
一个af