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仍然是正确的)。

总结

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

相关文章

  • C语言实现linux网卡连接检测的方法

    C语言实现linux网卡连接检测的方法

    这篇文章主要为大家详细介绍了C语言实现linux网卡连接检测的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-06-06
  • C++入门基础之命名空间、输入输出和缺省参数

    C++入门基础之命名空间、输入输出和缺省参数

    C++入门基础篇的内容为C++的基本特性,只有在掌握C++的基本特性后,是进入后面类和对象学习的基础,下面这篇文章主要给大家介绍了关于C++入门基础之命名空间、输入输出和缺省参数的相关资料,需要的朋友可以参考下
    2023-01-01
  • C++之std::vector删除元素的几种方式及区别说明

    C++之std::vector删除元素的几种方式及区别说明

    这篇文章主要介绍了C++之std::vector删除元素的几种方式及区别说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • 详细分析C++ 多态和虚函数

    详细分析C++ 多态和虚函数

    这篇文章主要介绍了C++ 多态和虚函数的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • C++修炼之拷贝构造函数

    C++修炼之拷贝构造函数

    这篇文章主要内容是6个默认成员函数之一的拷贝构造函数的认识与学习,让同学们充分理解浅拷贝与深拷贝,感兴趣的小伙伴可以参考阅读
    2023-04-04
  • C语言十进制转二进制代码实例

    C语言十进制转二进制代码实例

    这篇文章主要介绍了C语言十进制转二进制代码实例,并且转换后会统计二进制1的个数,实例简单明了,需要的朋友可以参考下
    2014-06-06
  • C++基础之this指针与另一种“多态”

    C++基础之this指针与另一种“多态”

    this指针识别了同一个类的不同的对象,换句话说,this指针使得成员函数可以访问同一个类的不同对象。再深入一点,this指针使得成员函数会因为this指针的不同而访问到了不同的成员变量
    2013-07-07
  • 基于C++实现的线程休眠代码

    基于C++实现的线程休眠代码

    这篇文章主要介绍了基于C++实现的线程休眠代码,包括了Linux平台及基于boost库的两种实现方法,有不错的参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • 利用c语言实现卷积码编码器示例

    利用c语言实现卷积码编码器示例

    这篇文章主要介绍了利用c语言实现卷积码编码器示例,需要的朋友可以参考下
    2014-03-03
  • C++最优二叉树哈夫曼树算法解析

    C++最优二叉树哈夫曼树算法解析

    这篇文章主要介绍了C++最优二叉树哈夫曼树算法解析,哈夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树,所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度,需要的朋友可以参考下
    2023-08-08

最新评论