【问题标题】:Signed Char Decimal to Hexadecimal Conversion in C programming [duplicate]C编程中的有符号字符十进制到十六进制转换[重复]
【发布时间】:2019-12-23 06:54:55
【问题描述】:

我正在尝试做某事,我基本上有两个问题。创建签名字符时,您如何 a)初始化和打印语句的约定是什么,用于以十六进制打印它和 b)如果我为我的字符分配了 -32 的值,我如何在 'e0' 之前打印没有 'ffffff' 的十六进制并且只打印 'e0' (如果可能的话,不删除 - )

我已经尝试了所有给出的常规语法,只是想知道我是否缺少明显的东西。

#include <stdio.h>

int main(void) {
    signed char tempC = -32;
    printf("%x\n", tempC);
    return 0;
}

预期结果:e0

实际结果:ffffffe0

【问题讨论】:

  • %x 格式指定对应的参数是unsigned 类型。通过传递signed char,您的代码的行为因此是未定义的。为了达到您的预期,您需要将signed char 转换为unsigned char,然后将unsigned char 转换为unsigned 以便打印。例如,printf("%x\n", (unsigned)((unsigned char)tempC))。而且,不,您不能直接将其转换为unsigned,因为signed charunsigned 的转换将根据unsigned 的最大值进行换行。
  • 如果你想在你的printf格式中使用%x,那么你需要传递一个unsigned int。您可以使用(unsigned) (tempC &amp; 0xff)。在这种情况下,tempC 被提升为signed int,然后除了最右边的 8 位之外的所有内容都被屏蔽掉,结果被强制转换为 unsigned int
  • @Peter 你为什么说unsigned而不是signed-320xff 都可以表示为int,因此根据C11 Standard - 6.3.1.1 Boolean, characters, and integers(p2),促销是int

标签: c


【解决方案1】:

嗯,这就是有符号数的表示方式。

这是 2 的补码形式。

如果你认为它是:

unsigned char tempC = -32;

这将导致e0

简单的逻辑是%x 格式说明符将打印所有32 位,而char 仅具有8 位。剩余的24 位是1,因为它们以2's 补码形式存储。如您所知,1111 以十六进制表示 f。所以ffffff 将代表那些剩余的24

unsigned char 的情况下,它们不存储为2's 补码,剩余的24 位为0

【讨论】:

    【解决方案2】:

    诸如printf() 之类的变量参数函数的省略号部分的参数经过默认参数提升(C11 §6.5.2.2 Function calls,¶6)。这意味着signed char 被转换为signed int。然后,您尝试将其打印为十六进制值。这严格会导致未定义的行为(正在打印的值无法表示为intunsigned int 和十六进制格式假定unsigned int),但您通常会得到您所看到的。

    如果您的系统支持 C99 格式字符串,您可以使用 %hhx 将值打印为(无符号)char。您可以修剪使用tempC &amp; 0xFF 传递的值。

    【讨论】:

    • 我怀疑 "%hhx" 仍然是 UB。 Format 需要 unsigned 参数和 -32 作为提升的 int 失败“不能同时表示为 int 和 unsigned int”。
    猜你喜欢
    • 2016-12-27
    • 2012-01-24
    • 2018-01-31
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 2017-08-12
    相关资源
    最近更新 更多