C语言程序的编译与预处理详解

 更新时间:2021年10月13日 08:32:39   作者:股神。  
这篇文章主要介绍了C语言程序的编译与预处理,包括介绍了C和C++混合编程的情况,需要的朋友可以参考下,希望能够给你带来帮助

一、程序的编译

我们写的源文件(*.c)是经过怎样的处理生产可执行文件(*.exe)的呢?这种处理有两个步骤—编译和链接。源文件在编译阶段通过编译器将每个源文件转换为目标文件(这些文件是可执行的机器指令),再通过链接器将其捆绑到一起,生成一个完整的可执行程序。

1、 编译阶段

编译阶段可细分为3个阶段:预处理(即预编译)、编译、汇编

预处理:主要进行头文件的包含、处理预处理指令(如:#define定义符号的替换)、删除注释。此时(*.c)文件转换为(*.i)文件。

编译:主要进行语法分析、词法分析、语义分析、符号汇总,此阶段会将c语言代码转换为汇编代码。此时(*.i)文件转换为(*.s)文件。

汇编:此阶段会形成符号表,将汇编代码转换为二进制指令(机器指令)。此时(*.s)文件转换为(*.o)文件。

2、链接

此阶段主要完成合并段表、符号表的合并和重定位工作,将(*.o)文件链接到一起生成可执行文件。

二、预处理详解

1、预定义符号

__FILE__      //进行编译的源文件
__LINE__     //文件当前的行号
__DATE__    //文件被编译的日期
__TIME__    //文件被编译的时间
__STDC__    //如果编译器遵循ANSI C,其值为1;如果不遵循,则编译器不认识这个符号,是个未定义标识符,此时使用这个符号程序会报错。该符号的作用是判断编译器是否遵循ANSI C。

下面为大家展示这些符号的作用。

执行结果为:

2、#define定义的标识符

语法:

#define MAX 100

这句代码的意思是数字“100”替换成符号MAX,例如:

#include <stdio.h>
#define MAX 100
int main()
{
	int i = 1 + MAX;
	printf("%d", i);
	return 0;
}

结果:

注意:define定义的标识符只进行替换,并不会在替换过程中执行运算,例如

#include <stdio.h>
#define MAX 5+5
int main()
{
	int i = 10;
	int x = i * MAX;
	printf("%d", x);
	return 0;
}

这个程序的结果是多少呢?100吗?答案其实是55,因为define只是简单的替换,i*MAX其实本质是i*5+5,即10*5+5=55.

3、#define定义的宏

语法:

#define SQUARE(x) x * x

当我们在程序中写下:SQUARE(5)这句代码,这预处理时,这句代码就会被替换成5*5。例如:

#include <stdio.h>
#define SQUARE(x) (x) * (x)
int main()
{
	int i = SQUARE(5);
	printf("%d", i);
	return 0;
}

程序结果为:

注意:同样的#define定义的宏也只是进行简单的替换。

例如:

#include <stdio.h>
#define SQUARE(x) x * x
int main()
{
	int a = 5;
	int i = SQUARE(a+1);
	printf("%d", i);
	return 0;
}

这个程序的结果是什么呢?答案是11,SQUARE(a+1)等同于SQUARE(5+1),即5+1*5+1=11,而不是6*6=36。

宏常常被用于执行简单的运算,比如在两个数中找出较大的一个。

#define MAX(a, b) ((a)>(b)?(a):(b))

那么为什么不用函数呢,因为宏有两个优势:

1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序 的规模和速度方面更胜一筹。

2. 更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏怎可 以适用于整形、长整型、浮点型等可以用于>来比较的类型。宏是类型无关的。

但宏也有劣势:

1. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。

2. 宏是没法调试的。

3. 宏由于类型无关,也就不够严谨

4. 宏可能会带来运算符优先级的问题,导致程容易出现错。(就是上面我提醒大家需要注意的地方)

4、#unef

这条指令用于移除一个#define定义标识符或宏定义。

例如:

#define	MAX 100
int main()
{
	int m = MAX;
#undef MAX
	int n = MAX;//err
	return 0;
}

这个程序会报错,因为那个int n=MAX中的MAX的定义被移除了,而其他的不会(m仍然是正确的)。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • opencv实现机器视觉检测和计数的方法

    opencv实现机器视觉检测和计数的方法

    在机器视觉中,有时需要对产品进行检测和计数。其难点无非是对于产品的图像分割。本文就来介绍一下机器视觉检测和计数的实现,感兴趣的可以参考一下
    2021-05-05
  • C语言中用于产生随机数的函数使用方法总结

    C语言中用于产生随机数的函数使用方法总结

    这篇文章主要介绍了C语言中用于产生随机数的函数使用方法总结,分别介绍了rand()函数和srand()函数以及封装出的arc4random()函数,需要的朋友可以参考下
    2016-05-05
  • C/C++如何实现循环左移,循环右移

    C/C++如何实现循环左移,循环右移

    这篇文章主要介绍了C/C++如何实现循环左移,循环右移,具有很好的参考价值,希望对大家有所帮助。具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • C语言 经典题目螺旋矩阵 实例详解

    C语言 经典题目螺旋矩阵 实例详解

    这篇文章主要介绍了C语言 经典题目螺旋矩阵 实例详解的相关资料,这里附有代码实例及实现效果图,需要的朋友可以参考下
    2016-12-12
  • 将正小数转化为2-9进制小数的实现方法

    将正小数转化为2-9进制小数的实现方法

    本篇文章对正小数转化为2-9进制小数的实现方法进行了介绍,需要的朋友参考下
    2013-05-05
  • 基于Matlab实现俄罗斯方块游戏

    基于Matlab实现俄罗斯方块游戏

    俄罗斯方块是一个最初由阿列克谢帕吉特诺夫在苏联设计和编程的益智类视频游戏。本文将利用Matlab实现这一经典的小游戏,需要的可以参考一下
    2022-03-03
  • C语言利用EasyX绘制小企鹅表情包

    C语言利用EasyX绘制小企鹅表情包

    这篇文章主要为大家详细介绍了C语言如何利用EasyX绘图库实现绘制可爱的小企鹅表情包,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2022-12-12
  • C语言scandir函数获取文件夹内容的实现

    C语言scandir函数获取文件夹内容的实现

    scandir 函数用于列举指定目录下的文件列表,本文主要介绍了C语言scandir函数获取文件夹内容的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • C++实现LeetCode(87.搅乱字符串)

    C++实现LeetCode(87.搅乱字符串)

    这篇文章主要介绍了C++实现LeetCode(87.搅乱字符串),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07
  • 详解C++11 线程休眠函数

    详解C++11 线程休眠函数

    这篇文章主要介绍了C++11 线程休眠函数的相关资料,帮助大家更好的理解和学习C++11,感兴趣的朋友可以了解下
    2020-10-10

最新评论