关于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,如何教新手编程,还有恐 ...
随机推荐
- 10款html5开发工具,实用+好用
利用HTML5工具不仅可以帮助设计师和开发者创建更具吸引力的网站,还能增加网站的可用性和可访问性.本文收集了10款HTML5开发工具让你在网页中搭建特效.动画.视频.音频等诸多功能,为你节省更多开发时 ...
- JSON介绍
JSONhttp://www.json.org/json-zh.html JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机 ...
- 简单的ATM,见笑见笑
#include<stdio.h>#include<string.h> void main(){ char a[4]={0}; char e[]="9527&quo ...
- iOS中AutoLayer自动布局流程及相关方法
关于UIView的Layer,IOS提供了三个方法: 1.layoutSubviews 在iOS5.1和之前的版本,此方法的缺省实现不会做任何事情(实现为空),iOS5.1之后(iOS6开始)的版本, ...
- JavaScript Module Pattern: In-Depth
2010-03-12 JavaScript Module Pattern: In-Depth The module pattern is a common JavaScript coding patt ...
- USBD_STATUS
USBD_STATUS 该USBD_STATUS数据类型为USB请求定义USB状态值. 的typedef LONG USBD_STATUS; USB状态值的最显著4位被如下表中所定义. 值 ...
- iOS学习之SKTagView的使用
SKTagView是一款支持自动布局的标签tag. 特性: -流式展示标签 -可以配置标签的颜色.事件.间隔.外边距等 -支持Auto layout -可以在UITableViewCell中良好展示 ...
- svg坐标系变换
svg的坐标变换有三个属性来决定:viewport, viewBox, 和 preserveAspectRatio,我发现三篇比较详细的博客,转载如下: 理解SVG坐标系和变换:视窗,viewBox和 ...
- WEB框架介绍
python web框架分类 自己实现socket Tornado 借助wsgi实现socket Django:因为Django用的wsgi,所以不用操作socket. wsgi有很多,如下, MV ...
- 新手码农浅谈观察者模式(java语言简单实现)
一:什么是观察者模式: 官方定义:定义对象间一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 举个例子,很多人都会订阅天气预报,当气象台获得明天的天气情况( ...