### C语言面试题知识点详解
#### 一、`static` 关键字的用途
1. **限制变量的作用域**:当在文件范围内定义一个变量时,如果不加 `static` 关键字,则该变量在整个文件范围内可见(即全局变量)。但如果加上 `static` 关词,则变量仅在其定义的文件内可见,而在其他文件中不可见。
2. **设置变量的存储域**:`static` 变量被存储在静态存储区中,这意味着它们在整个程序运行期间都存在,并且只有一次初始化机会。
#### 二、引用与指针的区别
1. **初始化**:引用必须被初始化,而指针可以不必初始化。
2. **可修改性**:引用一旦初始化后就不能被改变,而指针可以重新指向另一个对象。
3. **空值**:不存在指向空值的引用,但存在指向空值的指针。
#### 三、实时系统的特征
1. **实时性**:实时系统需要在规定的时间内完成任务,确保系统的响应速度符合预定的要求。
2. **可靠性**:除了实时响应之外,系统还需要具备高度的可靠性和稳定性。
#### 四、全局变量与局部变量的区别
- **存储位置**:
- 全局变量通常存储在静态数据段中;
- 局部变量则存储在栈中。
- **生命周期**:
- 全局变量在整个程序运行期间一直存在;
- 局部变量只在其所在的函数或作用域执行期间存在。
#### 五、平衡二叉树
- 平衡二叉树是一种特殊的二叉树,它要求每个节点的左子树和右子树的高度差不超过1。
- 它能够保持较低的高度,从而提供高效的查找、插入和删除操作。
#### 六、堆栈溢出的原因
- 堆栈溢出通常是因为递归调用过深或者局部变量占用空间过大导致栈空间不足。
#### 七、不能声明为虚函数的情况
- 构造函数不能被声明为虚函数。
- 析构函数可以声明为虚函数,这主要是为了支持多态性的析构。
#### 八、冒泡排序算法的时间复杂度
- 冒泡排序算法最坏情况下的时间复杂度为 O(n^2)。
#### 九、浮点数与零值的比较
- 浮点数与零值的比较应该考虑精度误差,例如 `if (fabs(x) < 0.000001)`,这里使用了 `fabs()` 函数来获取 x 的绝对值,并通过一个小阈值来进行比较。
#### 十、Internet网络协议及其层次结构
- Internet 采用 TCP/IP 协议族,主要包括以下层次:
1. **应用层**:如 HTTP、FTP、SMTP 等。
2. **传输层**:如 TCP、UDP。
3. **网络层**:如 IP 协议。
4. **数据链路层**:如 Ethernet、PPP。
5. **物理层**:如光纤、双绞线等物理介质。
#### 十一、Internet物理地址和IP地址转换
- ARP(Address Resolution Protocol)协议用于将IP地址转换为物理地址(MAC地址)。
#### 十二、IP地址的编码组成
- IP地址由网络号和主机号两部分组成,通过子网掩码可以区分这两部分。
#### 十三、循环链表实现M-N计数
- 可以使用循环链表结合取余操作来实现从1到N的循环计数,每数到M时输出该数值。
#### 十四、局部变量与全局变量的重名处理
- 在C语言中,局部变量可以与全局变量重名,但局部变量会覆盖全局变量的作用,即局部变量在函数内优先级更高。
#### 十五、引用全局变量的方法
- 使用 `extern` 关键字声明一个全局变量,可以引用在其他文件中定义的全局变量。
#### 十六、在头文件中定义全局变量
- 可以在头文件中声明全局变量,但在具体的C文件中定义并初始化它,这样可以在多个文件中使用相同的全局变量。
#### 十七、无限循环问题
- `for(;;)` 表示无限循环,相当于 `while(true)`。
#### 十八、do...while与while...do的区别
- `do...while` 循环至少执行一次,然后检查条件是否为真,决定是否继续执行。
- `while...do` 循环先检查条件是否为真,如果为真则执行循环体。
#### 十九、C语言代码示例解析
- 对于代码示例中的 `a=10; b=a++; c=++a; d=10*a++;`,输出结果应为 `b, c, d: 10, 12, 120`。
- 这里需要注意自增运算符 `++` 的前后位置对变量值的影响。
#### 二十、`static` 关键字的使用
- `static` 关键字用于修饰全局变量时,可以使该变量仅在当前文件内可见,从而避免在其他文件中引起命名冲突的问题。
- `static` 关键字用于修饰局部变量时,可以使该变量在函数每次调用之间保留上次调用后的值。
- `static` 函数仅在当前源文件内可见,有助于提高代码的封装性和模块化。