「今天是学习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请赏个 赞    点击右下角 在看」

c语言编译预处理指令大全,C语言预处理指令相关推荐

  1. java版我的世界附魔指令_我的世界手机版附魔指令大全 怎么使用附魔指令

    我的世界手机版附魔指令大全 怎么使用附魔指令.那下面则是我的世界手机版中的一些附魔指令哦~那我的世界手机版怎么使用这些附魔指令呢?那下面就给大家介绍一下吧! 游戏园我的世界官方群:325049520或 ...

  2. c语言编译为机器语言过程,C语言编译全过程

    C语言编译全过程 编译的概念 编译程序读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码,再由汇编程序转换为机器语言,并且按照操作系统对可执行文件格式的要求链接生成 ...

  3. c语言编译常见错误提示,c语言编译常见错误

    c语言编译常见错误 (2012-04-17 21:33:53) 标签: 杂谈 分类: 计算机 1."c" not an argument in function sum 该标识符不 ...

  4. stm单片机c语言编译,单片机开发之C语言编程基本规范

    为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范.本标准规定了程序设计人员进行程序设计时必须遵循的规范.本规范主要针对单片机编程语言和08编译器而言,包括排版.注释.命名.变量 ...

  5. keil c语言编译运行,Keil的c语言编译器

    我曾经通过查看反汇编代码对KEILC编译器进行了测试,大概有这么一下内容,也得出一些结论. (1)全局变量:如果程序中定义了全局变量,而且初始值不是0.此时,在程序调到main()函数执行前,除了要进 ...

  6. c语言编译的手机软件,C语言编译工具

    软件介绍 C语言编译工具app是一款功能十分强大的手机编译.更换代码的软件工具,C语言编译工具app可以快速进行代码翻译.代码查找.替换等,它支持多种代码语言,欢迎下载! C语言编译工具app内容 简 ...

  7. 求生之路显示服务器指令大全手机,求生之路2指令大全 求生之路2指令怎么用? (7) _地图指令_游侠网...

    地图指令 c1m1_hotel 1.死亡中心1旅馆 c1m2_streets 1.死亡中心2街道 c1m3_mall 1.死亡中心3购物中心 c1m4_atrium 1.死亡中心4中厅 c2m1_hi ...

  8. c语言免杀花指令大全,免杀花指令

    今天送上经典花指令 注:编写花指令,可参考以下成双指令,可任意自由组合.达到免杀效果. push ebp pop ebp push eax pop eax push esp pop esp push ...

  9. python语言指令大全_Python语言----linux常用命令(14)

    文件压缩解压:bzip2 压缩:bzip2 filename ---> 删除filename文件,生成 filename.bz2 解压缩:bzip2 -d filename.bz2 ---> ...

最新文章

  1. 【骚气的动效】外发光涟漪波纹动画、向外辐射动画效果,通常用于地图上面某一个扩散点效果
  2. Mtop,Mysql Top,一个Mysql的监控工具
  3. JavaScript 中对象的属性类型
  4. Kafka消息丢失、重复消费的解决方案
  5. Altium designer快捷键汇总
  6. 添加tomcat7插件设置jdk编译版本
  7. CF1526 D. Kill Anton
  8. mysql数据库新建一个递增的_分享一个mysql实验—基于数据库事务隔离级别RR及RC的测试...
  9. MySQL实战案例100例(一)-如何解决非等值范围查找问题?
  10. 2019年7月前CSDN最新排名
  11. bfs+优先队列(hdu1242)
  12. 促销海报创意|你想要的秋天(秋季),吸睛大促海报都在这里
  13. pythonmkdir语法错误_Python:windows创建文件夹时出错操作系统.mkdir使用方括号
  14. 玩人工智能的你必须知道的语音识别技术原理
  15. 【源码阅读】Java集合之一 - ArrayList源码深度解读
  16. 生信自学笔记(三)分子数据库
  17. oracle查询asm的绝对路径,查找ASM 1号文件位置
  18. 微信小程序开发入门教程
  19. maven 阿里源配置完整 亲测有效
  20. Python读取本地html文件,获取其中表格内容

热门文章

  1. 代理服务器和反向代理服务器详解
  2. 数学建模——时间序列模型及spss实现
  3. 两部电梯的测试用例设计
  4. 什么是文本挖掘以及应该如何学习?
  5. tcpdump抓包分析详解
  6. 公司简易注销常见问题汇总
  7. CAN DBC解析自动生成C 信号 API代码
  8. 西北农林科技大学与陕西师范大学计算机,陕西师大比较稳定!如何看待陕西19校在四大排行榜上的综合排名!...
  9. AIX 12.1.0.2 rtld: 0712-001 Symbol CreateIoCompletionPort was referenced from module
  10. FreeMarker的一些基础语法