关于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,如何教新手编程,还有恐 ...
随机推荐
- 1、C#基础:变量、运算符、分支、循环、枚举、数组、方法 <转>
转自:海盗船长 链接:http://www.cnblogs.com/baidawei/p/4701504.html#3241882 C#..Net以及IDE简介 一.什么是.Net? .Net指 .N ...
- HTMlhleper
@{ ViewBag.Title = "Index";} <h2>Index</h2> <div> @{ int id=12121; var I ...
- HTML 5 <script> 标签
HTML 4.01 与 HTML 5 之间的差异 async 属性是 HTML 5 中的新属性. 在 HTML 5 中,不再支持 HTML 4.01 中的一些属性. 提示和注释 注释:脚本按照如下方式 ...
- Android Studio 2.2.2 发布
Android Studio 2.2.2 发布了.包括 canary, dev, beta, and stable 这几个系列. 该版本修复了 Android Studio 2.2.1 中排名较前的b ...
- javascript学习之【new操作符】
首先请大家思考这么一段代码,如下: <script>var jquery=function(){ console.log(this);};jquery();new jquery() ...
- 通过a++来理解闭包改变作用域的问题
纯属个人理解,如果有误请指出! 让我们先看一段代码 function dog(){ var a=100; a++; return a; } alert(dog()); alert(dog()); 我们 ...
- 在win7环境下安装python2.6.6
Python2.x与3.x语法并不相同,这里装的是2.6.6的版本. 1.下载Python2.6.6: https://www.python.org/downloads/ 根据自身计算机的特点选择Py ...
- A Simple Problem with Integers_树状数组
Problem Description Let A1, A2, ... , AN be N elements. You need to deal with two kinds of operation ...
- XML代码生成器——XMLFACTORY 简介(四)
XML代码生成器——XMLFACTORY 简介(四) 这一篇我们讲“类属性”页签的配置功能,您将了解到:如何为元素子值指定类属性的名称,数据类型,及容器类型. 如果,你没看过这个系列的第一篇文章,请先 ...
- Tableview RefreashControl 下拉之后马上返回
Tableview RefreashControl 下拉之后马上返回 原因很简单: 我把 [self.tableView setContentInset:UIEdgeInsetsMake(0, 0, ...