首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

整理CC++可变参数

直到C99编译器标准,它允许可以定义可变参数(variadic macros) C可变参数 可变参数: #define DEBUG(...) printf(__VA_ARGS__) /* 1999...ISO C版本,你不能省略可变参数,但是你却可以给它传递一个空参数。...例如,下面的调用在ISO C里是非法,因为字符串后面没有逗号,: LOG("A message") 虽然GNU CPP这种情况可以让你完全忽略可变参数。...fprintf(stderr, format, ## __VA_ARGS__) 如果传入可变参数被忽略或者为空时,##操作会将使得预处理器(preprocessor)去除掉它前面的逗号。...#endif //end for #ifdef _DEBUG   1) FILE 预编译时会替换成当前源文件名   2) LINE预编译时会替换成当前行号   3) FUNCTION预编译时会替换成当前函数名称

5.2K00

CC++ 预处理器

名字不允许有空格,而且必须遵循C变量命名规则 替换列表(replacement list)或叫 主体(body), (这个地方可以省略,说明只是定义了这个一个) 预处理器程序中发现了实例后...展开: 从变成最终文本过程。...一般而言,预处理器发现程序后,会用它等价替代文本代替,如果该 文本 还包括,则继续替换这些。 如果存在与双引号内,则不予替换。...语言符号 从技术方面看,系统将 主体 当作语言符号(token)类型字符串,而不是字符型字符串。 C预处理器 语言符号 是定义主体 单独词(空格分割开词)。...+ ,# 与 ## 用法 # 作用 #功能是将其后面的 参数 进行字符串化操作, 就是:变量替换后,左右各加一个双引号。

1.3K90
您找到你想要的搜索结果了吗?
是的
没有找到

提高代码逼格利器:定义-从入门到放弃

; 我们写代码时候,所有使用名称地方,都可以理解为一个占位符。... C++ ,这样操作可以通过参数模板来实现,所谓模板也是一种代码动态生成机制。当定义了一个函数模板后,根据调用者实参,来动态产生多个函数。...所以,从代码动态生成角度看,定义和 C++ 模板参数有点神似,只不过定义仅仅是代码扩展而已。...在前面的例子参数传递都是一些变量,而这里传递参数是数据类型,通过类型无关性,达到了“动态”创建结构体目的: struct vector_int { int *data;...我记得侯杰老师 C++ 视屏,利用可变参数模板这个语法,也实现了类似的功能。

1K40

Linux kernel中常见整理

区别在于标识符列表使用,作为不同参数之间分割符。每一个参数都是一个 token 化列表。中空白符只起到分割 token 作用,空白符多少对于预处理器是没有意义。...Linux内核do{...}while(0)意义: 辅助定义复杂,避免引用时候出错,如果不用{},if后面的语句只有第一条进行了判断。同时避免展开后“;”造成编译不通过...., b) \ do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) container_of 根据一个结构体变量成员变量来获取整个结构体变量指针...这样cache取数据时就可以将分支后执行语句放在cache,提高cache命中率 http://www.169it.com/article/17243108930910839727.html...一些并发场景变量进行优化有可能导致错误,需要时刻得到变量最新值,所以用volatile强制访问一次进行更新。

1.9K50

Linux kernel中常见整理

区别在于标识符列表使用,作为不同参数之间分割符。每一个参数都是一个 token 化列表。中空白符只起到分割 token 作用,空白符多少对于预处理器是没有意义。...Linux内核do{...}while(0)意义: 辅助定义复杂,避免引用时候出错,如果不用{},if后面的语句只有第一条进行了判断。同时避免展开后“;”造成编译不通过....(a, b) \ do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) container_of 根据一个结构体变量成员变量来获取整个结构体变量指针...这样cache取数据时就可以将分支后执行语句放在cache,提高cache命中率。...一些并发场景变量进行优化有可能导致错误,需要时刻得到变量最新值,所以用volatile强制访问一次进行更新。

1.6K20

iOS预编译指令初步探究

其实__COUNTER__是一个预定义,这个值在编译过程中将从0开始计数,每次被调用时加1。因为唯一性,所以很多时候被用来构造独立变量名称。有了上面的基础,再来看最后实现就很简单了。...__FILE__返回当前文件绝对路径,__LINE__返回展开文件行数,__func__是改所在scope函数名称。...__VA_ARGS__表示定义...所有剩余参数。我们之前说过可变参数将被统一处理,在这里展开时候编译器会将__VA_ARGS__直接替换为输入从第二个参数开始剩余参数。...如果我们申明这个时候没有指定format参数,而直接使用参数列表,那么使用不写参数NSLog()也将被匹配到这个,导致编译无法通过。...另外你也不用担心展开以后式子里NSLog会再次被自己展开,虽然展开NSLog也满足了我们定义,但是展开非常聪明,展开后会自身无限循环情况,就不会再次被展开了。

2.2K80

变参函数和可变参数

print_num 函数,先获取 count 参数地址,然后使用 &count + 1 就可以获取下一个参数指针地址,使用指针变量 args 保存这个地址,并依次访问下一个地址,就可以直接打印传进来各个实参值了...但打印时候,我们还必须自己实现。 V4.0 版本,我们继续改进,使用 vprintf 函数实现我们打印功能。vprintf 函数声明 stdio.h 头文件。...预处理器展开时,会用变参列表替换掉定义所有 VA_ARGS 标识符。...printf("hello\n", ); 展开后,第一个字符串参数后面还有一个逗号,所以就产生了一个语法错误。我们需要对这个进行改进,使用连接符##,来避免这个语法错误。...连接符 ## 主要作用就是连接两个字符串,我们定义可以使用 ## 来连接两个字符。预处理器预处理阶段对展开时,会将## 两边字符合并,并删除 ## 这两个字符。

1.6K20

cc++:基于for each pair 遍历 __VA_ARGS__ 元素,实现定义struct

https://blog.csdn.net/10km/article/details/80798072 在上一篇博客《c/c++:for each遍历 __VA_ARGS__ 每一个元素...在上篇博客例子,可以利用这个遍历功能定义枚举(enum)类型。 进一步延伸思考,还可以利用这个能力定义结构体(struct)呀。...当然定义结构体与枚举类似是有区别的,结构体每个成员不光需要成员名还需要指定数据类型。所以不能简单使用上篇文章FL_FOREACH来实现。...我们需要能遍历成对参数能力,这就是下面的FL_VA_FOREACH_PAIR,这个函数对__VA_ARGS__(必须是偶数个)参数以两个一组为单位进行遍历。...m2,char*, m3) 展开代码(eclipse显示编译器花了18步完成展开,so艰难): ?

1.5K10

ReactiveCocoa 奇妙无比” 魔法

ReactiveCocoa ,封装了很多非常实用”,使用这些“”为我们开发带来了很多便利。 今天就来盘点一下RAC是如何实现。...计算机语言如C语言或汇编语言有简单系统,由编译器或汇编器处理器实现。C语言处理器工作只是简单文本搜索和替换,使用附加文本处理语言如M4,C程序员可以获得更精巧。...对于编译语言来说,所有的都是预编译时候被展开,所以lex进行词法扫描生成Token,词法分析过程之前,所有的都已经被展开完成了。 对于Xcode,预处理或者预编译阶段是可以直接查看。...ReactiveCocoa,作者定义了这么一些基础,作为“元”,它们是构成之后复杂基础。分析常用之前,必须要先分析清楚这些元具体实现。...由于展开预编译时期,所以它在预编译时期获取参数个数,其他非方法都是在运行时获取参数个数

2.5K20

RAC(ReactiveCocoa)介绍(十一)——RAC定义

绝大多数情况下,“”这个词使用暗示着将小命令或动作转化为一系列指令。 RAC框架,其定义功能强大能帮助开发者更加快速、便捷地进行开发工作。...常用比如:打破循环引用、以及KVO方法属性监听等等。 ? 打破实例变量循环引用 ? KVO属性监听 这一篇主要探究RAC定义强大之处究竟在哪。...经常使用定义RACObserve(TARGET, KEYPATH)观察KVO属性时,能够KEYPATH,代码预提示出指定TARGET属性 ?...RACObserve能够提示出当前self存在实例变量 metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)代码实现: #define...metamacro_atN定义 metamacro_atN定义,意思为截取掉定义前N个元素,保留剩下元素传入至metamacro_head(__VA_ARGS__) 展开metamacro_head

2.5K30

CC++ 之 C发展史及 各标准特性说明

C99标准规定,可以省略函数原型名称,但是如果省略名称,则需要用星号来代替省略维数: int sum2d(int , int, int ar[*][*]); // 只能用在函数声明  数组声明类型修饰符...分散代码与声明    解除了原先必须在block第一条语句之前声明变量限制:现在C99也和C++一样,可以代码随时声明变量了。 ...预处理程序修改  变参(Variadic Macros)    可以带变元,定义中用省略号(…)表示。内部预处理标识符__VA_ARGS__决定变元将在何处得到替换。...__VA_ARGS__)  // 参数里面“...”部份会展开到__VA_ARGS__处。   ...当变参部份为空时__VA_ARGS__展开成空字符串,并且##前面那个逗号也会在展开时去掉。

86500

玩转iOS“定义”

初学定义时候,大家可能都会有这样一种感觉:就是完全替换么,太简单了。但如果你真这么想,那你就太天真了,不说自己编写Foundation框架内置定义许多要看明白也要费一番脑筋。...,变量自加结果也不对了,我们检查其展开结果: CGFloat res = 3.1415926 * (r++) * (r++); 原来问题出在这里,展开时候,将参数替换了两次,由于参数本身是一个自加表达式...这确实难受,我们进一步,比如对临时变量名字做一些手脚,将其命名为极其不容易重复名字,其实系统内置一个就是专门用来构造唯一性变量:__COUNTER__,这个是一个计数器,在编译时候会自动进行累加...展开过程,如果替换列表中出现了要被展开,则此不会被展开。...上面的展开原则提到了替换列表,展开过程中会维护一个替换列表,展开过程需要从参数到本身,从外层到内层一层一层替换,每次替换时候都会将被替换名放入维护替换列表,再下一轮替换,如果再次出现替换列表中出现过

3.3K11

嵌入式c编程一点小记录——

1、通常来讲,就是预编译用于替换,因此,如果里面有enum,那么预编译是不会成功。gcc,tcc等编译器可以使用-E选项。可以输出.i 文件,查看预编译输出文件。...这就是ide流程好入门原因啊,把很多工作都做了。另外,vscode是个好工具,集成了C/C++插件鼠标点击到代码上就可以展开,微软工具还是说不错,毕竟“宇宙第一ide”是来自微软vs。...另外就是英文网址搜索了,bing,google等等我博客之前也是收集过。x macro好像还没有中文名称,又有点也有缺点,其中缺点就是不宜看懂,功力差点,估计看不懂,需要多看几遍就看懂了。...其中定义添加了可变参数功能,__VA_ARGS__,网上直接搜索“”可变参数“”,中文英文都很多,所以这个功能国内开发人员是用很多。这里就不展开了。...都知道c++是有模板,那么c语言可以模仿c++模板,至少是简易版本模板,提高了开发效率。

46720

C++使用QtSLOT须要注意一个小细节

大家都知道C++虚函数机制,对于基类定义为虚函数地方,子类假设覆写,基类指针或者引用来指向子类时候会实现动态绑定。...但假设指针去调用非虚函数,这个时候会调用C++静态绑定,去推断当前指针是什么类型,就去运行哪个类型函数。...但在使用QtSLOT时候,会出现一个问题须要注意,就是connect时候,你给当前子类对象child设置了SLOT,但这个基类实现过,举个样例 Class Base : public...myConnect,this指针表示你在当前Base类,这个时候非常自然去调用Base::say(),一開始可能这样写为了自己主动连接和断除比較方便,可是假设你写了继承子类,你非常自然去覆写了...say这个函数,而且认为既然不是虚函数,没什么须要操心,你可能会去用Child去连接别的对象,心理还在想着Basesay实现方法(由于我记得我当初链接信号时候写是Base,而且我如今没实用指针和引用

94420

DEBUG=1 定义对 @weakify 和 @strongify 影响分析

知识一、Debug 配置默认添加了 DEBUG=1 定义 知识二、是否存在 DEBUG=1 完全由开发者决定,不受其它因素影响 如何查看当前配置 点击项目名称弹出框,点击 Edit Scheme...如何调整当前配置 以 Run 为例,模态视图中,点击 Build Configuration 右侧 Debug 就可以切换配置 ?...DEBUG=1 定义对 @weakify 和 @strongify 有什么影响 如下:示例代码定义了一个 block,该 block 用于判断入参 obj 是否和 foo、far 其中任何一个对象相等并返回...理想情况时,Xcode 依然编译错误。但是,现实往往是残酷,Xcode 只提供了一个未使用变量警告⚠️。 ?...移除 DEBUG 定义后,rac_keywordify 被定义为 #define rac_keywordify try { } @catch(...) {},经预处理器处理后,会转换为下面的代码

74741

从零开始学C++之从C到C++(一):const与#define、结构体对齐、函数重载name mangling、newdelete 等

“它被拿来和谁比较” 此外,定义常量还可以用enum,c++ 尽量用const、enum替换#define定义常量,用inline 替换带参数定义;但 #define 底层编程是必不可少...参数定义意义就很清楚了,查看下输出即可。 我们知道printf函数带有可变参数,函数式定义也可以带可变参数,同样是参数列表中用...表示可变参数。...printf("x>y") : printf("x is %d but y is %d", x, y)); 定义,可变参数部分用__VA_ARGS__表示,实参对应...几个参数可以看成一个参数替换到定义...(四)、域运算符 C++增加作用域标识符 :: 用于对与局部变量同名全局变量进行访问 用于表示类静态成员,以后讲到类时候再详谈 (五)、new、delete 运算符 (1)、new...extern “C” 可以实现C与C++混合编程,被extern "C" 修饰变量和函数是按照C语言方式进行编译和链接,即对C语言写函数不进行改名,一般 C头文件中使用,如果头文件被C代码包含并用

1.2K00

C语言边角料-01

结构体 data 成员是一个指针变量,需要单独为它申请一块空间才可以使用。而且结构体使用之后,需要先释放 data,然后释放结构体指针 ams,顺序不能错。这样使用起来,是不是有点麻烦?...这里示例大家多多体会,很多通讯类处理场景,常常见到这种用法。 2....不定参数定义 定义参数个数可以是不确定,就像调用 printf 打印函数一样,定义时候,可以使用三个点(...)来表示可变参数,也可以在三个点前面加上可变参数名称。...看一下扩展之后代码(__VA_ARGS__为空): printf("hello \n",); 看出问题了吧?格式化字符串后面多了一个逗号!...为了解决问题,预处理器给我们提供了一个方法:通过 ## 符号把这个多余逗号给自动删掉。 于是定义改成下面这样就没有问题了。 #define debug3(format, ...)

46020

避免这7个误区,才能让【】削铁如泥

,通过主体编写不平衡开放括号,可以创建一个从主体内部开始但在主体外部结束调用。...运算符优先级问题 大多数定义示例,每次出现参数名称都带有括号,并且另一对括号通常会包围整个定义,这是编写最好方式。...例如计算foo(z)值时,将其保存在变量,然后min中使用该变量: //假设foo返回int类型 #define min(X, Y) ((X) < (Y) ?...* x) →(2 *(4 + y)) 当每个出现在另一个定义时,它们将被展开,但是当它间接出现在其自己定义时,则不会被展开。...如果按照给定方式替换了参数,并且没有进行扫描,则剩余单个扫描将找到相同调用并产生相同结果。 扫描处理以下三种特殊情况下有大作用。

1.2K20
领券