1. include
头文件的顺序以及双引号""
和尖括号<>
的区别
头文件的包含顺序:
- 通常首先包含本项目的头文件。
- 接着包含第三方库的头文件。
- 最后包含标准库的头文件。
这样的顺序有助于确保在有名称冲突时,本项目的头文件会被优先考虑。
双引号""
和尖括号<>
的区别:
-
使用尖括号
<>
时,编译器会在标准库路径中查找头文件。这主要用于标准库头文件的包含,例如<iostream>
。 -
使用双引号
""
时,编译器首先在当前源文件所在的目录中查找头文件。如果未找到,再按标准库路径查找。这通常用于包含用户自定义或项目内部的头文件。
2. C++结构体和C结构体的区别
C中的结构体(struct
):
- 主要用于封装数据,不包含函数。
- 成员默认是公共的。
- 通常用于表示一组相关数据的集合。
C++中的结构体(struct
):
- 与C中的结构体相似,但可以包含成员函数、构造函数、析构函数等。
- 成员默认也是公共的,但可以明确指定为私有或受保护的。
- 在C++中,结构体和类非常相似,主要区别在于默认的访问权限和继承方式。然而,在现代C++编程中,这种区别并不明显。
3. 导入C函数的关键字是什么?C++编译时和C有什么不同?
导入C函数的关键字:
-
在C++中,使用
extern "C"
来告诉编译器这些函数使用C语言的链接约定。例如:extern "C" { #include "c_header.h" }
C++编译时和C的不同:
- C++编译器需要处理更多的语言特性,如类、模板和异常。
- C++编译涉及名称修饰以支持函数重载,而C语言编译器则不进行名称修饰。
- C++具有更严格的类型检查。
- C++支持面向对象编程,而C主要是过程式编程。
4. 指针和引用的区别
指针(Pointer):
- 存储另一个变量的地址的变量。
- 可以为空(NULL)。
- 可以重新赋值以指向另一个变量。
- 支持算术运算。
- 在多级间接寻址时很有用。
引用(Reference):
- 为某个变量提供的另一个名字或别名。
- 必须在声明时初始化,且一旦与某个变量关联后就不能再更改。
- 不能为NULL。
- 与其所引用的变量共享内存地址。
- 使代码更加清晰和易于维护。
5. 在函数传递参数时,什么时候用指针,什么时候用引用?
- 当需要修改传入的变量时,可以使用指针或引用。这样函数可以修改原始数据而不是其副本。
- 当参数可能为NULL或不需要修改时,使用指针。因为引用不能为NULL且一旦绑定不能更改。
- 当使用C++并希望代码更清晰、更安全时,倾向于使用引用。引用提供了更严格的类型检查,编译器会确保引用总是被初始化。
- 当处理动态数据结构或与C语言互操作时,通常使用指针。
6. 简述C++从代码到可执行二进制文件的过程
C++从源代码到可执行二进制文件的过程包括以下几个步骤:
1.预处理(Preprocessing):
- 预处理器接收源代码文件,处理以
#
开头的预处理指令(如#include
、#define
等)。 - 将包含的头文件内容替换到源代码中。
- 处理条件编译指令。
- 生成预处理后的文件(通常是
.i
或.ii
扩展名)。
2.编译(Compilation):
- 编译器将预处理后的文件转换成汇编语言。
- 进行语法和语义分析,检查错误。
- 进行优化(如果指定了优化选项)。
- 生成汇编代码文件(通常是
.s
扩展名)。但在现代编译器中,这一步通常与下一步合并,直接生成目标文件。
3.汇编(Assembly):
- 汇编器将汇编代码转换成机器代码(目标代码)。
- 生成目标文件(通常是
.o
在Unix-like系统上,.obj
在Windows上)。 - 目标文件包含机器代码,但还不是可执行文件,因为它可能依赖于其他目标文件或库。
4.链接(Linking):
- 链接器接收一个或多个目标文件以及所需的库文件。
- 解析符号引用,将调用的函数和变量链接到它们的实际定义上。
- 生成最终的可执行文件(通常是
.exe
在Windows上,无扩展名或.out
在Unix-like系统上)。 - 可执行文件包含可以直接由操作系统加载和执行的机器代码。
正文完