C进阶:预处理(上)

简介: C进阶:预处理

一.代码运行是的两种环境

1.翻译环境,在这个环境中源代码被转换为可执行的机器指令。

2.执行环境,它用于实际执行代码

下面主要讲解翻译环境。

二.翻译环境

从.c 文件到 .exe 文件需要经过编译器的翻译,而翻译又分为 编译和链接两个部分

编译又分为三个部分:

1.预编译:又叫预处理,在这个部分主要完成头文件的包含,#define的替换,注释的删除;

2.编译:主要完成语法分析,词法分析,词义分析,符号汇总(符号包括全局性的变量和函数),生成汇编代码;

3.汇编:生成二进制指令,形成符号表(符号表是由符号和其地址组成的);

链接:合并段表,合并符号表(在这个阶段会发现未定义的函数)

见下图:

三.预定义符号

__FILE__    //进行编译的源文件

__LINE__   //文件当前的行号

__DATE__   //文件被编译的日期

__TIME__   //文件被编译的时间

__STDC__   //如果编译器遵循ANSI C,其值为1,否则未定义

四.#define

1.define  定义宏

宏的申明方式:

#define name( parament-list ) stuff

其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中。

注意 name 需与后面的括号紧密相连,不可以有空格,如果有任何空白存在,参数列表就会被解释为stuff的一部分。

注意当我们定义宏的时候,不要吝啬括号!

来看下面一个例子:

1. #define MOD(x,y) x*y
2. 
3. int main()
4. {
5.  int m = MOD(2+3,2);
6.  printf("%d\n", m);
7.  return 0;
8. }

对初学者来说,这段代码的答案很容易被认为式10,但事实并非如此,因为宏是在预处理阶段先替换掉,然后在进行计算,所以在没有括号的情况下,替换后是这样的:2+3*2=8;所以若是想要得到10这个结果,就要加上括号,即:

#define MOD(x,y) ((x)*(y))

2.带有副作用的宏参数

我们知像是前置++ ,后置++这种的运算符是会改变操作数的值属性的,那它如果应用到#define 定义的宏中会是怎么样呢?

我们来看下面这个例子:

1. #define MAX(x,y) ((x)>(y)?(x):(y))
2. 
3. int main()
4. {
5.  int a = 4;
6.  int b = 6;
7.  int m = MAX(a++, b++);
8.  printf("m=%d\n", m);
9.  printf("a=%d b=%d\n", a, b);
10.   return 0;
11. }

最后的答案会是多少呢?

首先完成宏参数的替换:((a++)>(b++)?(a++):(b++))

后置++是先使用后++,因为4<6,所以执行后面的 b++,经过前面的++,此时a=5,b=7,所以先把7赋给m,然后b++,得到b=8;

m=7  a=5  b=8

总结:

1.#define 定义的符号需要先原封不动的替换掉,所以建议在#define 后面不加 ' ; ' ;

2.#define 定义的宏不要吝啬括号,以免出现出乎意料的结果;

3.避免使用带有副作用的运算符。

五.#define定义宏 与函数对比

六.预处理指令

所有的预处理指令都是以井号(#)开头。它必须是第一个非空字符,为了增强可读性,预处理指令应从第一列开始。下面列出了所有重要的预处理指令:

目录
相关文章
|
存储 自然语言处理 API
|
机器学习/深度学习 人工智能 运维
《人工智能赋能网络拓扑分析:洞察关键节点与脆弱链路》
在数字化时代,网络作为现代社会的神经中枢,其关键节点与脆弱链路对性能和稳定性至关重要。传统方法在识别这些要素时面临局限,而人工智能技术(如机器学习、深度学习和强化学习)提供了新解决方案。通过分析网络拓扑数据,AI能精准识别关键节点与脆弱链路,优化资源配置并提升网络可靠性。实践案例表明,AI已显著改善互联网公司和智能交通网络的运维效率。未来,随着算法优化和技术融合,AI将在复杂网络中发挥更大作用,推动社会信息化迈向新高度。
337 2
|
缓存 前端开发 JavaScript
优化CSS和JavaScript加载
优化CSS和JavaScript加载
308 1
|
Java Unix 程序员
一文彻底搞定C语言的前世今生
C语言是计算机编程史上的一颗璀璨恒星,由贝尔实验室的肯·汤普逊和丹尼斯·里奇在20世纪70年代基于B语言开发。它凭借高效、灵活、可移植性强等特点迅速崛起,成为Unix操作系统的核心语言,并广泛应用于操作系统、嵌入式系统、游戏引擎等领域。C语言不仅推动了众多后续编程语言的发展,如C++、Java等,还通过多次标准化(C89、C99、C11等)不断适应新时代的需求,至今仍占据着计算机技术的重要地位。
422 0
|
数据采集 机器学习/深度学习 数据可视化
过采样与欠采样技术原理图解:基于二维数据的常见方法效果对比
本文介绍了处理不平衡数据集的过采样和欠采样技术,包括随机过采样、SMOTE、ADASYN、随机欠采样、Tomek Links、Near Miss 和 ENN 等方法。通过二维数据集的可视化示例,直观展示了各种方法的原理和效果差异。文章还讨论了混合采样方法(如SMOTETomek和SMOTEENN)以及应用这些方法的潜在风险,强调了在实际应用中审慎选择的重要性。
1088 3
|
安全 中间件 关系型数据库
如何选择国产化CMS来建设政务网站?
信创国产化网站建站保障信息安全,推动信息技术产业发展。PageAdminCMS支持信创,功能全面,满足新建或升级网站需求,助力单位信创国产化转型。
403 5
|
XML Java Android开发
Android Studio App开发之实现底部标签栏BottomNavigationView和自定义标签按钮实战(附源码 超详细必看)
Android Studio App开发之实现底部标签栏BottomNavigationView和自定义标签按钮实战(附源码 超详细必看)
1562 0
|
运维 机器人 开发者
使用阿里云百炼通过appflow模板,组合钉钉机器人搭建个人知识库评测与感想
尝试构建个人助手机制,用阿里云百炼+AppFlow+钉钉机器人,花费两午休时间解决配置问题。百炼appid复制时多出空格致错,文档未提及,耗时排查。应用创建时模型选项限于max, plus, turbo,性价比高的qwen-long未上线。期望尽快修复bug和上线新模型以降低成本。附故障排查截图。
861 1
|
测试技术 开发工具 Android开发
Python+Appium自动化测试(3)-编写自动化脚本
之前一篇博客已经讲述怎样手动使用appium-desktop启动测试机上的app,但我们实际跑自动化脚本的过程中,是需要用脚本调用appium启动app的,接下来就尝试写Python脚本启动app并登陆app。环境为Windows10 + Python3.7 + appium1.18.0 + Android手机 + 今日头条app + Pycharm
Python+Appium自动化测试(3)-编写自动化脚本