【发布时间】:2017-08-31 22:58:23
【问题描述】:
我试图用 C 语言编写一个函数来打印出通用数据类型值的十六进制表示。我第一次尝试失败,第二次成功,为什么?
-
第一次尝试
#include <stdio.h> /* prints out the hexadecimal representation of a generic value */ void show_hex(void*,size_t); int main() { int i = 12345; short s = 32767; /* 2^15 - 1 */ show_hex(&i, sizeof(int)); show_hex(&s, sizeof(short)); return 0; } void show_hex(void *x, size_t sz){ char *cx = x; int i; printf("0x"); for (i = 0; i < sz; ++i) printf("%.2x", cx[i]); printf("\n"); }输出:
0x39300000用于int情况,正如在 little endian 机器 (Mac OSX) 上所预期的那样。对于short的情况,它输出0xffffffff7f而不是0xff7f。 -
第二次尝试:
typedef unsigned char *byte_pointer; int main() { int i = 12345; short s = 32767; /* 2^15 - 1 */ show_hex((byte_pointer)&i, sizeof(int)); show_hex((byte_pointer)&s, sizeof(short)); return 0; } void show_hex(byte_pointer x, size_t sz){ int i; printf("0x"); for (i = 0; i < sz; ++i) printf("%.2x", x[i]); printf("\n"); }此程序在两种情况下都按预期输出
int: 0x39300000和short: 0xff7f
【问题讨论】:
-
对于第一种情况,将
printf("%.2x", cx[i]);更改为printf("%.2x", cx[i] & 0xFF);。普通的char类型是有符号的,因此 0xFF 被符号扩展为一个全为 F 的 8 字节值,如打印输出所示。使用printf()和其他可变参数函数,参数列表的...部分中的参数默认提升,因此char提升为int(与short一样),float提升为@987654339 @. -
@JonathanLeffler:你应该把它作为答案,因为它是值得的。
-
或者像第二次一样在第一次尝试中使用
unsigned char。 (我必须说你很好地隐藏了这种微妙的差异)。 -
输出不应该是 0x00003039 和 0x7fff,那为什么不做 'for(i = sizeof(int) - 1; i >= 0; i--)'?
-
感谢@JonathanLeffler 的回答。还是很模糊。为什么
int值在两种情况下都得到相同的输出?事实证明,short在第一种情况下的值,它在第一次迭代cx[0] = ffffffff中输出ffffffff(4 个字节)。我的论点是:cx是char*,所以当我们取消引用它时它应该给我们一个字节而不是四个,对吧?。
标签: c generics hex void-pointers