关于C语言的一些trick
很多东西已经记不起来了,想到一点写一点,碰到一点写一点,慢慢累积。
关于#
#在宏定义中用于替换传入变量的字符,例如: #define whole_operation(n) do { printf(#n "=%d\n", (n));} while(0);
调用whole_operation(5*6), 输出:5*6=30, 有助于增加输出的可读性。
关于##
##是c99中定义的用于粘连两个符号,标识符或参数。例如:#define name_index(index) name_##index
调用name_index(1),则生成name_1变量, 所以很多时候##用于动态的调用标识符具有一定规律的函数,宏或者变量。
举个列子,如果现在有add_arg_1(), add_arg_2()两个函数,只有在运行时才知道调用哪个函数,那么可以使用如下代码:
#define call_add_arg(argc) add_arg_##argc()
IPnet的log模块中,因为log级别不同而log级别的前几个标识符都是IPCOM_LOG_,所以采用IPCOM_LOG_##x的方式在运行是判断需要输出什么级别的log。
关于不定参数...
很久以前在防火墙上做log模块的时候,用到一个比较有意思的trick。因为log要接收不同模块的不同信息,但是每个模块都含有自己独特的信息,为了保证所有信息都能被log接受,当时用了不定参的函数作为log的接口log(msgid, ...),通过va_list ap; va_start(ap, firstarg); va_arg(ap, type);va_end(ap);的方式来接受传入的各个参数。事实上,大多数prinf也是通过这个方式实现。 但是这种方式的函数调用容易出问题, 函数不知道什么时候参数结束,有可能导致程序崩溃。
C99定义了__VA_ARGS__ 用于接受不定参数的宏:#define LOG(msgid, ...) log(msgid, __VA_ARGS__, lastarg) 或者#define LOG(msgid, arg...) log(msgid, arg, lastarg) lastarg是预定义的用于标识结束的宏或变量, 若不用__VA_ARGS__,则需用arg...来替代。 这样,LOG函数就可以接受任意多1个以上参数而不需要关系什么时候结束。那么如果LOG调用时只有一个msgid参数,就会变成log(msgid,,lastarg),这时候就需要借助##的另一个作用,如果##,后面没有参数,那么逗号就会被省略,于是LOG函数的最终定义变成: #define LOG(msgid, ...) log(msgid, ##__VA_ARGS__, lastarg)
关于C语言的一些trick的更多相关文章
- 编写高质量代码 改善Python程序的91个建议 (读后 小记)
此书是自己好久之前买的,当时总觉得Python语言中有各种trick, 总是要自己猝不及防的掉入到陷阱之中, 看了一些资料后发现了这本书,感觉很是不错,不过可惜自己平时总是杂事太多,总是找不到整块的时 ...
- C语言全局变量那些事儿
转自:http://blog.csdn.net/bingqingsuimeng/article/details/9405743 作为一名程序员,如果说沉迷一门编程语言算作一种乐趣的话,那么与此同时反过 ...
- C语言printf()函数:格式化输出函数
C语言printf()函数:格式化输出函数 头文件:#include <stdio.h> printf()函数是最常用的格式化输出函数,其原型为: int printf( char ...
- 漫谈C语言及如何学习C语言
抄自:http://my.oschina.net/apeng/blog/137911 目录:[ - ] 为什么要学习C语言? C语言学习方法 1,参考书籍 2,动手实验环境搭建 3,网络资源 附录 一 ...
- C语言 goto, return等跳转
C语言 goto, return等跳转 Please don't fall into the trap of believing that I am terribly dogmatical about ...
- [转贴]漫谈C语言及如何学习C语言
抄自http://my.oschina.net/apeng/blog/137911,觉得很有用,收藏它 目录:[ - ] 为什么要学习C语言? C语言学习方法 1,参考书籍 2,动手实验环境搭建 3, ...
- 文本挖掘预处理之向量化与Hash Trick
在文本挖掘的分词原理中,我们讲到了文本挖掘的预处理的关键一步:"分词",而在做了分词后,如果我们是做文本分类聚类,则后面关键的特征预处理步骤有向量化或向量化的特例Hash Tric ...
- 基于python语言的tensorflow的‘端到端’的字符型验证码识别源码整理(github源码分享)
基于python语言的tensorflow的‘端到端’的字符型验证码识别 1 Abstract 验证码(CAPTCHA)的诞生本身是为了自动区分 自然人 和 机器人 的一套公开方法, 但是近几年的 ...
- C语言函数实现的另类方法
在前面看过那个BT的Javascript程序后,我们来看一个C语言的,相信大家还记得输出从1到1000的数最后的那个示例,本站还有很多这样的示例,如:变态的hello word,如何教新手编程,还有恐 ...
随机推荐
- Java 中Iterator 、Vector、ArrayList、List 使用深入剖析
标签:Iterator Java List ArrayList Vector 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构.这些 ...
- Windows Phone开发需要了解的背景
在Windows Phone8.1之前,Windows Phone应用是基于Silverlight的,这些代码也不能在Windows上运行,从Windows Phone8.1开始,开发者多了一个选择, ...
- 【three.js详解之一】入门篇
[three.js详解之一]入门篇 开场白 webGL可以让我们在canvas上实现3D效果.而three.js是一款webGL框架,由于其易用性被广泛应用.如果你要学习webGL,抛弃那些复杂的 ...
- mysqlnd cannot connect 连接错误处理方法
mysqlnd cannot connect to MySQL 4.1+ using the old insecure authentication. Please use an administra ...
- Disable the screen switching about VI
If you want to disable the screen switching, and you don't want tochange your termcap, you can add t ...
- linux命令:du
1.命令介绍: du用来查看文件和目录的使用空间. 2.命令格式: du [选项] 文件 3.命令参数: -a或-all 显示目录中个别文件的大小. -b或-bytes 显示目录或文件大小时,以b ...
- codeforces 341d (树状数组)
problem Iahub and Xors 题目大意 一个n*n的矩阵,要求支持两种操作. 操作1:将一个子矩阵的所有值异或某个数. 操作2:询问某个子矩阵的所以值的异或和. 解题分析 由于异或的特 ...
- JavaScript设计模式学习笔记
1 JavaScript设计模式深入分析 私有属性和方法:函数有作用域,在函数内用var 关键字声明的变量在外部无法访问,私有属性和方法本质就是你希望在对象外部无法访问的变量. 特权属性和方法:创建属 ...
- python自动化框架nose
python除了unittest,还有一款更快捷的nose,nose可以说是对unittest的一种简化吧 但是他不需要unittest那种必须有固有的格式,他只需要文件,类名,方法名等含有test就 ...
- Thread1:EXC_BAD_ACCESS 错误
描述:野指针,在对象被释放之后又调用了该对象 场景:在某个UIVIewController释放之后有调用了该Controller的某些方法. 由于项目需求需要监控WebView的滚动,所以在控制器中给 ...