[C.C++] 超详细的C进阶教程!(七)C语言预处理

380 0
Honkers 2025-5-31 04:27:29 来自手机 | 显示全部楼层 |阅读模式

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

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

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

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


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

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

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

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

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


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


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

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

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

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

  1. int main()
  2. {
  3. printf("hello world!\n");//you can see me!
  4. return 0;
  5. }
复制代码

预处理后的结果:

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

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

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

#define

#define定义标识符

通用格式:

  1. #define name stuff
复制代码

例子:

  1. #define MAX 200
  2. #define str struct
复制代码

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

可以在linux上简单测试一下

  1. #define MAX 200
  2. #define reg register
  3. int main()
  4. {
  5. reg int a=MAX;
  6. printf("%d\n",a);
  7. return 0;
  8. }
复制代码

而代码也能跑的过去

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

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

  1. #define MAX 200;
复制代码

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


看起来很奇怪,是吧!

#define定义宏

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

例子

  1. #define DOUBLE(x) (x+x)
复制代码

通用格式

  1. #define name(list) stuff
复制代码

宏的使用

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

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

  1. #define SQUARE(x) x*x
复制代码

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

  1. SQUARE(5+1)
复制代码

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

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


结果居然是11!

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

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

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

1*5=5+5+1=11

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

  1. #define SQUARE(x) ((x)*(x))
复制代码

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

条件编译

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

有以下条件编译指令

#ifdef,#ifndef,#if等等

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

#ifdef

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

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

ifndef

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

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

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

  1. #ifndef __TEST_H__
  2. #define __TEST_H__
  3. //代码
  4. #endif
复制代码

#if

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Honkers

荣誉红客

关注
  • 4014
    主题
  • 36
    粉丝
  • 0
    关注
这家伙很懒,什么都没留下!

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行