深入了解计算机系统中:unsigned char和char的思考和实验

笔者最近再看深入理解计算机系统,在看到书31(中文版)不禁对下面的程序起了疑惑

typedef unsigned char *byte_pointer;
void show_byte(byte_pointer start, size_t len) {
	for (size_t i = 0; i < len; i++)
		printf("%.2x", start[i]);
	printf("\n");
}

为什么byte_pointer是unsigned char*类型呢?而不是int *或者char *。话不多说,立马开始了实验

实验代码:

void show_int(int x) {
	show_byte(byte_pointer(&x), sizeof(int));
}
int main()
{
	unsigned int test = 12345;
	unsigned int test2 = 54321;
	show_int(test);
	show_int(test2);
	return 0;
}

当把byte_pointer改为int *时,程序结果为

深入了解计算机系统中:unsigned char和char的思考和实验_第1张图片

为什么回事这个呢?

通过debug,发现 printf("%.2x", start[i]); start[i]被解释为了int。所以,程序每次读取4个字节(int 的大小),并以16进制输出。


可以通过内存值来证明

start[0]  39 30 00 00 ->    3039

start[1]  5a 10 3a 01 ->     013a 105a

start[2]  5a 10 3a 01 ->    013a 105a

start[3]  00 90 f0 00  ->    00f0 0900

这也和输出是符合的。


在来看把byte_pointer改为char *时,程序结果为

深入了解计算机系统中:unsigned char和char的思考和实验_第2张图片

哇,好奇怪。打印出来的第一的是对的,第二个却很奇怪。

废话不多说,debug抄起。

此时start[i]被解释为了char

test =12345的16进制为00003039。test=54321的16进制为0000d431

而问题就是出现在这。

在打印test的情况下,

start[0] 39  <128

start[1] 30  <128

start[2] 00  <128

start[3] 00  <128

都是在char的正范围。但是在打印test=54321的情况下

start[0] 31 <128

start[1] d4 >128

start[2] 00 <128

start[3] 00 <127

在打印start[1]时,值超过了char的正范围。本来也是没什么问题的,但是此时打印格式是16进制。所以程序按照补码扩充。

d4  ->                                                    1101 0111

   -> 1111 1111 1111 1111 1111 1111 1101 0111->F F F F F F D 4

所以出了错误。


结语:

通过这次实验,我终于明白为什么呀用unsigned char *而不是其他了。

你可能感兴趣的:(深入理解计算机系统家庭作业)