【问题标题】:Showing Bytes in C在 C 中显示字节
【发布时间】:2018-02-21 23:28:46
【问题描述】:

我正在编写一个 C 程序,它必须以十六进制答案显示每个操作,但您必须显示与数据类型对应的所有字节。

例如,如果它是一个 int,它应该显示 8 个字节,如果它是一个短的 4 个字节。

它适用于所有其他数据类型,包括仅显示两个字节的 char。但是当我打印时,short 总是显示 8 个字节

char x5 = 0xa1;
short z5 = x5;

printf("\nProblem 1f: %x\n", z5);

它会打印“问题 1f: ffffffa1”

一位同学找到了一个解决方案,其中 %hx 打印了正确的字节数,但我不明白为什么这个 %x 会打印额外的字节,这些字节是从哪里来的?

提前致谢!

【问题讨论】:

  • 发生这种情况是因为整数提升。你char是一个8位有符号值,0xa1是b1010 0001,最高有效位设置为1,所以当它被提升为整数时(用短赋值和后来的printf,符号应用扩展名,用 1 填充所有其他 3 个字节。您最终得到 b1111 1111 1111 1111 1111 1111 1010 0001,即 ffffffa1。
  • 对我来说看起来是正确的。 char 是一个字节,打印为两个十六进制数字。 short 是 4 个字节,打印为 8 个十六进制数字。
  • @Pablo 是对的。试试这个:当x5=0x7f

标签: c byte


【解决方案1】:

这是由于静默整数类型提升。因为0xa1 是负值(-95 dec) char、short 将被提升为 4 字节 int 并被 printf 函数打印为负数。

为了防止提升,您可以使用unsigned 类型。

下面的程序说明了有符号和无符号类型的行为:

#include<stdio.h>
#include<stdlib.h>

int main() {

    char x5 = 0xa1;
    short z5 = x5;
    int i5 = x5;

    unsigned char ux5 = 0xa1;
    unsigned short uz5 = 0xa1;
    unsigned int ui5 = 0xa1;

    size_t sx5 = sizeof(x5);
    size_t sz5 = sizeof(z5);
    size_t si5 = sizeof(i5);


    printf("%zu %zu %zu\n", sx5, sz5, si5);  

    printf("%x %x %x\n", x5, z5, i5);     // silent promotion to 32 bit negative integers

    printf("%x %x %x\n", ux5, uz5, ui5);  // no promotion

    ux5 = x5;   
    uz5 = z5; // remember that z5 is negative number
    ui5 = i5; // same for i5

    printf("%x %x %x\n", ux5, uz5, ui5); // no promotion but numbers are negative ones

   return 0;
}

输出:

1 2 4
ffffffa1 ffffffa1 ffffffa1
a1 a1 a1
a1 ffa1 ffffffa1

【讨论】:

  • 好答案,来自我,只是一个小抱怨:打印size_t时使用%zu。
  • @Pablo 谢谢你,Pablo!我现在会记得%z。
【解决方案2】:

由于x5 足够大(任何超过127 或0x7F 的单字节数据类型)可以设置最高位(1010 0001),它被解释为使用默认签名类型时为负数。正如提到的另一个答案,使用unsigned char 解决了这个问题。但是,类型转换 x5 也可以,因为 short 使用两个字节来存储该值,即使已签名也不会将其视为负数 (0000 0000 1010 0001)。

类型转换将起作用:

char x5 = 0xa1;
short z5 = (unsigned char) x5;

因此将使用无符号字符:

unsigned char x5 = 0xa1;
short z5 = x5;

但如果您以这种方式使用它,您应该为所有内容指定无符号以避免此类情况。

unsigned char x5 = 0xa1;
unsigned short z5 = x5;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    • 2012-12-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多