文章目录
前言
本文主要介绍预处理指令 #define ,以及C语言程序的编译和链接。
一、什么是编译程序?
1.编译程序
编译程序(compiler)是一种程序。它把用高级语言写的源程序作为数据接收,经过翻译转换,产生面向机器的代码作为输出。
此过程中代码可能还要由汇编程序作进一步加工,得出目标程序,交给计算机执行。
即:
2.翻译程序
翻译程序( Translator)是一种程序,其输入是某种语言的一系列语句,而其输出则是另一种语言的一系列语句。
即:
3.编译、翻译的比较
两者之间的比较如下图所示:
4.解释程序
解释程序( lnterpreter ) ——将高级程序设计语言写的源程序作为输入,边解释边执行源程序本身,而不产生目标程序的翻译程序。
二、编译过程的概述
1.编译过程的组成
整个过程如下图所示:
2.各个部分解释
(1)词法分析
词法分析是将源程序字符串转化为一个个单词符号。
整个流程为:输入源程序,扫描﹑分解字符串,识别出一个个单词(定义符﹑标识符﹑运算符﹑界符、常数)
(2)语法分析
在词法分析基础上,将单词符号串转化为语法单位(语法范畴)(短语、子句、句子、程序段、程序),并确定整个输入串是否构成语法上正确的程序。
(3)语法分析
通过对程序结构的分析,判断其符合那种语法(如:循环结构——for循环、whlie循环)
(4)语义分析与中间代码生成
对语法分析所识别出的各类语法范畴,分析其含义,并进行初步翻译(产生中间代码)
(5)代码优化
对于代码(主要是中间代码)进行加工变换,以期能够产生更为高效(省时间和空间)的目标代码。
经过以上步骤最终生成目标代码。
三、预处理指令 #define
1.预定义符号
__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
2.#define
(1) #define 定义标识符
语法:#define name stuff
例:
#define MAX 1000
#define reg register //为 register这个关键字,创建一个简短的名字
#define do_forever for(;;) //用更形象的符号来替换一种实现
#define CASE break;case //在写case语句的时候自动把 break写上。
// 定义过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \
date:%s\ttime:%s\n" ,\
__FILE__,__LINE__ , \
__DATE__,__TIME__ )
(2) #define 定义宏
#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏或定义宏。
例:
#include<stdio.h>
#define SQUARE(x) (x) * (x)
int main()
{
int a = 5;
printf("%d\n", SQUARE(a + 1));
return 0;
}
结果:
(3) #define 替换规则
a. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。
b.替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值替换。
c.最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。
注意事项:
a.宏参数和#define 定义中可以出现其他#define定义的变量。但是对于宏,不能出现递归。
b.当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
3.宏和函数对比
宏和函数的对比如下:
总结
以上就是本文的全部内容。