gpt4 book ai didi

c - 为什么将负整数分配给 unsigned int 不会导致错误?

转载 作者:太空宇宙 更新时间:2023-11-04 05:58:18 25 4
gpt4 key购买 nike

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
unsigned int i;
i = -12;
printf("%d\n" , i);
system("pause");
return 0;
}

我在 Visual Studio 2012 中运行上面的代码。因为我知道 unsigned 指的是非负数,所以我预计程序会报错。为什么它仍然运行流畅并打印输出?

最佳答案

正如 200_success 所暗示的那样,尽管混合无符号和有符号整数值存在明显的问题,但这里有两件事正在结合以产生正确的输出。

首先,行 i = -12 隐式地将(有符号的)int 文字值 -12 转换为 unsigned整数。存储在内存中的位不会改变。它仍然是 0xfffffff4,这是 -12 的二进制补码表示。但是,unsigned int 会忽略符号位(最高位),而是将其视为值的一部分,因此作为 unsigned int,此值(0xfffffff4) 被解释为数字 4294967284。这里的底线是 C 对有符号和无符号值之间的隐式转换有非常宽松的规则,尤其是在相同大小的整数之间。您可以通过执行以下操作来验证这一点:

printf("%u\n", i);

这将打印 4294967284

这里发生的第二件事是 printf 除了您通过格式字符串告诉它的内容外,对您传递给它的参数一无所知.对于使用可变参数列表定义的 C 中的所有函数(例如,int printf(const char *fmt, ...);),这基本上是正确的,这是因为编译器不可能确切地知道哪些类型的参数可能会传递给此函数,因此当编译器生成用于调用此类函数的汇编代码时,它无法进行类型检查。它所能做的就是确定每个参数的大小,并将适当数量的字节压入堆栈。因此,当您执行 printf("%d\n", i); 时,编译器只是将 sizeof(unsigned int) 字节压入堆栈。它无法进行类型检查,因为 printf 的函数原型(prototype)没有关于任何参数类型的任何信息,除了第一个参数 (fmt) ,它知道这是一个 const char *。任何后续参数都只是复制为一定字节数的通用 blob。

然后,当 printf 被调用时,它只查看堆栈上的第一个 sizeof(unsigned int) 字节,并按照您告诉它的方式解释它们到。即,作为带符号的 int 值。由于存储在这些字节中的值仍然只是 0xfffffff4,它会打印 -12

编辑:请注意,通过声明内存中的值为 0xfffffff4,我假设 sizeof(unsigned int ) 在你的机器上是 4 个字节。 unsigned int 可能在您的机器上被定义为其他大小。但是,相同的原则仍然适用,无论值是 0xfff4 还是 0xfffffffffffffff4,或者它可能是什么。

关于c - 为什么将负整数分配给 unsigned int 不会导致错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23095914/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com