众所周知,《深入计算机系统》是本程序员修内功的书。作为小白的我,现在也正在学习这本神书。在学习的过程中,总有一些知识吸引着我,因此现在我准备把刚读这本书的时候最吸引我的一个点表达出来。虽然,大佬们看着我的文会觉得十分简单,不过没关系,我正在向高处攀登的路上!
在运行程序之前,先要看懂代码。如下,就是经典的show-bites代码(只有片段且进行了简单粗暴的修改):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len){
size_t i;
for (i = 0; i < len; i++)
printf("%p\t0x%.2x\n", &start[i], start[i]);
printf("\n");
}
void show_twocomp()
{
short x = 12345;
short mx = -x;
show_bytes((byte_pointer) &x, sizeof(short));
show_bytes((byte_pointer) &mx, sizeof(short));
}
int main(int argc, char *argv[]){
int val = 12345;
if (argc > 1) {
exit(0);
} else {
printf("calling show_twocomp\n");
show_twocomp();
}
return 0;
}
我第一次看这串代码的时候,我总觉得自己处于一种似懂非懂的状态。感觉大致明白什么意思,但细致下来,发现很多代码都不知道是什么意思。现在,我打算把我第一次看的时候不知道的、模糊的地方讲解出来。
第一处:
typedef unsigned char *byte_pointer;
void show_bytes(byte_pointer start, size_t len){
这里,主要是两个点。第一个是typedef 的用法的格式是:typedef OldName NewName
作用就是把“OldName”取一个新的名字“NewName”,两个名字都是代表同一个东西。第二个就是“size-t”是什么东西。我在看这个时候,我只是觉得我知道“size”是一个数的大小什么的,十分的模糊。为此,我特意去查找了资料,最后得出了最为直观的答案。“size-t=typeof(sizeof(X))” 也就是说这个“size-t”也是表明某一大小的数据类型。
第二处:
printf("%p\t0x%.2x\n", &start[i], start[i]);
这段代码中,“%p”、“\t”、“%.2x”等都是什么意思呢?
格式控制符“%p”中的p是pointer(指针)的缩写。通常这个可以与地址对应。
"\t"的意思是 :水平制表符。将当前位置移到下一个tab位置。
“%x”指的是十六进制数,而“%.2x”指的是两位的十六进制数。举个例子,如果要输出1,则“%x”输出的是“1”,而“%.2x”输出的是“01”。这样子做是为了输出时能够对齐。
还有一个就是在“printf”中,“&start[i]”与“start[i]”输出的东西是不一样的。“&start[i]”输出的是存放start[i]的地址,“start[i]”输出的是存放在该变量里的值。
第三处:
show_bytes((byte_pointer) &x, sizeof(short));
show_bytes((byte_pointer) &mx, sizeof(short));
这里就有一个强制转换的格式在里面了。“(byte_pointer) &x”是将本为short型的x转换为无符号字符型。
同时,这里的“sizeof(short)”与函数中的“size-t”相对应,成功将short型数的大小传给“size-t”。
第四处:
int main(int argc, char *argv[]){
在学习《深入计算机系统》之前,我写C语言的主函数都是这样写的“int main(){
”
那么二者有什么区别呢?哪一个更好呢?
argc是命令行总的参数个数; argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数。
在运行时,这两个变量能够记录整个代码中所用过的参数,并且全部记录在argv中。
这整串代码在我的电脑上运行出来的结果如图:
已知12345的十六进制表示是0x3039,-12345的十六进制表示是0xcfc7。
从结果中看出,存放0x30的地址是0060FECF,存放0x39的地址是0060FECE。符合小端模式的“低对低,高对高”,即低位数据放在低地址,高位数据放在高地址。所以确定了该电脑是小端模式存储方式。
同时可以看出,先申明的变量x的地址比后申明的变量mx的地址要高。根据知识,局部变量存储于栈中,可以推测出该电脑的栈是向下取地址法。
这就是如何通过运行show-bites代码看出电脑存储数据的模式的整个过程。
作为小白的我,十分欢迎五湖四海的朋友的指点和批评,希望我们能够在这条道路上越走越远!