当前位置:   article > 正文

c语言编译预处理指令大全,C语言预处理指令

c语言预处理指令单词

「今天是学习C语言第 32 天」

当你选择了一种语言,意味着你还选择了一组技术、一个社区。——Joshua Bloch

# 预处理

C语言源程序先经过预处理器进行预处理,之后经过编译器编译成二进制可执行代码执行。一般编译器套件、集成开发工具都将两种工具集成,预处理过程和编译过程一并处理。

C语言预处理是通过预处理指令实现,每个预处理指令以#符号开头,以行为单位,实现编译前的准备工作,例如文件条件引入、宏替换和条件编译。

# 预处理指令

C语言提供以下预处理指令,预处理指令必须以#开头,#符号必须是当前行的第一个非空白字符。预处理指令以一行作为处理单位,每行预处理指令是有多个预处理单词组成,单词之间使用空格或横向制表符分割。

预处理指令包括:

- #include:包含一个指定的源文件

- #define :定义一个宏

- #undef  :取消已定义的宏

- 条件编译:#if #ifdef #ifndef #elif #else #endif

- #line   :产生下一代码行号和源文件名称

- #error  :产生一个诊断错误信息

- #pragma :编译指示,预处理器实现自定义的编译动作

- #       :空指示,不起作用

# 文件包含

编译前引入特定的文件内容到当前的源代码文件中一起编译,主要用来引入头文件或其他源代码文件。三种形式:

第一种:

#include :一般从系统路径位置寻找引入的头文件。

第二种:

#include "文件名":一般是先在用户定义的路径寻找该文件,如果找不到再去系统路径寻找。

第三种:

#include 任意的预处理单词

该形式下的预处理单词也按照普通正文进行处理,处理完成以后,应和前两种之一匹配,再进行处理。

例如:

#include

#include "mystdio.h"

#define MYFILE "mystdio.h"

#include MYFILE

# 宏替换

宏(英文:Macro),根据一系列预定义的规则替换一定的文本模式,作用是将一个简单的小命令或动作转化为一系列指令,C语言中的宏的作用就是在宏出现的位置展开替换的文本。

语法:

#define  宏名  替换文本  :简单替换

#define  宏名(参数) 替换文本 :带参数的宏,类似函数调用

例如:

#define MAX_LEN 100

char str[MAX_LEN];

定义常量,使用宏定义字符数组最大长度,出现MAX_LEN全部替换成100,当需要修改数组长度时,只需要修改宏定义即可。

#define MAX_LEN 100

#undef MAX_LEN

char str2[MAX_LEN];

取消MAX_LEN宏定义,在#undef命令之后,就不能使用该宏,否则编译出错。

#define SUM(a, b) (a+b)

int s = SUM(1,2);

double d = SUM(100.01,200.01)

类似函数,使用宏定义计算参数a和b的和。

# 条件编译

根据条件例如不同硬件平台,选择不同的代码进行编译,方便程序移植和跨平台。

if条件有三种形式:

#if 常量表达式

#ifdef 宏名称

#ifndef 宏名称

根据if条件值,当值为0时,忽略和不编译后面代码文本。

注:#if后面必须是常量表达式,不能是函数调用和变量。

其中#if可包含以下条件:

#if defined 宏名称

#if defined (宏名称)

#ifdef 等价于 #if defined

#if ! defined 等价于 #ifndef

else条件三种形式:

#elif:#else和#if的结合,后面常量表达式

#else:与#if配合使用

#endif:结束#if或#else条件块

例如:

#ifndef MYHEADER_H

#define MYHEADER_H "myheader.h"

// 头文件内容

#endif

避免重复引入同一个文件多次,可以在被引入的头文件开头加入添加编译。

例如:不同硬件平台使用数字代替,x86=0,x64=1,arm=2。

#define X86 0

#define X64 1

#define ARM 2

#define ARCH 0

#if ARCH==0

#include "x86.h"

#elif ARCH==1

#include "x64.h"

#elif ARCH==2

#include "arm.h"

#else

#include "others.h"

#endif

或者:

#define DEBUG

#ifdef DEBUG

// 执行调试模式下的代码

#else

// 执行非调试模式下的代码

#endif

等价于:

#define DEBUG

#if defined DEBUG

// 执行调试模式下的代码

#else

// 执行非调试模式下的代码

#endif

# 行控制

预处理指令#line 用来控制编译器编译时警告和错误信息的行号和文件名。

两种形式:

1.#line  整数n

设置当前#line所在行的行号是整数n,后面的代码行均从此整数计数。

例如:

#include int main(){int *p = NULL;#line 30*p = 0return 0;}

编译出错:提示是31行出错,*p=0 末尾缺少分号,出错的文件名默认是当前文件名。

2.# line 整数n  文件名称

设置当前#line所在行的行号和当前文件名。

#include int main(){int *p = NULL;#line 30 "mytest.c"*p = 0return 0;}

编译出错:提示是mytest.c文件的31行出错,*p=0 末尾缺少分号。

# 出错处理指示

预处理指令#error用来控制编译器停止编译,显示特定的出错信息。

例如:

#include int main(){#error "test error"return 0;}

编译出错:显示 "test error"

# 编译指示

预处理指令#pragma,各种编译器实现自定义预处理功能,用于扩展,例如禁用编译器的一些警告信息,拓展一些编译功能,标准没有定义具体的指令,需要根据不同编译器文档使用。

# 系统预定义的宏名

预定义的宏以两个下划线开头__。

__LINE__  当前源代码的行号

__FILE__  当前的源代码文件名称

__DATE__  编译日期,格式是Mmm dd yyyy

__TIME__  编译时间,格式是hh:mm:ss

__STDC__  表示当前编译器是否符合标准,1表示符合标准

例如:

#include int main(){printf("%d\n", __LINE__);printf("%s\n", __FILE__);printf("%s\n", __DATE__);printf("%s\n", __TIME__);printf("%d\n", __STDC__);return 0;}

输出:4E:\dev\test.cApr 2 202020:35:251

# 有关宏中的#和##运算符

宏中的#运算符,将宏参数字符串常量化,具体是将#和跟在其后的参数转换成字符串,自动加入双引号和转义特殊字符。

例如:

#include #define TEST(s) "012345"#s"789\n"int main(void){printf(TEST(6));printf(TEST("6"));return 0;}

输出:0123456789012345"6"789

##运算符将多个宏参数的值直接连接起来(不转换为字符串),##出现的两个宏参数中间,不能出现替换文本的开头和末尾。

例如:

#include #define TEST(s1,s2,s3) s1##s2##s3int main(void){printf("%d\n",TEST(1,2,3));return 0;}

输出:123

---------- End ----------

往期精彩推荐:

「喜欢C请赏个 赞    点击右下角 在看」

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/609472
推荐阅读
相关标签
  

闽ICP备14008679号