(1)怎样才能检测到链表中存在循环
面试者可能如下作答
1.
2.
3.
设置一个指针,指向链表的头部。在接下去对直到第N个元素的访问中,把N-1个元素依次同指向的元素进行比较。然后指针移向下一个元素,把同后面的N-2个元素进行比较。根据这个方法依次进行比较,如果出现比较相等的情况,就说明前N个元素中存在循环,否则如果所有N个元素两两之间进行比较都不相等,说明链表中不存在循环。
4.参考答案
(2)不同的增值语句有什么区别
需要提供适当的上下文才好找出其中的区别
(1)
x += 1; 是在算法语言中表达 "x = x + 1;"的便捷方法
(2)
++x 它先增加 x的值,然后再在周围的表达式中 使用x的值
x++ 先在周围的表达式中 使用x的值,然后再增加x的值
(3)
当x不是一个简单的变量而是一个涉及数组的表达式,像x += 1 这样的形式是很有用的。
如果你有一个复杂的数组引用,并需要证明 同一种 下标形式在两种引用中都可以使用,那么
就是你应该采用的方法。
(4)
左值(通常具有一个地址,它也可能是一个寄存器,也可能是地址或者寄存器加上一个位段)
只被计算了一次。
这意味着,表达式
mango[j++] += y;
被当作
mango[j] = mango[j] + y;
j++;
而不是
mango[j++] = mango[j++] + y;
有人解释说,这些区别与编译器的中间代码有关。例如,"++x"表示取地址x的地址,增加它的内容,然后把值放在寄存器中:"x++"则表示取x的地址,把它的值转入寄存器,然后增加在内存中的x的值
(5)
K & R 认为 ++ 比 直接加 1 更有效率。
但是 当代编译器 在没有区别的上下文中,产生的代码相同的指令,它们应该是 增加一个变量最快的一种指令。
一般较短的形式 比 较长的形式 更容易阅读一些。
然而,过度简洁的代码 也会导致代码难以阅读
frotz[--j + i++] += --y;
改成
--y;
--j;
frotz[j+i] = frotz[j+i] + y;
i++;
所以,不要在一行代码里实现太多的功能
因为这并不会使编译器 产生更有效率的代码,但会使你丧失调试代码的机会。
K & R 说:
人人都知道调试比第一次编写代码要难上一倍。所以,如果在编写代码时就把自己的聪明发挥到极致,那么调试时又该怎么办呢?
(3)库函数调用和系统调用
简单的回答是
而 系统调用是操作系统的一部分。
你要确保 弄懂 trap的含义。系统调用是 操作系统内核 发现一个 trap 或者中断之后进行的。
库函数调用
在ANSI C编译器中,C函数库是系统的
调用函数库的一个程序
与用户程序相联系
在用户的地址空间执行
运行时间属于“user”时间
属于过程调用,开销较小
在C函数库libc中大约300个程序
典型调用
但是,你必须记住:
比如文件系统相关的操作
windows中fopen
(4)文件描述符和文件指针
系统IO调用有 creat(),open(),read(),write(),close(),ioctl(),接受一个文件描述符,是一个整数,用于索引开放文件的每个进程表(per-process table -of -open -file)
为了确保程序的可移植性应该使用标准IO库调用,如fopen(0,fclose(),fputc(),fseek()等,它们绝大多数中的名字中带有一个"f"。这些调用都接受一个类型为FILE结构的指针(有时称为流指针)的参数。FILE指针指向一个流结构,在<stdio.h>中定义。结构的内容根据编译器的不同而有所不同,在UNIX中通常是Open File的每个进程表的一个条目。在典型情况下,它包含了流缓冲区、所有用于提示缓冲区有多少字节是实际的文件数据的变量以及提示流状态的标志(如ERROR和EOF)等
所以,文件描述符 就是 Open File中的每个进程表的一个偏移量(如"3")。它用于UNIX系统中,用于标识文件。
FILE指针保存了一个FILE结构的地址。FILE结构用于表示 开放的I/O流(如hex 20938).它用于ANSI C标准的IO库调用中,用于标识文件。
(5)确定一个变量unsigned 还是signed
函数的参数形式是在函数内部定义的,所以你无法用函数来实现这个目的。
那么用 宏。
有符号数的本质就是 对最左边的一个位取补将会改变它的符号。由于其他位与这个测试无关,所以你可以将它的所有位都取补。
#define ISUNSIGNED(a) (a >=0 && ~a >= 0)
ANSI C的类型提升规则(所有的表达式中,如果是个变量,因为编译器无法判断结果是否溢出,都对类型进行提升)
char
short int
bit(unsigned /signed)
enum
如果int能够完整的容纳原先的数据,否则将被转换为 unsigned int
gcc 居然丢出这样一句话来
warning: comparison is always true due to limited range of data type
如果是一个类型
#define ISUNSIGNED(type) ((type)0 - 1) > 0)