【问题标题】:converted an integer to short in C, get 4-byte when printed short在 C 中将整数转换为短整数,打印短时得到 4 字节
【发布时间】:2021-10-25 07:36:46
【问题描述】:

我将一个整数值转换为short,但是当我打印short的十六进制结果时,显示为4字节,我找不到原因。

#include <stdio.h>

void main()
{
   int j = 53191;
   short s = (short)j;
   printf("s = %x",s);
}

输出:ffffcfc7

【问题讨论】:

  • 另请注意,shorts 的长度可以是 4 个字节。
  • 根据@Jean-BaptisteYunès 的评论,您可能希望使用 typedef 的 stdint 集合来确保您的变量具有您期望的值范围。 int16_t 用于 16 位有符号整数(短),uint16_t 用于 unsigned short
  • 如果不是default argument promotions,您将通过使用"%x"(需要相应的unsigned 值)和short 类型的值来调用未定义行为。
  • @ᕮ_ᑐᑌᑎᕮ4 不,这不是这些帖子的重复,因为%hx 假定一个无符号参数。 short 不是未签名的。

标签: c integer short


【解决方案1】:

原因是%x 说明符期望传递一个 32 位整数(默认参数提升)。

数字前面的0xFFFF 表示您的数字实际上是负数。 这是因为53191 高于short 的“有符号阈值”(即 32k(-32,768 到 32,767))。

使用低于 32k 的值再试一次或使用unsigned short,您的结果应该会相应改变。

或者,或者,请参阅printf 的规范并在 x 之前使用 h 说明符。 (%hx) 而是告诉printf 期待short

(感谢 Adrian Mole 提醒我)

【讨论】:

  • O 只需使用%hx 格式说明符。
  • %hx 严格来说仍然会给出 UB,因为传递的类型不是无符号的。
【解决方案2】:

如果我们假设 int 是 4 个字节,short 是 2 个字节,那么值 53191 不适合短。然后发生的事情没有明确定义:

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

因此,由编译器来处理它认为合适的情况。一个常见的实现是将原始类型的二进制表示视为新类型的相应 2 的补码表示。在这种情况下,0xCFC7 被视为 short,值为 -12345。

接下来,%x 假定一个 unsigned int 类型的参数。 printf("s = %x",s); 因此也没有明确定义 - 严格来说,它是未定义的行为。

实际上,s 将根据适用于 printf 等所有可变参数函数的“默认参数提升”的要求进行提升。也就是说,从shortint。然后一个常见的非标准扩展是将提升的int 的二进制表示重新解释为无符号整数。如果发生这种情况,我们会观察到在参数提升期间发生的符号扩展,这意味着值将从0xCFC7 更改为0xFFFFCFC7。但是打印int%x 并不能保证行为,所以我们不应该依赖它或编写这样的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-28
    • 1970-01-01
    • 2011-01-03
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多