文章目录
- 🚩前言
-
- [1. 宏定义](#1. 宏定义)
-
- [1.1 无参宏定义](#1.1 无参宏定义)
- [1.2 有参的宏定义](#1.2 有参的宏定义)
- [1.3 带参宏定义和带参函数的对比](#1.3 带参宏定义和带参函数的对比)
- [1.4 取消宏定义](#1.4 取消宏定义)
- [2. 条件编译](#2. 条件编译)
- 3. #pragma
🚩前言
在C语言中,除了之前的各种语句,还包括一种特殊语句------预处理语句。它不是实现程序的功能,而是给C语言编译系统提供信息。C语言提供的预处理语句主要包括宏定义、文件包含、条件编译等。
1. 宏定义
宏定义的作用就是用一个标识符表示一个需要用到的字符等。其可以分为带参和不带参的宏定义。一般根据程序需要来写宏定义。
1.1 无参宏定义
定义格式:[注意:没有分号]
c
#define <标识符> <字符串......>
//比如:
#define PI 3.1415926
#define
用于定义宏的。
标识符
:定义的宏的名字。
字符串
:是指宏体,可以是常量、表达式等。一般宏定义在源程序的开头、函数定义的外面,有效范围是从宏定义语句开始到源文件结束。
1.2 有参的宏定义
上述无参宏定义只能完成简单的替换数值操作,为了更加灵活,我们可以给宏定义带上参数。
定义格式:
c
#define 标识符(参数1,参数2,......) 字符串
例:计算圆的周长,用带参宏定义
c
//1、带参宏定义
#include<stdio.h>
#define PI 3.1415926//无参宏定义
#define COMP_CIR(x) 2*PI*x//有参宏定义
int main()
{
double r=1.0;
printf("圆的周长:2*PI*r=%f\n",COMP_CIR(r));
return 0;
}
结果展示:
1.3 带参宏定义和带参函数的对比
基本操作 | 带参宏定义 | 带参函数 |
---|---|---|
处理时间 | 预处理 | 编译+运行 |
参数类型 | 无类型 | 根据需要定义类型 |
参数传递 | 不分配内存,无传递 | 分配内存,实参带入形参 |
运行速度 | 快 | 相对较慢,因为函数的调用需要内存分配、参数传递、压栈、出栈等操作 |
因此,带参宏定义较为灵活,它在程序预处理时就执行了。相比于函数,宏定义更好些。但是需要注意参数替换问题:
比如下面代码:
c
//2、带参宏定义的替换问题
#include<stdio.h>
#define ABS(x) (x)>=0?(x):-(x)//求绝对值问题
double compAbs(double num)
{
return num>=0?num:-num;
}
int main()
{
double x=12,y=12;
printf("ABS(++x)=%f\n",ABS(++x));//(++x)>=0?(++x):-(++X)
printf("compAbs(++y)=%f\n",compAbs(++y));//13>=0?13:-13
return 0;
}
结果展示:
1.4 取消宏定义
#undef
指令就是取消宏定义的。比如:
c
//3、取消宏定义
#include<stdio.h>
#define PI 3.14
int main()
{
printf("%f\n",PI);
#undef PI//取消后
printf("%f\n",PI);//再次引用
return 0;
}
结果展示:
2. 条件编译
条件编译:就是说,有些程序需要在一定条件下才编译的。详解如下:
2.1 #if......#else...#endif
#if......#else...#endif
该指令是根据常数表达式决定某段代码是否需要编译。格式如下:
c
#if 常数表达式
程序段1;
#else
程序段2;
#endif
上面就是,编译器只会编译代码块1和2,若常数表达式条件成立,编译器会编译代码块1,否则编译代码块2;
实例如下:
c
//4、条件编译#if......#else...#endif
#include<stdio.h>
//宏定义
#define WIN32 0
#define x64 1
#define SYSTEM WIN32//通过改变这里进行条件编译
int main()
{
//通过判断SYSTEM的值,输出程序支持的平台
#if SYSTEM==WIN32
printf("win32\n");
#else
printf("x64");
#endif
return 0;
}
结果展示:
2.2 #ifdef
在程序中,若想判断某个宏是否被定义,可以使用这个指令
#ifdef
,通常和#endif
一起用。格式如下:
c
#ifdef <宏名>
程序段1;
#else
程序段2;
#endif
代码演示:
c
//5、#ifdef
#include<stdio.h>
#define DEBUG
int main()
{
int i=5;
#ifdef DEBUG
printf("i=%d\n",i);
#endif
int j=10;
#ifdef DEBUG
printf("j=%d\n",j);
#endif
int sum=i+j;
#ifdef DEBUG
printf("i+j=%d\n",sum);
#endif
return 0;
}
结果展示:只有当
DEBUG
被定义了才会有输出的
2.3 #ifndef
#ifndef
作用是:用来确定某一个宏是否未被定义,它和#ifdef
意思相反。若宏没被定义才编译ifndef
指令下的内容,否则就跳过。格式:
c
#ifndef <宏名>
程序段1;
#else
程序段2;
#endif
代码演示:
c
//6、#ifndef
#include<stdio.h>
#define DEBUG
int main()
{
#ifndef DEBUG
printf("输出信息:\n");
#else
printf("无信息\n");
#endif
return 0;
}
结果展示:
3. #pragma
#pragma
预处理的作用是:设置编译器的状态或者指示编译器完成特殊的功能。格式:
c
#pragma parameter
parameter
表示:编译器特有的字段,常用的用法有下面几种:
格式 | 作用 |
---|---|
#pragma warning |
对编译器的警告处理 |
#pragma message |
用于让编译器在编译过程中输出相应的信息 |
#pragma comment |
通常用于连接库文件 |