超详细的C进阶教程!C语言预处理

Posted 东条希尔薇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了超详细的C进阶教程!C语言预处理相关的知识,希望对你有一定的参考价值。

作者的码云地址:https://gitee.com/dongtiao-xiewei
后续作者会更新力扣的每日一题系列,原代码会全部上传码云,推荐关注哦,笔芯~

还像更深入地了解c语言?快来订阅作者的c语言进阶专栏!作者承诺本系列不会TJ!预计更新:指针,字符串处理,内存管理,结构体,预处理等等

感谢朋友们的支持,我们这个系列今天终于完结啦!

我们一直以来写的代码,本质其实都是以.c文件为后缀名的文本文件,例如我们随便以记事本形式点来一个.c后缀的文件


点开我们看到,就是我们熟悉的代码样式

但这就有一个问题,这种文本文件是如何被计算机识别的呢?

其实计算机能够识别的就只有机器语言,也就是一串二进制代码,早期的程序员也是全用机器语言编程,后面为了避免麻烦,简化编程的过程,就产生了较为容易理解汇编语言,而汇编过程就是将汇编语言转化为机器语言

而为了解决平台的可移植性和通用性的问题,又产生了高级语言,例如c语言,basic语言等,而编译过程,可把高级语言转化为汇编语言

所以,现代计算机可分为以下几个层次


我们的c代码若要生成一个可执行程序(二进制代码)需要进行以下几个步骤


今天的章节我们重点介绍预处理环节

预处理环节将会进行以下工作

  1. 处理define定义好的标识符,宏等
  2. 去掉注释

我们可以先测试一下去掉注释

int main()
{
	printf("hello world!\\n");//you can see me!
	return 0;
}

预处理后的结果:

注:由于VS编译器查看预处理后的代码比较困难,所以本章节的代码我们使用linux平台测试

本节用到的linux指令:
touch test.c创建一个源文件
vim test.c 编写代码
gcc -E test.c -o test.i 将预处理后的代码保存在test.i中

好,坐稳扶好,我们正式开始喽!

#define

#define定义标识符

通用格式:

#define name stuff

例子:

#define MAX 200
#define str struct

我们用这个定义标识符可以起到定义常量,重命名,同名替换等等

可以在linux上简单测试一下

#define MAX 200
#define reg register

int main()
{
	reg int a=MAX;
	printf("%d\\n",a);
	return 0;
}

而代码也能跑的过去

我们可以看到,预处理阶段就完成了简单替换

萌新最容易犯的错误:在定义完成后加上’’;’'

#define MAX 200;

虽然这个代码可能在有些情况不会出错,但替换下来就是这个结果


看起来很奇怪,是吧!

#define定义宏

这是define的一个特殊机制,允许把参数替换在文本中

例子

#define DOUBLE(x) (x+x)

通用格式

#define name(list) stuff

宏的使用

虽然是宏,但我们可以观察到,本质也是简单替换

我们同样也可以定义以下的宏

#define SQUARE(x) x*x

但是注意,这个宏存在一个问题,假如我们要算这个表达式的结果

SQUARE(5+1)

我们期望结果当然是6的平方,也就是36

但是我们测试发现结果并不是36


结果居然是11!

我们可以打开test.i文件查看一下预处理后的代码

我们可以发现,宏仅仅只是完成了简单替换,并没有考虑优先级的问题

这个其实就是根据替换后的算术优先级来计算结果

1*5=5+5+1=11

当然,为了避免算术优先级的问题,我们可以对代码做一点改进

#define SQUARE(x) ((x)*(x))

这样修改后,宏就会是相对独立的运算结果了

条件编译

在编译一个程序的时候我们如果要将一条语句(一组语句)编译或者放弃是很方便的。因为我们有条件编译指令。

有以下条件编译指令

#ifdef,#ifndef,#if等等

注意,条件编译的末尾一定要加上#endif!

#ifdef

只有你编译了某个宏,代码才会被执行
比如我们在要调试一个代码的场景

这里显示了打印字符,如果我们把它注释掉,就不会显示

ifndef

同样还是上面的代码,但是却与上面功能相反

没有定义,才执行下列的程序

应用场景:头文件防止被重复包含

#ifndef __TEST_H__
#define __TEST_H__
//代码

#endif

#if

与分支语句的if相同,例如

以上是关于超详细的C进阶教程!C语言预处理的主要内容,如果未能解决你的问题,请参考以下文章

超详细的c进阶教程!C语言数据存储剖析

超详细的C进阶教程!深度解剖C语言自定义类型

超详细的c进阶教程!手撕c指针

超详细的C进阶教程!动态内存管理

超详细的C进阶教程!字符串及内存函数的使用及其模拟实现

手把手教你c语言队列实现代码,通俗易懂超详细!