【问题标题】:Clarifications about unsigned type in C关于 C 中无符号类型的说明
【发布时间】:2020-07-05 05:24:32
【问题描述】:

您好,我目前正在学习 C,但有些东西我完全不明白。 首先有人告诉我,如果我这样做:

unsigned int c2 = -1;
printf("c2 = %u\n", c2);

根据这张表,它会输出 255:

但我得到一个奇怪的结果:c2 = 4294967295

现在更奇怪的是这有效:

unsigned char c2 = -1;
printf("c2 = %d\n", c2);

但我不明白,因为char 是,好吧,char,为什么它甚至打印任何东西?因为这里的说明符是%d 而不是%u,因为它应该用于无符号类型。

【问题讨论】:

  • 在 C 中,char 也是数字类型
  • int(还有unsigned int)通常是一个32位整数类型。您引用的表仅显示 8 位。尝试使用更多位来推断模式...
  • 继续该表 24 位,你就有答案了
  • 关于%d适用于char,这是因为小于int的类型值是promotedint
  • @chux 我在看第一个printf。我应该早点删除那条评论。

标签: c memory char unsigned integer-promotion


【解决方案1】:

以下代码:

unsigned int c2 = -1;
printf("c2 = %u\n", c2);

永远不会打印255。您正在查看的表格是指一个 8 位的无符号整数。 C 中的 int 至少需要 16 位才能符合 C 标准(UINT_MAX 在第 5.2.4.2.1 段第 22 页here 中定义为 2^16-1)。因此,您将看到的值将比 255 大得多。最常见的实现使用 32 位来表示 int,在这种情况下,您将看到 4294967295 (2^32 - 1)。

您可以通过执行sizeof(type_or_variable) * CHAR_BITCHAR_BITlimits.h 中定义并表示每个字节的位数,这在大多数情况下也是如此)来检查系统上任何类型的变量使用了多少位8).

获取255作为输出的正确代码是:

unsigned char c = -1;
printf("c = %hhu\n", c);

hh 前缀说明符的含义(来自man 3 printf):

hh:后面的整数转换对应于signed charunsigned char 参数,或者后面的n 转换对应于指向signed char 参数的指针。

其他任何事情都只是实现定义或更糟糕的未定义行为。

【讨论】:

    【解决方案2】:

    在此声明中

    unsigned char c2 = -1;
    

    -1 的内部表示被截断为一个字节并解释为无符号字符。即对象 c2 的所有位都已设置。

    在本次通话中

    printf("c2 = %d\n", c2);
    

    具有 unsigned char 类型的参数被提升为 int 类型,保留其值为 255。该值作为整数输出。

    这是声明吗

    unsigned int c2 = -1;
    

    没有截断。通常占用 4 个字节的整数值 -1(根据 int 类型的大小)被解释为所有位设置的无符号值。

    所以在这次通话中

    printf("c2 = %u\n", c2);
    

    输出 unsigned int 类型的最大值。这是最大值,因为内部表示中的所有位都已设置。从有符号整数类型到更大的无符号整数类型的转换保留将其传播到无符号整数对象宽度的符号。

    【讨论】:

    • "-1 的内部表示被截断为一个字节并解释为无符号字符。' --> 2的补码的合理解释int.
    【解决方案3】:

    在C中整数可以有多种表示,所以有多种存储大小和取值范围 详情请参阅下表。

    【讨论】:

    • 您显示的表格(不能复制粘贴或屏幕阅读器使用,请不要发布图片)是最常见的范围和大小。除了long,即使在 64 位系统上也可能是 4 字节(32 位)(例如,Micosoft Visual C++ 使用 32 位 long)。它错过了 64 位(至少)类型long long
    • 这没有回答问题,表格只是显示了标准的许多有效实现中的 一些
    猜你喜欢
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多