目录
前言:c语言中的编译过程
任何c语言的实现中都有两个环境
test.c 编译器 test.exe 操作系统 结果
源代码 翻译 可执行程序 执行环境 结果
1.翻译环境 源代码转化为可执行的机器指令
2.执行环境 实际执行代码
这里主要介绍一下翻译环境:
编译阶段分为三个阶段:预编译(预处理) 编译 汇编
1.预编译 头文件的包含#include预处理指令#define执行查找替换,#if可以区分是否编译,#undef可以反定义,也就是取消#define宏定义的东西
#define也是在阶段完成 预处理指令。
注释也是在这里删掉
2.编译 会产生.s的文件 即汇编代码 将c语言代码翻译成了汇编代码
过程难 语法词法语义分析,符号汇总
具体说一下符号汇总:
汇总全局的 比如外部声明的函数名 main等 函数名
3.汇编
产生(windows环境下).obj linux下是.o文件。
将汇编指令翻译成了二进制指令。
然后将所有.o(.obj)链接起来生成.exe文件 1.合并段表 2.符号表的合并和重定位
正片开始:
一、#define
1.符号
#define 修饰的符号在预处理中会被替换,所以它的作用相当于替换的意思,比如:
#define PE 3
#define ER "mihoyo"
int main()
{
int a = PE;
char c[] = ER;
printf("%s\n", c);
return 0;
}
编译的时候相当于替换了,然后运行结果自然而然也就出来了。
2.宏
应该是具备一定的功能,类似于函数:
比如:
//定义一个宏来求两个数的最大值
#define MAX(x, y) ((x) > (y)? (x) : (y))
int main()
{
int a = 1, b = 2;
printf("%d\n", MAX(a, b));
printf("%d\n", (a) > (b) ? (a) : (b));
return 0;
}
3.#
当我们想用宏表示时同时将这个变量名显示出来的时候怎么办呢?
//宏中#的用法:
void print(int n)
{
printf("the value of n is %d\n", n);
}//用宏实现上面的做法
#define PRINT(N) printf("the value of "#N" is %d\n", N)
int main()
{
int a = 10;
print(a);
printf("the value of ""a"" is %d\n", a);
PRINT(a);
return 0;
}
就会得到上面的结果;
4.##
##可以把位于它两边的符号合成一个符号。它允许宏定义从分离的文本片段创建标识符。
但是必须时创建过的:
#define CAT(name, num) name##num
int main()
{
int nihao = 13;
printf("%d\n", CAT(ni, hao));//##可以把位于它两边的符号合成一个符号。它允许宏定义从分离的文本片段创建标识符。return 0;
}
5.#undef
当我们用#define定义了一个符号或者宏,想取消其定义的话就可以使用这个用来取消定义即可。需要注意的是,和上一个定义其符号的#define组成域(作用范围,不受其他影响)。
#define PR 12
int main()
{
int a = PR;
#undef PR
int b = PR;
return 0;
}
二、条件编译
所谓条件编译,就是看你这段代码是否编译,即在不屏蔽或者删除的情况下,为了不舍弃代码而做出的一种调整。
下面是常见的条件编译:
(注意到每一个if后面必须跟着一个endif这个是常规的if else没有的)
如下代码:
#define MAX 0
int main()
{
//defined表示定义 !defined表示没有定义
//#if defined(MAX)
// printf("hehe\n");
//#endif
//
//#if !defined(MAX)
// printf("cici\n");
//#endif// #ifdef表示定义 #ifndef表示未定义
#ifdef MAX
printf("cici\n");
#endif#ifndef MAX
printf("hehe\n");
#endifreturn 0;
}
一定要努力哦!