读《C专家编程》总结二

接上篇《C专家编程》总结一

这一篇总结主要是书中附录介绍的“程序员工作面试的秘密”。

1.怎样才能检测到链表中存在循环

第一种答案:
对访问过的每个元素做个标记,继续遍历这个链表,如果遇到某个已经做过标记的元素,说明链表存在循环。

第二个限制:
这个链表位于只读内存区域,无法在元素上做标记。
第二种答案:
当访问每个元素时,把它存储在一个数组中。检查每一个后继的元素,看看它是否已经存在于数组中。

第三个限制:
内存空间非常有限,无法创建一个足够长的数组。然后,可以假定如果链表中存在循环,它出现在前N个元素之中。
第三种答案:
设置一个指针,指向链表的头部。在接下去对直到第N个元素的访问中,把N-1个元素依次同指针指向的元素进行比较。然后指针移向第二个元素,把它与后面N-2个元素进行比较。根据这个方法依次进行比较,如果出现比较相等的情况就说明前N个元素中存在循环,否则如果所有N个元素两两之间进行比较都不相等,说明链表中不存在循环。

第四个限制:
链表的长度是任意的,而且循环可能出现在任何位置。
最后的答案:
首先,排除一种特殊的情况,就是3个元素的链表中第2个元素的后面是第1个元素。设置两个指针p1和p2,p1指向第一个元素,p2指向第三个元素,看看它们是否相等。如果相等就属于上述这种特殊情况。如果不等,把p1向后移动一个元素,p2向后移动两个元素。检查两个指针的值,如果相等,说明链表中存在循环。如果不相等,继续按照前述方法进行。如果出现两个指针都是NULL的情况,说明链表中不存在循环。如果链表中存在循环,用这种方法肯定能够检测出来,因为其中一个指针肯定能够追上另一个(两个指针具有相同的值),尽管有可能要对这个链表经过几次遍历才能检测出来。

2.库函数调用和系统调用区别何在

简明的回答是函数库调用是语言或应用程序的一部分,而系统调用是操作系统的一部分。

3.文件描述符与文件指针有何不同

文件描述符不是ANSI C的一部分,它依赖于操作系统,不会存在于非Linux环境。但是文件指针是ANSI C的一部分,与操作系统无关,用户使用他们可以在任何一个操作系统上运行。

4.编写一些代码,确定一个变量是有符号数还是无符号数

1.在ANSI C中“char”即可以是有符号数,也可以是无符号数,这由编译器决定的。当你编写的代码需要移植到多个平台时,知道类型是不是有符号数就非常有用了。
2.无法用函数实现目的。函数形式参数的类型是在函数内部定义的,所以它无法穿越调用这一关。因此,必须编写一个宏,根据参数的声明对它进行处理。
3.下面要区别宏的参数是一个类型还是一个类型的值。如果是一个值,无符号数的本质特征就是它永远不会小于0,有符号数的本质特征是对最左边一个位取反将会改变它的符号(其实对这个数所有bit取反是一样的),因此,这个宏可以这样写:
#define ISUNSIGNED(a)   (a>=0 && ~a>=0)
如果宏的参数是一个类型,一种方法就是使用类型转换:
#define ISUNSIGNED(a)   ((type)0 - 1 > 0)

已完。

原文地址:https://www.cnblogs.com/cnpirate/p/2721825.html