C语言进阶(9)

程序的执行时有两种环境,一种是翻译环境,另一种是执行环境。程序先经过编译成为obj的后缀的文件,然后将文件和链接库链接起来,然后将形成可执行程序,前者时翻译环境,后者时执行环境。(链接库就是库函数的所在和一些其他的)

1.翻译环境

翻译分为编译和链接,编译又分为预编译,编译和汇编;链接又分为合并段表和合并符号表和重定位。

预编译就是将一些引用的头文件转换和,#definde定义的进行替换,注释的删除等,就可以得到预编译的程序文件(后缀时.i)

编译就是将预编译的文件由C语言代码转变为汇编代码,编译器要进行语法分析,词法分析,符号汇总,语义分析的操作,得到后缀为.s的编译文件。其中语法分析就是将整个程序中函数,全局变量等进行汇总。

汇编就是将汇编代码转变成二进制指令和形成符号表,把汇编文件转变成以obj结尾的目标文件。这个符号表就是将每一个obj目标文件就是将符号汇总中进行匹配地址,就可以得到符号表。(如果没有函数体只是函数声明,就匹配一个无效地址)

链接的合并段表就是将不同文件(obj文件是linux elf文件的格式,内容是一段一段的)每一段进行合并。

链接的符号表的合并和重定位,就是将不同文件中的符号表进行合并,相同的符号,删除无效地址的符号,得到全新的符号表。重新根据符号的地址定位,最终得到可执行程序。

2.执行环境

执行环境的具体过程是

(1)将文件载入内存中;

(2)调用main函数

(3)执行程序代码和函数堆栈,存储函数的局部变量和返回地址;

(4)终止程序(有可能是意外终止和正常终止)

下面介绍预处理的详解

3.预处理符号

在编译器中自带一些符号,他们可以显示编译的一系列信息,相当于存储这些信息的变量:

FILE //进行编译的源文件

LINE //文件当前的行号,就是显示当前代码所在编译器的行号

DATE //文件被编译的日期

TIME //文件被编译的时间

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

下面是使用示例

\是续行符,可以将代码延申到下一行。

4 .#define

(1)#define定义标识符

define可以定义常量,代码等,本质上是替换,将定义的替换成原来的,在进行汇编。

如下

(2)#define定义宏

宏就是一种类似函数形式,本质上是将宏参在文本中进行替换。然后将文本在主函数中进行替换后运算。

宏的声明方式是#define name( parament-list ) stuff,其中parament-list是宏参,是传给宏的参数,stuff是文本,然后就会进行文本宏参的替换和代码的替换。

下面是使用示例:

经过替换后可以写成

cs 复制代码
int main()
{
	printf("%d", ((2)+(3)));
	return 0;

}

经过完整的替换,文本是什么样就替换成什么样,这一点很重要!!!

我们为了防止出现出乎意料的结果,我们要每一个宏参加括号,整个文本加括号。

宏参可以出现其他#define定义的变量,但是不可以出现递归,字符串常量时不被检索。

宏和函数的对比:

函数

函数代码只出现于一个地方,每次使用这个函数时,都调用那个地方的同一份代码 存在函数的调用和返回的额外开销,所以相对慢一些

函数参数只在函数调用的时候求值一次,它的结果值传递给函 数。表达式的求值结果更容易预 测。

函数参数只在传参的时候求值一 次,结果更容易控制。

函数的参数是与类型有关的,如 果参数的类型不同,就需要不同的函数,即使他们执行的任务是 不同的。

函数是可以逐语句调试的

函数是可以递归的

#define定义宏

每次使用时,宏代码都会被插入到程序中。除了非常小的宏之外,程序的长度会大幅度增长

宏参数的求值是在所有周围表达式的上下文环境里, 除非加上括号,否则邻近操作符的优先级可能会产生 不可预料的后果,所以建议宏在书写的时候多些括号。

参数可能被替换到宏体中的多个位置,所以带有副作用的参数求值可能会产生不可预料的结果。

参 数 类 型 宏的参数与类型无关,只要对参数的操作是合法的, 它就可以使用于任何参数类型。

宏是不方便调试的

宏是不能递归的

(3)#和##

#是将非字符转变成字符

##是将两个符号合并成一个符号,这样的连接产生已申明的标识符,否则无效。

下面是使用示例

#和##只能在宏中使用。

(4)#undef

#undef就是将定义的宏进行删除,当我们需要重命名宏,发现重复时,就可以使用#undef来删除宏。

相关推荐
雨颜纸伞(hzs)2 分钟前
C语言介绍
c语言·开发语言·软件工程
J总裁的小芒果4 分钟前
THREE.js 入门(六) 纹理、uv坐标
开发语言·javascript·uv
坊钰33 分钟前
【Java 数据结构】移除链表元素
java·开发语言·数据结构·学习·链表
chenziang138 分钟前
leetcode hot100 LRU缓存
java·开发语言
时雨h1 小时前
RuoYi-ue前端分离版部署流程
java·开发语言·前端
云计算DevOps-韩老师1 小时前
【网络云计算】2024第52周-每日【2024/12/25】小测-理论&实操-自己构造场景,写5个系统管理的脚本-解析
开发语言·网络·云计算·bash·perl
暮色尽染1 小时前
Python 正则表达式
开发语言·python
IT猿手1 小时前
最新高性能多目标优化算法:多目标麋鹿优化算法(MOEHO)求解GLSMOP1-GLSMOP9及工程应用---盘式制动器设计,提供完整MATLAB代码
开发语言·算法·机器学习·matlab·强化学习
小爬虫程序猿1 小时前
利用Java爬虫获取速卖通(AliExpress)商品详情的详细指南
java·开发语言·爬虫
xlsw_1 小时前
java全栈day21--Web后端实战之利用Mybaits查询数据
java·开发语言