我定义了一个名为queryData的结构,如下面的代码所示。当我尝试使用shift和right操作来操作和分配数据时,qdata.data.data4 [0],打印出数据,我之前说过的数据是一个字符是错误的。这是8位,但当我打印时,它实际上是32位, 0xffffff8b 。我想知道它是怎么样的。谢谢。
int main(void){
union Data{
char data2[2];
char data4[4];
};
struct queryData{
char byte; // 2bytes or 4bytes.
union Data data;
};
struct queryData qdata;
unsigned long int data;
data = rand()%4294967295;
qdata.byte = 4;
qdata.data.data4[0] = (char)(data>>24);
qdata.data.data4[1] = (char)((data<<8)>>24);
qdata.data.data4[2] = (char)((data<<16)>>24);
qdata.data.data4[3] = (char)((data<<24)>>24);
printf("%ld\n",data);
printf("%x\n",qdata.data.data4[0]);
printf("%x\n",qdata.data.data4[1]);
printf("%x\n",qdata.data.data4[2]);
printf("%x\n",qdata.data.data4[3]);
printf("%x",(unsigned int)(1804289383<<8)>>24);
return EXIT_SUCCESS;
}
结果如下: The result after run
答案 0 :(得分:1)
您使用的是错误的printf
格式。使用%hhd
作为char
作为数值。如果您希望以十六进制格式打印,则必须使用unsigned char
作为类型,而不是char
。
您所观察到的是,char
被提升为int
,并将其传递给printf
。然后,您将int
打印为unsigned
十六进制。因为您的平台似乎有一个带符号的char
类型并且使用了两个补码来表示负值,所以您会看到所有起始位都已打开的模式。
答案 1 :(得分:0)
诸如printf之类的Vararg函数会将小于int的所有整数提升为int。由于char是一个整数(在你的例子中是8位有符号整数),你的字符将通过符号扩展名提升为int。
由于8b具有前导1位(并且作为8位整数为负),因此它们将被符号扩展,而样本中的其他符号则不会。
要避免此类促销,您必须在printf中使用长度说明符:
printf("%hhx\n",qdata.data.data4[1]);