文章目录

  • 预处理
  • 预处理运算符
  • 宏定义
    • 无参宏定义
    • 带参宏定义
    • 宏定义-定义函数

此文主要介绍宏定义,并在介绍宏定义时举例介绍预处理命令

预处理

参考:C 预处理器 | 菜鸟教程
重要的预处理器指令如下:

指令 描述
#define 定义宏
#include 包含一个源代码文件
#undef 取消已定义的宏
#ifdef 如果宏已经定义,则返回真
#ifndef 如果宏没有定义,则返回真
#if 如果给定条件为真,则编译下面代码
#else #if 的替代方案
#elif 如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码
#endif 结束一个 #if……#else 条件编译块
#error 当遇到标准错误时,输出错误消息
#pragma 使用标准化方法,向编译器发布特殊的命令到编译器中

预处理运算符

符号 描述
\ 宏延续运算符。一个宏通常写在一个单行上。但是如果宏太长,一个单行容纳不下,则使用宏延续运算符(\)
# 字符串常量化运算符。在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)。
## 标记粘贴运算符。宏定义内的标记粘贴运算符(##)会合并两个参数。
defined 预处理器 defined 运算符是用在常量表达式中的,用来确定一个标识符是否已经使用 #define 定义过。

宏定义

define,宏定义,C语言中预处理命令一种。分为无参宏定义和带参宏定义。

无参宏定义的一般形式为:#define 宏名 字符串
带参宏定义的一般形式为:#define 宏名(参数表) 字符串

无参宏定义

C语言中无参宏定义的一般形式为:#define 宏名 字符串

  • 使用#undef 宏名取消已定义的宏
#define MESSAGE "Hello World!"
printf("%s\n",MESSAGE);
#undef MESSAGE
  • 如果MESSAGE没有定义,则定义MESSAGE为10000
#ifndef MESSAGE#define MESSAGE 10000
#endif
printf("%d\n",MESSAGE);

带参宏定义

带参宏定义的一般形式为:#define 宏名(形参表)字符串

  • 如果MESSAGE没有定义,执行语句1;否则,执行语句2
#define MAX(a,b) a>b?a:b#if !defined(MESSAGE)#define MESSAGE 10000
#elseprintf("%d\n",MAX(1,10));
#endif
  • 如果if判断为真,则执行语句
bool flag=true;
#define PRINT(section) if(flag){\printf("%s\n",section);\
}
PRINT("hello world!");

宏定义-定义函数

可以通过宏定义少写很多代码,大家可以看下面一串代码

#define _CONFIG_MAKE_PROTOTYPE(fname,type) type cfg_get##fname(const char *name,const type def)_CONFIG_MAKE_PROTOTYPE(str,char*);
_CONFIG_MAKE_PROTOTYPE(num,int);
_CONFIG_MAKE_PROTOTYPE(uint8,uint8_t);
_CONFIG_MAKE_PROTOTYPE(int8,int8_t);
_CONFIG_MAKE_PROTOTYPE(uint16,uint16_t);
_CONFIG_MAKE_PROTOTYPE(int16,int16_t);
_CONFIG_MAKE_PROTOTYPE(uint32,uint32_t);
_CONFIG_MAKE_PROTOTYPE(int32,int32_t);
_CONFIG_MAKE_PROTOTYPE(uint64,uint64_t);
_CONFIG_MAKE_PROTOTYPE(int64,int64_t);
_CONFIG_MAKE_PROTOTYPE(double,double);

_CONFIG_MAKE_PROTOTYPE(str,char*);为例,这一行等价于什么呢?等价于:

char *cfg_getstr(const char *name, const char *def);

_CONFIG_MAKE_PROTOTYPE(fname,type);返回类型为type类型,形参为const char *name和类型为const typedef
此时fname=str,type=char*中,##标记粘贴运算符,合并两个参数。将fnametype替换之后,即:

char *cfg_getstr(const char *name, const char *def);

对于代码的具体实现,可以如下处理:

#define _CONFIG_GEN_FUNCTION(fname,type,convname,format) \
type cfg_get##fname(const char *name,const type def) { \paramstr *_cfg_tmp; \for (_cfg_tmp = paramhead ; _cfg_tmp ; _cfg_tmp=_cfg_tmp->next) { \if (strcmp(name,_cfg_tmp->name)==0) { \STR_TO_##convname(_cfg_tmp->value); \} \} \if (logundefined) { \mfs_arg_syslog(LOG_NOTICE,"config: using default value for option '%s' - '" format "'",name,def); \} \COPY_##convname(def); \
}_CONFIG_GEN_FUNCTION(str,char*,charptr,"%s")
_CONFIG_GEN_FUNCTION(num,int,int,"%d")
_CONFIG_GEN_FUNCTION(int8,int8_t,int32,"%"PRId8)
_CONFIG_GEN_FUNCTION(uint8,uint8_t,uint32,"%"PRIu8)
_CONFIG_GEN_FUNCTION(int16,int16_t,int32,"%"PRId16)
_CONFIG_GEN_FUNCTION(uint16,uint16_t,uint32,"%"PRIu16)
_CONFIG_GEN_FUNCTION(int32,int32_t,int32,"%"PRId32)
_CONFIG_GEN_FUNCTION(uint32,uint32_t,uint32,"%"PRIu32)
_CONFIG_GEN_FUNCTION(int64,int64_t,int64,"%"PRId64)
_CONFIG_GEN_FUNCTION(uint64,uint64_t,uint64,"%"PRIu64)
_CONFIG_GEN_FUNCTION(double,double,double,"%lf")

C语言 | 预处理 | 宏定义 | #define | 定义函数相关推荐

  1. C语言初阶:define定义的常量和宏,关于指针的详细讲解,初步认识结构体的使用

    目录: 1.define定义常量和宏 2.指针 3.初始结构体 学习内容: 1.define是一个预处理指令 //1.作用一:定义标识符常量 //2.作用二:定宏 define定义的宏是用来完成替换的 ...

  2. 宏定义#define整理

    一.宏定义#define 优点:一方面可以节省程序的空间上的篇幅,另外,恰当地使用宏定义可提高程序的时间效率.代码可以写的通俗易懂.可以提高程序的清晰性.可读性,使于修改移植等. 缺点:宏定义的使用实 ...

  3. c语言----预处理

    c语言----预处理 宏 不带参数的宏 带参数的宏 头文件 条件编译 #if 命令 #else 与#elif #ifdef及#ifndef命令 #progma命令 预定义宏名 宏 不带参数的宏 宏定义 ...

  4. C语言学习笔记--预编译/宏定义/数组/参数传递/函数指针

    目录 预编译 值传递.指针传递.引用传递 数组 typedef 函数指针 预编译 预编译又叫预处理.预编译不是编译,而是编译前的处理.这个操作是在正式编译之前由系统自动完成的.#define 和 #i ...

  5. C语言常用宏定义(#define)使用方法

    ·  正  ·  文  ·  来  ·  啦  · 前言 ------在上篇文章里面,我们分析了预处理的一个完整过程,这能够让我们理解一个写好的程序,在生成一个可执行文件,到底发生了什么,对我们在大型 ...

  6. c语言 #define dpath .exe是什么意思,C语言宏定义#define

    姓名:吕彬 学号:1613014035 [嵌牛导读]#define 宏定义是个演技非常高超的替身演员,但也会经常耍大牌的,所以我们用它要慎之又慎.它可以出现在代码的任何地方,从本行宏定义开始,以后的代 ...

  7. c语言数组宏定义标识符,C语言学习笔记--预编译/宏定义/数组/参数传递/函数指针...

    目录 预编译 值传递.指针传递.引用传递 数组 typedef 函数指针 预编译 预编译又叫预处理.预编译不是编译,而是编译前的处理.这个操作是在正式编译之前由系统自动完成的.#define 和 #i ...

  8. define定义的函数如何引用_「C与指针心得」25.预处理器-宏函数

    感谢您的阅读与点赞!欢迎关注:「大猫玩程序」,查看C语言系列文章 上一节讲了一些系统的预定义宏,这一节来讲一讲 宏定义.宏函数. 预处理常量 define: 预处理器指令从#开始,到最后第一个换行符为 ...

  9. c语言解除宏定义_C语言宏定义 define,及一些陷阱!

    https://m.toutiaocdn.com/group/6584292311289561607/?iid=39362926900&app=news_article&timesta ...

最新文章

  1. VSTO Office二次开发PPTRibbonX命令操作及对象添加
  2. python最早引入json的版本_详解Python在使用JSON时需要注意的编码问题
  3. 数据结构与算法之“之”字型打印矩阵和矩阵中找数
  4. origin遇到不适当的参数_Origin教程|如何更改Lable和设置非均匀坐标
  5. 不是吧?!程序员月入10w,原因竟然是这个......
  6. 写给软件工程师的 30 条建议
  7. 程序员面试揭秘之求职渠道
  8. 面向对象(Python):学习笔记之单例模式
  9. 组态王图素制作_组态王教程 很实用
  10. Windows设置访问白名单
  11. 海马玩模拟器离线安装包下载方法
  12. 三种数据流分析的方程、用途
  13. rxjava背压_RxJava(九):背压
  14. GNU Radio: USRP2 and N2x0 Series
  15. TopoTag:A Robust and Scalable Topological Fiducial Marker System 笔记
  16. 移动通信网络规划:频谱划分
  17. JSP学生奖学金系统JSP学生评奖评优系统JSP奖学金管理系统 JSP奖学金评定系统
  18. 如何优雅的完成一场说来就来的APP自建
  19. 0.linux中英文环境的切换
  20. iframe 边框去除,使用大全

热门文章

  1. 通信工程之网线项目-心得体会
  2. 「镁客·请讲」武谷论链粗院长:区块链社区的核心价值是一种共识文化
  3. 关于NG-ZORRO的历史
  4. php和python区别-PHP和Python的区别是什么?
  5. 数据库SQL执行顺序
  6. Unity2d 击败敌人随机掉落物件
  7. 关于使用二维数组实现输出三角形规律排列数字的Java代码
  8. gensim中动态主题模型(DTM)两种实现方法(二)
  9. Mac下安装GenyMotion模拟器并关联AndroidStudio
  10. python语言概述答案_Python语言概述。