预处理

本文深入探讨C语言预处理过程,解析#include指令中不同符号的意义,对比宏定义与函数、const、typedef的区别,以及条件编译的应用。通过具体示例,帮助读者理解宏定义的常见用途和潜在陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

预处理


1 预处理

在编译之前进行的处理,处理以 # 开头的指令,包括拷贝#include包含的文件代码,替换#define定义的宏,条件编译#if。

2 文件包含

2.1 #include指令中 < > 和 “ ” 的区別

对于 #include <filename.h>,编译器先从标准库路径开始搜索 filename.h,

对于 #include “filename.h”,编译器先从用户的工作路径开始搜索 filename.h,

2.2 头文件的作用
  • 通过头文件来调用库函数。

  • 头文件能加强类型安全检查。

3 宏定义

3.1 宏和函数的区别
  • 宏替换只作替换,不做计算,不做表达式求解;而函数调用需要。
  • 宏替换在编译前进行,不分配内存;函数调用在编译后程序运行时进行,且分配内存。
  • 宏定义不存在类型问题,没有类型转换;而函数有。
  • 宏展开会使源程序变长,而函数调用 不会。
  • 宏展开不占运行事件,只占编译时间;函数调用占运行时间。
3.2 #define的缺陷

宏定义在预处理阶段进行,主要做的是字符替换工作。

  • 无法进行类型检查。
  • 由于优先级的不同,使用宏定义时,可能会存在副作用。
  • 无法单步调试。
  • 会导致代码膨胀,由于宏定义是文本替换,需要对代码进行展开,相比较函数调用的方式,会存在较多的冗余代码。
3.3 typedef和define的区别

typedef与define都是替一个对象取一个别名,以此来增强程序的可读性。

原理不同:#define是预处理指令,只进行字符串替换,不作类型检查;typedef是关键字,在编译时处理,有类型检查的功能。

功能不同:#define不仅可以为类型取别名,还可以定义常量、变量、编译开关等;typedef用来定义类型的别名,包括内部类型和用户自定义类型。

作用域不同:#define没有作用域限制;typedef有自己的作用域。

void fun(){
    #define A int
    typedef int B;
}
int main()
{
    A a = 5;  //正确,可以使用A,因为宏替换没有作用域
    B b = 0;  //错误,不能使用B,但一般不在函数内定义typedef
}

对指针操作不同:两者修饰指针类型时,作用不同。

#define IPTR1 int*
typedef int* IPTR2;
int main()
{
    INTPTR1 pl,p2;  //字符串替换后为int* p1,p2;声明了一个指针变量p1和整型变量p2
    INTPTR2 p3,p4;	//p3、p4都为指针变量
}
3.4 #define和const的区别

define既可以替代常数值,又可以替代表达式,甚至是代码段,但是容易出错,而const的引入可以增强程序的可读性,它使程序的维护与调试变得更加方便。

  • define只是用来进行单纯的文本替换,不分配内存空间,它存在于程序的代码段;const常量存在于程序的数据段,并在堆栈中分配了空间,并且可以被调用、传递。
  • define常量没有数据类型;const常量有数据类型,编译器可以对const常量进行类型检查。
3.5 使用#define声明1年中有多少秒(忽略闰年问题)

#define SECOND_PER_YEAR (365*24*60*60)UL

考虑可能存在数据溢出问题,使用长整型。

3.6 宏定义返回两数中的最大值

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

3.7 判断一个数是无符号数还是有符号数

对于值而言,若这个数及其求反后的值都大于0,则该数为无符号数,反之为有符号数。

#define ISUNSIGNED(a) (a>=0 && ~a>=0)

3.8 解释作用

#define TRACE(S) (printf("%s\n",#S))

3.9 不使用第三个变量,交换两个变量的值

#define SWAP(a,b) a=a+b,b=a-b,a=a-b


4 条件编译

4.1 防止头文件被重复包含

使用条件编译

#ifndef __MY_HEAD_H__
#define __MY_HEAD_H__
...
#endif

4 条件编译

4.1 防止头文件被重复包含

使用条件编译

#ifndef __MY_HEAD_H__
#define __MY_HEAD_H__
...
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值