C语言 带参数宏定义中 # 和 ## 知识点总结、代码分析
目录
一、宏定义中 “#”知识点
1、直接转换字符串,不展开。
2、转换出的结果一定是“字符串”。
二、宏定义中 ## 知识点
1、应用场景
2、“##”的作用是将 左右两边的参数做整体字符串拼接替换
3、经过 ## 替换后的内容必须 有一个 同名的 变量与之对应。
4、 只拼接,不展开。
5、## 操作 动态函数指针 案例代码
一、宏定义中 “#”知识点
#的作用是将“#”后面的宏参数进行字符串转换操作,也就是将#后面的参数 两边加上一对双引号,使其成为字符串。
这里面有几个知识点:
1、直接转换字符串,不展开。
这句话的意思是,带参数宏定义也是宏,而不是普通函数,所以要保留宏的基本特性,也就是全部替换,而不展开。示例代码:
#include <stdio.h>
#include <stdlib.h>#define CONVERT(a) #aint main(int argc, char *argv[]) {int a = 6;printf("res:%s\n", CONVERT(a));return 0;
}
运行结果:
res:a
2、转换出的结果一定是“字符串”。
代码如下:
#include <stdio.h>
#include <stdlib.h>#define CONVERT(a) #aint main(int argc, char *argv[]) {printf("string print:%s\n", CONVERT(6)); // 字符串格式打印printf("int print:%d\n", CONVERT(6)); // 整型打印return 0;
}
运行结果如下:
string print:6
int print:4210688
二、宏定义中 ## 知识点
1、应用场景
## 的 应用场景主要是 函数指针的动态绑定,使用该宏参数,可以实现 同类型 函数指针 赋值或者引用的 方便操作。这个后面会有代码详细分析。
2、“##”的作用是将 左右两边的参数做整体字符串拼接替换
不管 ## 左右两边是字母还是数字,最终都是作为 一个整体 拼接成一个字符串。代码如下:
#include <stdio.h>
#include <stdlib.h>#define FUNC(a) func_##avoid func_1(void)
{printf("this is func 1.\n");
}void func_2(void)
{printf("this is func 2.\n");
}int main(int argc, char *argv[]) { FUNC(1)();FUNC(2)();return 0;
}
3、经过 ## 替换后的内容必须 有一个 同名的 变量与之对应。
比如 运行 FUNC(1),必须要保证 有一个 func_1 函数, 同样的 FUNC(2) 对应 func_2函数,如果没有,编译会报错,提示对象未 定义。
4、 只拼接,不展开。
这个类似于 # ,也是原封不动的转换,并不会进一步展开,比如:
int i = 1;
FUNC(i)();
尽管 i = 1,但是 FUNC(i) 的结果是 func_i,而不是 func_1.,所以我们不能够使用 ## 的时候,自作聪明的使用变量。
5、## 操作 动态函数指针 案例代码
在 知识点3中,我们提到 不能使用 变量 和 ## 的结合来实现 动态绑定函数指针,那么我们的程序代码就相对不太方便,尤其是我们 想要定义 一系列的 函数,这些函数主题名相同,但是序号不同,那么这个时候,就推荐使用 结构体 数据结构,代码如下所示:
#include <stdio.h>
#include <stdlib.h>#define FUNC(a) func_##avoid func_0(void)
{printf("this is func 0.\n");
}void func_1(void)
{printf("this is func 1.\n");
}void func_2(void)
{printf("this is func 2.\n");
}//包含函数 序号、 函数指针的 结构体
typedef struct func_t{int id;void (*func)(void);
} func_map_t;// 函数结构体 数组
static func_map_t g_func_map[3] = {
{0, FUNC(0)},
{1, FUNC(1)},
{2, FUNC(2)},
};int main(int argc, char *argv[]) { g_func_map[0].func(); //间接调用 序号对应的 函数。g_func_map[1].func();g_func_map[2].func();return 0;
}
这里需要注意的是,我们在定义 上面的 g_func_map 数组 时,需要 在 函数func_0、func_1、func_2之后,这可能是因为编译器先后顺序的原因,如果g_func_map 在这三个函数之前,那么会出现 编译报错信息,显示 这3个函数未定义,可以简单的认为,在定义的时候,数据类型从 前面 查找, 而不是全局查找。
运行结果如下:
this is func 0.
this is func 1.
this is func 2.
C语言 带参数宏定义中 # 和 ## 知识点总结、代码分析相关推荐
- 宏定义有无参数宏定义和带参数宏定义两种
宏定义有无参数宏定义和带参数宏定义两种. 无参数的宏定义的一般形式为 # define 标识符 字符序列 其中# define之后的标识符称为宏定义名(简称宏名),要求宏名与字符序列之间用空格符分隔. ...
- c语言宏定义可变参数,C语言可变参数宏定义方法
http://blog.csdn.net/skyflying2012/article/details/38436711 2014 在GNU C中,宏可以接受可变数目的参数,就象函数一样,例如: 1 2 ...
- c 语言 宏 可变 参数,C语言 如何在宏定义中使用可变参数
有一个记录日志的函数,想用宏定义进行包装,简化调用方法,但是xlc报如下的错误:void _log(const int level, char* file, int line, const char* ...
- C语言带参宏定义和函数的区别
带参数的宏和函数区别: 宏展开仅仅是字符串的替换,不会对表达式进行计算:宏在编译之前就被处理掉了,它没有机会参与编译,也不会占用内存.而函数是一段可以重复使用的代码,会被编译,会给它分配内存,每次调用 ...
- [C语言编程入门]带参数宏定义
问题描述 定义一个带参的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参.输出已交换后的两个值. 解决方案: #include<stdio.h> #define swap( ...
- [编程入门]带参数宏定义练习:定义一个带参的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参。输出已交换后的两个值。
#include<bits/stdc++.h> #define fun(a,b) t=a;a=b;b=t; using namespace std;int main() {int a,b, ...
- mysql宏参数_C语言带参数的宏定义
C语言允许宏带有参数.在宏定义中的参数称为"形式参数",在宏调用中的参数称为"实际参数",这点和函数有些类似. 对带参数的宏,在展开过程中不仅要进行字符串替换, ...
- 【C语言】宏定义和带参宏定义
宏定义是在编程中经常使用的一个模块,其优点在于当写的代码量比较大的时候方便修改检查,可以做到改一变"百". 一.宏定义 宏定义是用宏名来表示一个字符串,在宏展开时又以该字符串取代宏 ...
- 巧用c语言宏定义实现自动注释调试代码,C语言宏定义中的特殊用法
C宏定义中的特殊用法 在分析一些C源码时,经常会遇到各种宏定义操作,本文即总结一下C语言宏定义中常见的预定义宏.调试宏:宏的条件编译用法及特殊的宏关键字用法. #undef 限定宏的作用域 一般来讲宏 ...
最新文章
- 关于Android开源库分享平台,(GitClub)微信小程序的开发体验
- jenkins需安装插件总结
- Spark编程指南笔记
- 5 Android数据存储 任务二 应用程序数据文件夹里的文件读写 ,
- 【数据竞赛】Kaggle秘技,用Sigmoid函数做回归问题!
- java 1.8签名apk_给Android的APK程序签名和重新签名的方法
- Leetcode 565. Array Nesting
- 大数据自学——Spark
- Python:Python程序设计思维、计算生态、用户体验、程序设计模式
- Java集合Collection接口中的常用方法演示
- 2021年南阳市五中高考成绩查询,南阳市“赫赫有名”的五大高中,2020年高考成绩一目了然!...
- ueditor+asp.net异步提交,可以实现了,嘿嘿
- lbochs模拟器最新版_bochs模拟器最新版下载
- 圆锥曲线之用齐次法求解直线过定点问题
- V-rep机器人仿真软件使用的学习笔记-续
- 有关于fprintf()函数的用法
- 荣耀MagicOS 7.0正式发布;快手科技2022年第三季度收入同比增长12.9% | 美通企业日报...
- 2022年下半年信息系统项目管理师下午真题及答案解析
- Unity出IOS包报错记 -1
- 分享个龙门神途脚本辅助工具,相当于一个云端的安卓模拟器