编译和链接
一般高级语言的编译过程:预处理、编译、汇编、链接
- 源程序 → 预处理 → 编译和优化 → 生成目标文件 → 链接 → 可执行文件
- 预处理是C语言程序从源代码变成可执行程序的第一步,主要是C语言编译器对各种预处理命令进行处 理,包括头文件的包含、宏定义的扩展、条件编译的选择等。
- 编译是指编译器读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码。
- 汇编实际上指汇编器(as)把汇编语言代码翻译成目标机器指令的过程。
- 链接指的是将目标代码同使用的函数的目标代码以及一些标准的启动代码组合起来,生成程序的运行阶段版本。
内存(位与字节)
计算机内存的基本单元是 位(bit)。
字节(byte/B)通常指的是8位内存单元。从这个意义上说,字节指的就是描述计算机内存量的度量单位。然而,C++对字节的定义与此不同。C++字节由至少能够容纳实现的基本字符集的相邻位组成,也就是说,可能取值的数目必须大于等于字符数目。
sizeof
运算符返回类型或变量的长度,单位是字节
#include <iostream>
#include 为预处理器编译指令,该编译指令将导致:在源代码被编译之前,预处理器将 iostream 文件的内容添加到程序中。即,iostream 文件的内容将取代程序中的代码行#include <iostream>
,原始文件没有修改,而是将源代码文件和 iostream 组合成一个复合文件,编译的下一阶段将使用该文件。
int main(void)
上述语句在C++中,在括号中使用void与让括号空着等效,即函数不接受任何参数。
而在C中,让括号空着意味着对是否接受参数保持沉默。
endl 和 “\n”
endl确保程序继续运行前刷新输出(将其立即显示在屏幕上),而使用 “\n” 不能提供这样的保证,这意味着在有些系统中,有时可能在您输入信息后再会出现提示。
编译指令 using namespace
- 命名空间 namespace 是ANSI C++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。
- 命名空间实际上就是一个由程序设计者命名的内存区域,程序设计者可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。
- 本质上讲namespace是对全局作用域的细分。
- 作用域解析运算符 “::”
- 使用:
- 命名空间的名字也必须在定义它的作用域内保持唯一。
- 命名空间既可以定义在全局作用域内,也可以定义在其它命名空间中,但是不能定义在函数或类的内部。
- 命名空间作用域后面无须分号。
- 嵌套的命名空间中的名字遵循的规则与往常类似:内层命名空间声明的名字将隐藏外层命名空间声明的同名成员。在嵌套的命名空间中定义的名字只在内层命名空间中有效,外层命名空间中的代码要想访问它必须在名字前添加限定符。
让程序能访问命名空间 std 的方法有多种,下面是其中4种:
- 将
using namespace std;
放在函数定义之前,让文件中所有的函数都能够使用命名空间 std 中所有的元素。 - 将
using namespace std;
放在特定函数定义中,让该函数能够使用命名空间 std 中的所有元素。 - 在特定的函数中使用类似
using std::cout;
这样的编译指令,让该函数能够使用指定的元素。 - 完全不使用编译指令
using
,而在需要使用命名空间 std 中的元素时,使用前缀std::
,如:
std::cout << "I'm using cout and endl from the std namespace" << std::endl;
注意: using 一次性注入某个命名空间的所有名字,这种用法看似简单实则充满了风险:只使用一条语句就突然将命名空间中所有成员的名字变得可见了。如果应用程序使用了多个不同的库,而这些库中的名字通过using指示变得可见,则全局命名空间污染的问题将重新出现。