C语言宏定义函数中的“_##”的意思
最近在看google vp9的代码的时候碰到:
#define intra_pred_sized(type, size) \
void vp9_##type##_predictor_##size##x##size##_c(uint8_t *dst, \
ptrdiff_t stride, \
const uint8_t *above, \
const uint8_t *left) { \
type##_predictor(dst, stride, size, above, left); \
}
对于define 中 ##的用法的确不知知道,网上找啦很多资料,总结收集如下:
#define Conn(x,y) x##y
#define ToChar(x) #@x
#define ToString(x) #x
x##y表示什么?表示x连接y,举例说:
int n = Conn(123,456); 结果就是n=123456;
char* str = Conn("asdf", "adf")结果就是 str = "asdfadf";
怎么样,很神奇吧
再来看#@x,其实就是给x加上单引号,结果返回是一个const char。举例说:
char a = ToChar(1);结果就是a='1';
做个越界试验char a = ToChar(123);结果是a='3';
但是如果你的参数超过四个字符,编译器就给给你报错了!error C2015: too many characters in constant :P
最后看看#x,估计你也明白了,他是给x加双引号
char* str = ToString(123132);就成了str="123132";
最后留几个小试验给大家去测测:
#define Dec(x,y) (x-y)
int n = Dec( A(123,1), 1230);
n = Conn(123, Conn(123,332) );
char* str = A("12", ToString( Dec(3,1));
结果会如何呢? 嘿嘿嘿嘿~
三.
#define xxx() {}
标准C支持的
#define xxx() ({})
GCC新增的功能,主要为了防止宏展开出现问题,默认展开时是要加上一个;的,容易出问题。
CODE:#define A(a,b,c) ({a=1;b+=1;c=3;a+b+c;})
#include <stdio.h>
int main()
{
int a;
int b=1;
int c;
int d;
d=A(a,b,c);
printf("%d,%d,%d,%d\n",a,b,c,d);
return 0;
}
表示该宏函数还有返回值,最后一个式子的返回值作为宏函数的返回值。
运行结果:
1,2,3,6
结合上面说的VP9部分的代码可以解释为如下:
#define intra_pred_sized(type, size) \
void vp9_##type##_predictor_##size##x##size##_c(uint8_t *dst, \
ptrdiff_t stride, \
const uint8_t *above, \
const uint8_t *left) { \
type##_predictor(dst, stride, size, above, left); \
}
eg: #define intra_pred_sized(d207, 8*8) \
void vp9_d207_predictor_8**_c(uint8_t *dst, ptrdiff_t stride, const uint8_t *above, const uint8_t *lef){
d207_predictor(dst, stride, size, above, left);
}
C语言宏定义函数中的“_##”的意思的更多相关文章
- C 语言宏定义函数编写时 do-while 的妙用和一些注意事项
在 C 语言中,我们都知道可以用宏定义来编写函数,一般称为宏函数.如果一个宏函数比较复杂,那么在编写这样的宏函数是有一定技巧和注意事项的.文章给出一些我认为值得关注的地方,以及一些注意事项(个人建议) ...
- 将C语言宏定义数值转换成字符串!
将C语言宏定义转换成字符串! 摘自:https://blog.csdn.net/happen23/article/details/50602667 2016年01月28日 19:15:47 六个九十度 ...
- c语言宏定义详解
1,防止一个头文件被重复包含 #ifndef COMDEF_H #define COMDEF_H //头文件内容 #endif 2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数 ...
- C 语言宏定义
C 语言宏定义1.例子如下: #define PRINT_STR(s) printf("%s",s.c_str()) string str = "abcd"; ...
- iOS 使用宏定义函数和代码块
iOS使用宏定义函数和代码块 今天在开发过程中碰到一个问题:就是父类中要向外发送通知,然后子类中或者其他类中来接收它.当然一般是把它写到类方法中去,但是有个问题,就是如果调用的类不是它的子类,就不能直 ...
- C语言 宏定义之可变参数
可变参数宏定义 C99编译器标准允许你可以定义可变参数宏(variadic macros),这样你就可以使用拥有可以变化的参数表的宏.可变参数宏就像下面这个样子: #define dbgprint(. ...
- C语言宏定义和宏定义函数
要写好C语言,漂亮的宏定义是非常重要的.宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等. 在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定 ...
- C语言宏定义中的#和##的作用【转】
本文转载自:http://my.oschina.net/shelllife/blog/123202 在宏定义中#和##的作用是:前者将宏定义的变量转化为字符串:后者将其前后的两个宏定义中的两个变量无缝 ...
- C语言宏定义时#(井号)和##(双井号)的用法
C语言中如何使用宏C(和C++)中的宏(Macro)属于编译器预处理的范畴,属于编译期概念(而非运行期概念).下面对常遇到的宏的使用问题做了简单总结. 关于#和## 在C语言的宏中,#的功能是将其后面 ...
随机推荐
- 操作系统之进程篇(4)--经典进程间通信(IPC)问题
1. 哲学家进餐问题: 问题描述: 五个哲学家在一个圆桌上进餐,每人的面前放了一盘意大利面,两个盘子之间有一个叉子,但是由于盘子里面的面条十分光滑,需要两个叉子才能进行就餐行为.餐桌的布局如下图所示: ...
- mini2440移植uboot-2008.10 遇到的问题
1.mkimage的使用(u-boot-2008.10/tools/mkimage) 首先./mkimage 运行或者 将mkimage 拷贝到 /bin 目录下面 法一: #mkimage -n ' ...
- Linux 下如何使用看门狗
Linux内核有集成WD的选项.将其使能后,系统里就会有watchdog的设备驱动:/dev/watchdog.这样,在应用程序里只需打开这个设备使用即可:#include <fcntl.h ...
- 简单Linq笔记
Linq是.net 3.5才引入的 要引入命名空间System.Linq. Linq to XML要引入System.Xml.Linq Linq to ADO.NET要引入System.Data.L ...
- php 定时执行任务
之于是否控制,可以做到的,应借用第三个条件: config.php <?phpreturn 1;?> cron.phpignore_user_abort();//关掉浏览器,PHP脚本也可 ...
- JavaMail 发送邮件
JavaMail邮件发送 引用maven jar包 <dependency> <groupId>javax.mail</groupId> <artifactI ...
- uva 12124 - Assemble
最大值最小的题: 直接用二分,比较简单: 不过我的二分老是不用好.有时间总结一下! #include<cstdio> #include<map> #include<vec ...
- uva 10881 - Piotr's Ants
这个题的突破点就在于蚂蚁不能够穿过对方,故相对位置不变: 另外,又可以把蚂蚁看成运动方向不变: 代码: #include<cstdio> #include<algorithm> ...
- SDUT 2351 In Danger
点我看题目 题意 : 有n个兵想要自杀,所以他们决定围成一个圈,从1开始一直环到n,然后每第2个开始自杀,但是有一个兵不想死,所以让你编程求出最后一个应该死的人的位置,这样的话就剩他自己他可以不自杀了 ...
- Hibernate save或者persist 后获取主键ID
一个自增长ID的对象被save或者persist后,会返回其主键ID: Department department = new Department(); department.setName(&qu ...