《C语言深度剖析》第三章 预处理详解 p1 C语言从入门到入土(进阶篇)

简介: 本章节文章是作者通过观看《C语言深度剖析》等各种资料总结的精华,基础部分省略了不少,是为了让大家能够更加深入了解C语言的魅力!因为为了避免与之前的文章发生赘述,所以就直接讲作者认为的精华部分哈!现在正文开始!

预处理


宏定义


3.1.1 数值宏常量

#define PI 3.1415926

作用:1.好改(用了多次,可维护性) 2.赋有意义


3.1.2 字符串宏常量

#include <stdio.h>

#include <windows.h>

/* 第一个宏,字符串没有带双引号,直接报错 */

//#define PATH1 C:\Users\whb\Desktop

/* 第二个宏,字符串带上双引用,有告警,能够编译通过。不过 windows 中路径分割符需要 \\, 输出乱码,改过之后,正常

*/

//#define PATH1 "C:\\Users\\whb\\Desktop

/* 第三个宏,不带双引号,进行 \ 续行 */

//#define PATH1 C:\\Users\\whb\\Desktop

/* 第四个宏,带双引号,进行 \ 续行 */

#define PATH1 "C:\\Users\\whb\\Desktop"



89.png90.png

结论:宏定义代表字符串的时候,一定要带上双引号,可以用\续行 。


3.1.3 用宏定义充当注释符号

// 程序翻译过程:

// 预处理 -E :头文件展开,去注释,宏替换

// 编译 -S : 将干净的 C 语言,编译成为汇编语言

// 汇编 -c :将汇编翻译成为目标二进制文件

// 链接 :将目标二进制文件与相关库链接,形成可执行程序



91.png92.png

结论:在预处理后,注释直接变为空格。


示例二:

93.png

结论:宏在预处理后直接替换掉为宏的定义。


示例三:

91.png


PS:这里是 .i  如果是 .c 就会再次进行预处理 。

94.png

结论:编译就是把原来的代码编译为汇编语言。


示例四:  


95.png96.png

其实是不可显示,本质上已经是二进制了。


97.png



3.1.4 预处理,编译,汇编,链接的总结

98.png


链接:自身程序+库文件进行关联(动,静态链接),形成可执行程序。

这里有一个小技巧,我们键盘左上角有一个Esc,这就刚好对应我们的前三步,预处理(E),编译(S),链接(c),只有链接是小写哈。


3.1.5 去注释和宏替换谁先谁后?


99.png100.png


结论:预处理期间,先执行去注释,在进行宏替换


3.1.6 define 宏定义表达式


例一:

101.png

其实是把sum(10)直接转化为了宏定义的式子,同时x=10,就变成了右边的样子。


例二:

102.png

PS:上面是加上 ; 不是 : 之前写错了。


103.png

例三:

104.png


这是错的哈!因为 if 和 else 是对不上的,原因就是if后面没有 { } 括起来。

105.png


这里相较于上面我们进行了 { } 的优化发现就对了。


但是:如果我们不准给if带{}呢?


来看看下面的代码:


106.png

这样我们就可以不用带 { } 了,并且后面可以跟 “ ; ” 。


结论:当我们需要宏进行多语句替换的时候, 推荐使用do-while-zero结构。当然,如若可以,宏方面的东西,推荐少用。


3.1.7 宏定义中的空格

[whb@VM-0-3-centos code]$ cat test.c
#include <stdio.h>
#define INC(a) ((a)++) //定义不能带空格
int main()
{
        int i = 0;
        INC (i); //使用可以带空格,但是严重不推荐
        printf("%d\n", i);
}

3.1.8 #undef


3.1.8.1 先探讨2个问题


1. 宏只能在main上面定义吗?

2. 在一个源文件内,宏的有效范围是什么?


问题一:


107.png108.png

结论:经过测试,宏,在哪都可以,习惯放在最上面。


问题二:


109.png

结论:宏的作用范围是从定义处开始,往后都是有效的。注意!程序是从上往下走的,是只要宏定义在上面,下面就能用是这个意思哈!


3.1.8.2 undef本质作用

120.png

结论:undef是取消宏的意思,可以用来限定宏的有效范围。



121.png122.png


是4哈!这个应该是好理解的,上面的定义3被取消了,是使用的下面的2。


3.1.8.3 注意!这个是可以使用的

123.png


今天的内容就到这里了哈!!!

要是认为作者有一点帮助你的话!

就来一个点赞加关注吧!!!当然订阅是更是求之不得!

最后的最后谢谢大家的观看!!!

你们的支持是作者写作的最大动力!!!

下期见哈!!!

相关文章
|
1月前
|
存储 安全 C语言
深度剖析c语言程序 -- 函数栈帧的创建和销毁(纯肝货)-2
深度剖析c语言程序 -- 函数栈帧的创建和销毁(纯肝货)-2
|
1月前
|
编译器 Linux PHP
C语言从入门到实战——预处理详解
C语言预处理是C语言编译过程的一个阶段,它在编译之前对源代码进行一系列的处理操作,包括宏替换、文件包含、条件编译等,最终生成经过预处理的代码,然后再进行编译。
46 0
|
1月前
|
存储 编译器 程序员
【程序环境和预处理】C语言
【程序环境和预处理】C语言
|
1月前
|
存储 小程序 C语言
【深度剖析数据在内存中的存储】C语言
【深度剖析数据在内存中的存储】C语言
|
1月前
|
存储 机器学习/深度学习 自然语言处理
【进阶C语言】编译与链接、预处理符号详解
【进阶C语言】编译与链接、预处理符号详解
25 0
|
1月前
|
存储 自然语言处理 编译器
【C语言进阶】程序环境和预处理
【C语言进阶】程序环境和预处理
|
1月前
|
存储 小程序 C语言
【C语言进阶】深度剖析数据在内存中的存储
【C语言进阶】深度剖析数据在内存中的存储
|
15天前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
26 0
|
26天前
|
编译器 C语言 C++
【C语言】memset()函数(内存块初始化函数)
【C语言】memset()函数(内存块初始化函数)
26 0
|
2天前
|
存储 C语言
C语言函数的返回值
C语言函数的返回值
7 0