《深入理解计算机系统-CSAPP》练习题笔记(一)

前言


实验室学长毕业临走前,推荐了《深入理解计算机系统》CSAPP,大部头。第1章《计算机系统漫游》,去年寒假前翻了一遍。后面由于实验室的事就一直放在那里。前一段时间,继续从第2章看起《信息的表示和处理》。内容还是比较晦涩,硬着头皮翻了一遍。

作为软件工程专业的学生,大二时学过《计算机组成与结构》。课本用的是自己老师编的书,第2章也是数据的表示和运算。当时把那些进制表示、原码、补码、加减法等基本都挺熟的,一来时间过了4年了,二来当时还是学的比较简单。

《深入理解计算机系统》书中的讲解,显示出作者强大的数理逻辑背景,信手拈来。而看起来如果没有一点基础,真是挺难的。上网看了下大家的评论,都反映没有一定基础看不进去。这本书有一个好,每小节都带有练习题,而这些练习题都非常有趣。于是我就三分看书,七分看题。

现摘录若干道比较有意思的题目,做个笔记,也是分享。


布尔代数简介 & C语言中的位级运算


练习题2.10


对于任一位向量a,有a^a=0(异或)。应用这一属性,考虑下面程序:


void inplace_swap(int *x,int *y){

      *y = *x ^ *y;

      *y = *x ^ *y;

      *y = *x ^ *y;

}


这个过程是交换指针变量x、y所指向的存储位置处存放的值。这与通常的方法:需要第三方位置来临时存储另一个值的做法不同。这种交换方式并没有性能上的优势,仅仅是一个智力游戏。填写下表。回想一下,每个元素就是自

步骤 *x *y
初始 a b
第一步    
第二步    
第三步    

练习题2.10计算结果


步骤 *x *y
初始 a b
第一步 a a^b
第二步 b a^b
第三步 b a


可以看到,三步以后,*x和*y的值做了一个交换。


练习题2.11


在练习题2.10的inplace_swap函数的基础上,你决定写一段代码,实现将一个数组中的元素头尾两端依次对调。写出下面这个函数:


void reverse_array(int a[ ], int cnt){

    int first, last;

    for (first = 0,last = cnt-1;first <= last; first++,last--)

          inplace_swap(&a[first], &a[last]);

}


当你使用这个函数时,会发现这段代码对所有偶数长度的数组都可以正确工作,但是当数组长度变为奇数时,就会把中间的元素设置为0.


A:对于一个长度为奇数的数组,函数reverse_array最后一次循环时,变量first和last的值分别是什么?

B:为什么这时调用函数会将中间元素设置为0?

C:对这段代码做哪些简单改动就可消除这个问题?


练习题2.11解答


A:最后一次循环时,两个变量值相同。奇数数组长度为2k+1,则变量值为中间的元素值array[k]。

B:当调用inplace_swap函数时,实际上两个参数指向同一个位置。*x=*y。由于a^a=0,第一步运算后,*y=0=*x。后两步再运算,值全是0。最终array[k]=0。

C:将for循环中的条件first <= last,改为first < last 即可。不让两个相同元素交换,即可保证代码逻辑正确。

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