C预处理器是一个文本替换工具,在实际编译之前完成一些预先的处理。

C预处理器(C Preprocessor)简写为 CPP

预处理器命令都是以#开头,如:

#include <stdio.h>
包含源代码文件stdio.h

#define定义宏

  1. 代码文本替换
  2. 增强可读性
#define MAX_ARRAY_LENGTH 20
main () {
/*
*把所有的MAX_ARRAY_LENGTH 替换为20
*#define:增强可读性
*/
char a1[MAX_ARRAY_LENGTH];
char a2[MAX_ARRAY_LENGTH];
char a3[20];
}

系统提供的预定义宏

DATE 当前日期 字符串常量
TIME 当前时间 字符串常量
FILE 当前文件名 字符串常量
LINE 当前行号 十进制数字常量
puts(__DATE__);
puts(__TIME__);
puts(__FILE__);
printf("%d",__LINE__);

条件编译

  • 定义一个非0的宏
#include <stdio.h>
#define DEBUG 1
main(void) {
#if DEBUG
printf("Debug模式");
#else
printf("Release模式");
#endif
}
  • defined:专用于预处理器的运算符,只要定义无需具体内容
#include <stdio.h>
#define DEBUG
main(void) {
#if defined(DEBUG)
printf("Debug模式");
#else
printf("Release模式");
#endif
}

#undef取消已定义的宏

带参数的宏

  • 带参数的宏经常用来作为简单的函数使用。
  • 宏名字和左括号间必须没有空格。
  • 比函数速度稍微快一些(函数需要存储上下文信息、复制参数值等)。
  • 宏参数没有类型,更通用。
  • 每次调用宏都有代码替换,编译后代码会变大。
#include <stdio.h>
#define MAX(x,y) (x>y?x:y)
main(void) {
int i = MAX(1,2);
// →int i = (1>2?1:2);
printf("%d",i);
}
#include <stdio.h>
#define IS_EVEN(n) (n%2==0)
main(void) {
int i = IS_EVEN(20);
// →int i = (20%2==0);
printf("%d\n",i);
int j = IS_EVEN(21);
// →int i = (21%2==0);
printf("%d\n",j);
}

*字符串常量化(#)

#include <stdio.h>
#define func(a) printf("我乃是")
int main(void) {
func("五百年前大闹天宫的齐天大圣");
return 0;
}
#include <stdio.h>
#define func(a) printf("我乃是"#a)
int main(void) {
func(五百年前大闹天宫的齐天大圣);
return 0;
}

宏换行(\)

#include <stdio.h>
#define func(a) \
printf("我乃是"#a)
int main(void) {
func(五百年前大闹天宫的齐天大圣);
return 0;
}

*标记粘贴运算符(##)

  • 将两个标记“粘合”在一起。

    如:MAX函数,只能用于某一特定的类型,如果既要适用于int,又要适用于float,就需要定义两个函数,函数体完全一样。如果还要再适用于long,double等,重复代码将会更多。
#include <stdio.h>
int int_max(int x,int y) {
return x>y?x:y;
}
float float_max(float x,float y) {
return x>y?x:y;
}
main(void) {
printf("%d\n",int_max(1,2));
printf("%f\n",float_max(1.2,2.3));
}
#include <stdio.h>
#define GENERIC_MAX(t) \
t t##_max(t x,t y)\
{\
return x>y?x:y;\
}
GENERIC_MAX(int);
GENERIC_MAX(float);
main(void) {
printf("%d\n",int_max(1,2));
printf("%f\n",float_max(1.2,2.3));
}

C语言讲义——预处理的更多相关文章

  1. C语言: 预处理

    1. 字符映射 键盘有多种标准规格,例如常用的IBM 104键盘标准,然而不是所有键盘都能打出像#这样的符号,因此C语言的预处理引入了字符映射机制.如果程序员要求,预处理会按照约定对源代码中的字符进行 ...

  2. C语言之预处理命令

    /**************************************************************************** Title:C之预处理命令 Time:201 ...

  3. R语言数据预处理

    R语言数据预处理 一.日期时间.字符串的处理 日期 Date: 日期类,年与日 POSIXct: 日期时间类,精确到秒,用数字表示 POSIXlt: 日期时间类,精确到秒,用列表表示 Sys.date ...

  4. C语言之预处理详解

    C语言之预处理详解 纲要: 预定义符号 #define #define定义标识符 #define定义宏 #define的替换规则 #与## 几点注意#undef 带副作用的宏参数 宏和函数的对比 命名 ...

  5. C语言之预处理

    这是2016年的最后一篇博客,年初定的计划是写12篇博客,每月一篇,1/3转载,2/3原创,看来是实现不了了! -- 题外话.今天要写的东西是C语言中的预处理器,我们常说的宏定义的用法.为什么要写这个 ...

  6. iOS开发系列--C语言之预处理

    概述 大家都知道一个C程序的运行包括编译和链接两个阶段,其实在编译之前预处理器首先要进行预处理操作,将处理完产生的一个新的源文件进行编译.由于预处理指令是在编译之前就进行了,因此很多时候它要比在程序运 ...

  7. Linux C编程学习之C语言简介---预处理、宏、文件包含……

    C的简介 C语言的结构极其紧凑,C语言是一种模块化的编程语言,整个程序可以分割为几个相对独立的功能模块,模块之间的相互调用和数据传递是非常方便的 C语言的表达能力十分强大.C语言兼顾了高级语言和汇编语 ...

  8. 【C语言入门教程】2.8 C 语言的预处理命令

    预处理命令是在程序编译阶段进行执行的命令,用于编译与特定环境相关的可执行文件.预处理命令扩展了 C 语言,本节将选择其中一些常用的预处理命令进行讲解. 2.8.1 宏替换命令 宏替换命令的作用类似于对 ...

  9. c语言编译预处理和条件编译执行过程的理解

    在C语言的程序中可包括各种以符号#开头的编译指令,这些指令称为预处理命令.预处理命令属于C语言编译器,而不是C语言的组成部分.通过预处理命令可扩展C语言程序设计的环境. 一.预处理的工作方式 1.1. ...

随机推荐

  1. SpringApplication.run(xxx.class, args)背后的东东——整体脉络

    从spring到springmvc,再到springboot.springcloud,应用程序api开发调用方面都已经非常熟悉,但对spring背后的扩展机制:为何一个简单的main方法可以实现这么强 ...

  2. 牛客1029A 袜子分配

    题面传送门 没学过数论的蒟蒻第一次做出数学题, 这是一种乱搞的复杂做法 先来看个简单的问题, 数字1-10取1个,问包含1的方案有多少种.显然,每一个数字取到的概率是同样的, 方案数为    , su ...

  3. Android 教你如何发现 APP 卡顿

    最近部门打算优化下 APP 在低端机上的卡顿情况,既然想优化,就必须获取卡顿情况,那么如何获取卡顿情况就是本文目的. 一般主线程过多的 UI 绘制.大量的 IO 操作或是大量的计算操作占用 CPU,导 ...

  4. 微信小程序--基于ColorUI构建皮皮虾短视频去水印组件(仅供学习使用)

    微信小程序--基于ColorUI构建皮皮虾短视频去水印组件(仅供学习使用) 没错,我是皮友,我想学习舞蹈(/doge)和瑜伽 ,要无水印的那种有助于我加深学习. 1.组件效果展示 2.组件引入准备 h ...

  5. Java学习的第三十二天

    1. 2.综合例题没太看懂 3.明天复习第十二章

  6. xlwt模块,(Excel表格)

    1. 安装模块 #pip install xlwt 2. 简单例子打印excel import xlwt # 创建一个workbook 设置编码 workbook = xlwt.Workbook(en ...

  7. windows下redis的PHP扩展安装

    1.查看已安装PHP的信息,打印phpinfo(); 主要看三个信息:PHP版本,是否线程安全(TS或NTS),系统是x64还是x86.用以确定扩展文件的版本. 2.需要php_redis.dll这个 ...

  8. 我的 Redis 被入侵了

    好吧,我也做了回标题党,像我这么细心的同学,怎么可能让服务器被入侵呢? 其实是这样的,昨天我和一个朋友聊天,他说他自己有一台云服务器运行了 Redis 数据库,有一天突然发现数据库里的数据全没了,只剩 ...

  9. python开发--基础知识-(持续更新)

    python基础 --基础: 1, 第一句python - 用cmd 调用--python (路径)+(文件名)) 扩展名是任意的 - 导入模块是,如果不是.py文件,可能导入不成功 - python ...

  10. C# 中的 ref 已经被放开,或许你已经不认识了

    一:背景 1. 讲故事 最近在翻 netcore 源码看,发现框架中有不少的代码都被 ref 给修饰了,我去,这还是我认识的 ref 吗?就拿 Span 来说,代码如下: public readonl ...