首页 文章

“int”和“unsigned int”之间的真正区别

提问于
浏览
42

int

32位int数据类型可以包含-2,147,483,648到2,147,483,647范围内的整数值 . 您也可以将此数据类型称为signed int或signed .

unsigned int

32位无符号int数据类型可以包含0到4,294,967,295范围内的整数值 . 您也可以将此数据类型简称为无符号 .

好的,但是,在实践中:

int x = 0xFFFFFFFF;
unsigned int y = 0xFFFFFFFF;
printf("%d, %d, %u, %u", x, y, x, y);
// -1, -1, 4294967295, 4294967295

没有区别,O.o . 我有点困惑 .

9 回答

  • 1

    问题是你调用了Undefined Behaviour .


    当你调用 UB 时,任何事情都可能发生 .

    作业还可以;第一行有一个隐式转换

    int x = 0xFFFFFFFF;
    unsigned int y = 0xFFFFFFFF;
    

    但是,对 printf 的调用还不行

    printf("%d, %d, %u, %u", x, y, x, y);
    

    UB% 说明符和参数类型不匹配 .
    在您的情况下,通过提供1 int ,1 unsigned int ,1 int 和1 unsigned int ,按此顺序指定2 int s和2 unsigned int s .


    不要 UB

  • 1

    intunsigned int 的内部表示是相同的 .

    因此,当您将相同的格式字符串传递给 printf 时,它将被打印为相同 .

    但是,比较它们时存在差异 . 考虑:

    int x = 0x7FFFFFFF;
    int y = 0xFFFFFFFF;
    x < y // false
    x > y // true
    (unsigned int) x < (unsigned int y) // true
    (unsigned int) x > (unsigned int y) // false
    

    这也可以是一个警告,因为在比较有符号和无符号整数时,其中一个将被隐式地转换为匹配类型 .

  • 0

    他在问真正的区别 . 当您谈论未定义的行为时,您处于语言规范提供的保证级别 - 它在您最喜欢的编译器上完美定义's far from reality. To understand the real difference please check this snippet (of course this is UB but it':

    #include <stdio.h>
    
    int main()
    {
        int i1 = ~0;
        int i2 = i1 >> 1;
        unsigned u1 = ~0;
        unsigned u2 = u1 >> 1;
        printf("int         : %X -> %X\n", i1, i2);
        printf("unsigned int: %X -> %X\n", u1, u2);
    }
    
  • 23

    该类型只是告诉你比特模式应该代表什么 . 这些比特只是你对它们所做的 . 相同的序列可以用不同的方式解释 .

  • 15

    printf 函数根据匹配位置中的格式说明符解释传递它的值 . 如果你告诉 printf 你传递 int ,但是传递 unsignedprintf 将重新解释为另一个,并打印你看到的结果 .

  • 42

    呵呵 . 你在这里有一个隐式演员,因为你告诉 printf 期望什么类型 .

    请尝试使用此尺寸代替:

    unsigned int x = 0xFFFFFFFF;
    int y = 0xFFFFFFFF;
    
    if (x < 0)
        printf("one\n");
    else
        printf("two\n");
    if (y < 0)
        printf("three\n");
    else
        printf("four\n");
    
  • 3

    是的,因为在你的情况下他们使用the same representation .

    当解释为32b有符号整数时,位模式 0xFFFFFFFF 看起来像-1,当解释为32b无符号整数时,位模式看起来像4294967295 .

    它与 char c = 65 相同 . 如果将其解释为有符号整数,则为's 65. If you interpret it as a character it' s a .


    由于R和pmg指出,从技术上讲,传递与格式说明符不匹配的参数是未定义的行为 . 所以程序可以做任何事情(从打印随机值到崩溃,打印“正确”的东西等) .

    该标准指出 7.19.6.1-9

    如果转换规范无效,则行为未定义 . 如果任何参数不是相应转换规范的正确类型,则行为未定义 .

  • 6

    它们如何存储在内存和寄存器中没有区别,没有有符号和无符号版本的int寄存器没有用int存储的签名信息,差异只在执行数学运算时变得相关,有内置于CPU中的数学运算的有符号和无符号版本,签名告诉编译器使用哪个版本 .

  • 2

    这个很直接 . 二进制表示是它被提及但从未显示的键 . 如果0XFFFFFFF =机器代码= 1111 1111 1111 1111 1111 1111 1111 1111 = 4,294,967,295 数字的正表示,则在HEX中无符号 . 这一切都很好,但我们需要一种方法来表示负数 . 所以大脑决定两个补码 . 这意味着什么,简而言之,他们取最左边的数字,并决定当它是1(然后是所有的直到你到达最左边的最高位),如果它是0,则数字将是负数 . 现在让我们来看看 0000 0000 0000 0000 0000 0000 0000 0011 = 3 会发生什么 . 现在让我们继续添加这个数字 0111 1111 1111 1111 1111 1111 1111 1111 = 2,147,483,645 带有signed int的最高正数 . 让我们加1(这里你可能想要查找二进制加法)我们必须一直带着它 . 1111 1111 1111 1111 1111 1111 1111 1110 = -1 所以我想简而言之,我们可以说差异是允许负数而另一个不允许,这是由于 sign bit 或最左位或最高位 .

相关问题