根据提供的文档内容,我们可以归纳总结出以下几个重要的IT面试笔试知识点:
### 1. 字符串复制函数 `strcpy` 的实现
在C/C++编程中,`strcpy` 函数是用来复制字符串的基本工具。文档中给出了一个不使用标准库函数实现 `strcpy` 的示例代码。
#### 示例代码分析
```cpp
char* strcpy(char* strDest, const char* strSrc) {
if (strDest == NULL || strSrc == NULL)
return NULL;
if (strDest == strSrc)
return strDest;
char* tempPtr = strDest;
while ((*strDest++ = *strSrc++) != '\0')
;
return tempPtr;
}
```
- **功能**: 实现字符串复制。
- **参数**:
- `strDest`: 目的地字符串。
- `strSrc`: 源字符串。
- **返回值**: 返回目的地字符串的指针。
- **注意事项**:
- 需要检查输入参数是否为空。
- 如果目标和源字符串相同,则直接返回原字符串指针。
- 使用 `while` 循环逐个字符复制,直到遇到空字符 `\0` 结束。
- 最后返回最初的目标字符串指针。
### 2. 类 `String` 的实现
文档中还提供了一个简单的字符串类 `String` 的实现,包括了构造函数、拷贝构造函数、赋值运算符以及析构函数。
#### `String` 类的实现
```cpp
class String {
public:
String(const char* str = NULL); // 普通构造函数
String(const String& other); // 拷贝构造函数
~String(); // 析构函数
String& operator=(const String& other); // 赋值函数
private:
char* m_data; // 用于保存字符串
};
```
- **构造函数**:
- 接受一个 `const char*` 参数,并根据参数是否为空进行处理。
- 如果参数为空,则分配一个字符并置为 `\0`。
- 如果参数不为空,则分配足够的内存并使用 `strcpy` 复制字符串。
- **拷贝构造函数**:
- 接受一个 `String` 对象作为参数。
- 分配足够内存并使用 `strcpy` 复制字符串。
- **赋值运算符**:
- 实现自我赋值检查。
- 删除原有数据,分配新内存并复制字符串。
- **析构函数**:
- 释放 `m_data` 指向的内存。
### 3. C/C++ 编程基础知识问答
文档中还提到了一些常见的 C/C++ 编程基础知识问答。
#### 3.1 头文件中的 ifndef/define/endif 的作用
- **作用**: 防止头文件被重复包含,通常使用 `#ifndef`, `#define`, `#endif` 结构来实现。
#### 3.2 #include <filename.h> 和 #include "filename.h" 的区别
- **区别**:
- `#include <filename.h>`: 从标准库路径开始搜索文件。
- `#include "filename.h"`: 从当前工作目录开始搜索文件。
#### 3.3 在 C++ 程序中调用被 C 编译器编译后的函数为何要加 extern "C"
- **原因**:
- C++ 支持函数重载,C 不支持。
- C++ 编译后的函数名称可能与 C 不同。
- `extern "C"` 可以确保正确地调用 C 编译后的函数。
#### 3.4 构造函数的执行顺序
- **顺序**:
- 先执行基类构造函数。
- 再执行成员对象的构造函数。
- 最后执行自身构造函数。
- 若有虚基类,则优先执行虚基类的构造函数。
#### 3.5 设计模式
- **举例**: 单例模式、工厂模式等。
#### 3.6 UML 中聚合与组合的区别
- **聚合**:
- 表示整体与部分的关系,部分可以属于多个整体。
- 如书籍与页面的关系。
- **组合**:
- 表示更紧密的整体与部分的关系,部分与整体共存亡。
- 如书架与书籍的关系。
#### 3.7 C# 与 C++ 的不同之处
- **主要区别**:
- C# 支持垃圾回收机制。
- C# 限制使用指针。
- C# 只支持单一继承。
- C# 访问静态成员需通过类名。
- C# 覆盖父类方法需使用特定关键字。