【发布时间】:2015-05-21 15:50:53
【问题描述】:
在 CentOS-5 64 位上使用 gcc 4.1.2 编译。
将整数打印为两个字符的十六进制字符串:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
int8_t iNegVar = -1;
int8_t iPosVar = 1;
printf(" int negative var is <%02X>\n", iNegVar);
printf(" int positive var is <%02X>\n", iPosVar);
return 0;
}
由于该值只有 1 个字节,我希望整数值“-1”会打印“0xFF”。但是,我得到:
int negative var is <FFFFFFFF>
int positive var is <01>
我尝试将其抽象为 char* 缓冲区,以一次打印 1 个字节。这产生了相同的结果:
#include <stdio.h>
#include <stdint.h>
void print_hex(void* pBuffer, uint8_t uiBufSize);
int main(void)
{
int8_t iNegVar = -1;
int8_t iPosVar = 1;
printf(" int negative var is <%02X>\n", iNegVar);
print_hex(&iNegVar, 1); //pass by reference
printf(" int positive var is <%02X>\n", iPosVar);
print_hex(&iPosVar, 1); //pass by reference
return 0;
}
void print_hex(void* pBuffer, uint8_t uiBufSize)
{
int i;
char pTmp[3]; //Holds 2-character string, plus NULL
char* pByteBuff = pBuffer; //Use char* to parse byte-by-byte
for(i = 0; i < uiBufSize; i++) //Process all bytes in buffer
{
sprintf(pTmp, "%02X", pByteBuff[i]); //store each byte as 2-character string in "pTmp"
printf(" Converted to %s!\n\n", pTmp);
}
}
打印:
int negative var is <FFFFFFFF>
Converted to FFFFFFFF!
int positive var is <01>
Converted to 01!
我认为“char”在 C 中是作为整数类型实现的,所以我决定尝试在“print_hex”函数中将“char* pByteBuff”更改为“unsigned char* pByteBuff” .这行得通,并且只打印了我期望的两个字符:
int negative var is <FFFFFFFF>
Converted to FF!
虽然这“解决”了我的问题,但问题仍然存在:为什么显式打印为两个字符的十六进制值会打印 8 个字符而不是指定的两个字符?
【问题讨论】:
-
这是因为负数的二进制表示:en.wikipedia.org/wiki/Signed_number_representations
-
@iharob - 我试了一下,并在原始问题发布中提到了它。它有效——寻找更多的“为什么”。感谢您的评论。
-
注意:""int8_t" 可能只有 1 个字节,也可能不只有 1 个字节" - 我确信如果系统支持
int8_t,它是可选的,它必须是 1 个char(字节)在 大小. -
@guidotex 规范“c11 der 7.20.1.1 精确宽度整数类型”确实详细说明了精确宽度类型,例如
int8_t,因为它是 2 的补码并且没有填充:正好是 8 位“因此,@987654330 @ 表示这种有符号整数类型,宽度正好为 8 位。” - 除了更广泛的精确类型的字节序和对齐要求外,没有编译器回旋余地。unsigned char不允许有填充 &char必须是最小尺寸类型且至少 8 位:尔格char是 8 位。 -
@guidotex ...“当 sizeof 应用于类型为 char、unsigned char 或 signed char 的操作数(或其合格版本)时,结果为 1”§6.5.3.4 4
标签: c