IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 程序的编译与预处理详解 -> 正文阅读

[C++知识库]程序的编译与预处理详解

目录

一、程序的编译

1、 编译阶段

2、链接

二、预处理详解

1、预定义符号

2、#define定义的标识符

3、#define定义的宏

?4、#undef


一、程序的编译

我们写的源文件(*.c)是经过怎样的处理生产可执行文件(*.exe)的呢?这种处理有两个步骤—编译链接。源文件在编译阶段通过编译器将每个源文件转换为目标文件(这些文件是可执行的机器指令),再通过链接器将其捆绑到一起,生成一个完整的可执行程序

1、 编译阶段

编译阶段可细分为3个阶段:预处理(即预编译)、编译、汇编

预处理:主要进行头文件的包含、处理预处理指令(如:#define定义符号的替换)、删除注释。此时(*.c)文件转换为(*.i)文件。

编译:主要进行语法分析、词法分析、语义分析、符号汇总,此阶段会将c语言代码转换为汇编代码。此时(*.i)文件转换为(*.s)文件。

汇编:此阶段会形成符号表,将汇编代码转换为二进制指令(机器指令)。此时(*.s)文件转换为(*.o)文件。

2、链接

此阶段主要完成合并段表、符号表的合并和重定位工作,将(*.o)文件链接到一起生成可执行文件。

二、预处理详解

1、预定义符号

__FILE__      //进行编译的源文件
__LINE__     //文件当前的行号
__DATE__    //文件被编译的日期
__TIME__    //文件被编译的时间
__STDC__    //如果编译器遵循ANSI C,其值为1;如果不遵循,则编译器不认识这个符号,是个未定义标识符,此时使用这个符号程序会报错。该符号的作用是判断编译器是否遵循ANSI C。

下面为大家展示这些符号的作用。

执行结果为:

2、#define定义的标识符

语法:

#define MAX 100

?这句代码的意思是数字“100”替换成符号MAX,例如:

#include <stdio.h>
#define MAX 100

int main()
{
	int i = 1 + MAX;
	printf("%d", i);

	return 0;
}

结果:

?注意:define定义的标识符只进行替换,并不会在替换过程中执行运算,例如

#include <stdio.h>
#define MAX 5+5

int main()
{
	int i = 10;
	int x = i * MAX;
	printf("%d", x);

	return 0;
}

?这个程序的结果是多少呢?100吗?答案其实是55,因为define只是简单的替换,i*MAX其实本质是i*5+5,即10*5+5=55.

3、#define定义的宏

语法:

#define SQUARE(x) x * x

当我们在程序中写下:SQUARE(5)这句代码,这预处理时,这句代码就会被替换成5*5。例如:

#include <stdio.h>
#define SQUARE(x) (x) * (x)

int main()
{
	int i = SQUARE(5);
	
	printf("%d", i);

	return 0;
}

程序结果为:

注意:同样的#define定义的宏也只是进行简单的替换。

例如:

#include <stdio.h>
#define SQUARE(x) x * x

int main()
{
	int a = 5;
	int i = SQUARE(a+1);
	
	printf("%d", i);

	return 0;
}

这个程序的结果是什么呢?答案是11,SQUARE(a+1)等同于SQUARE(5+1),即5+1*5+1=11,而不是6*6=36。


宏常常被用于执行简单的运算,比如在两个数中找出较大的一个。

#define MAX(a, b) ((a)>(b)?(a):(b))

?那么为什么不用函数呢,因为宏有两个优势:

1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序 的规模和速度方面更胜一筹。

2. 更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏怎可 以适用于整形、长整型、浮点型等可以用于>来比较的类型。宏是类型无关的。

?但宏也有劣势:

1. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。

2. 宏是没法调试的。

3. 宏由于类型无关,也就不够严谨

4. 宏可能会带来运算符优先级的问题,导致程容易出现错。(就是上面我提醒大家需要注意的地方)

?4、#undef

这条指令用于移除一个#define定义标识符或宏定义。

例如:

#define	MAX 100

int main()
{
	int m = MAX;
#undef MAX
	int n = MAX;//err

	return 0;
}

这个程序会报错,因为那个int n=MAX中的MAX的定义被移除了,而其他的不会(m仍然是正确的)。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-13 11:17:51  更:2021-10-13 11:18:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/14 14:37:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码