C语言中do...while(0)用法小结
在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个:
本文地址:http://www.cnblogs.com/archimedes/p/do-while-0.html,转载请注明源地址。
1、避免goto语句:
通常,如果一个函数开始要分配一些资源,然后如果在中途遇到错误则要退出函数,当然,退出前要释放资源,我们的代码可能如下:
#defien N bool Execute()
{
// 分配资源
int *p = (int *)malloc(N * sizeof(int));
bool bOk = true; // 执行并进行错误处理
bOk = func1();
if(!bOk)
{
free(p);
p = NULL;
return false;
} bOk = func2();
if(!bOk)
{
free(p);
p = NULL;
return false;
} bOk = func3();
if(!bOk)
{
free(p);
p = NULL;
return false;
} // .......... // 执行成功,释放资源并返回
free(p);
p = NULL;
return true;
}
这里最大的问题是代码冗余,每增加一个操作,就要做相应的错误处理,非常不灵活,于是想到了一下的goto:
#defien N bool Execute()
{
// 分配资源
int *p = (int *)malloc(N * sizeof(int));
bool bOk = true; // 执行并进行错误处理
bOk = func1();
if(!bOk) goto errorhandle; bOk = func2();
if(!bOk) goto errorhandle; bOk = func3();
if(!bOk) goto errorhandle; // .......... // 执行成功,释放资源并返回
free(p);
p = NULL;
return true; errorhandle:
free(p);
p = NULL;
return false;
}
代码冗余是解决了,但是引入了C语言中比较微妙的goto语句,虽然正确的使用goto语句可以大大提高程序的灵活性与简洁性,但是会使我们的程序捉摸不定,为了既避免使用goto语句,又能消除代码冗余,可以考虑使用下面的 do...while(0):
#defien N bool Execute()
{
//分配资源
int *p = (int *)malloc(N * sizeof(int));
bool bOK = true; do {
//执行并进行错误处理
bOK = fun1();
if(!bOK) break; bOK = fun2();
if(!bOK) break; bOK = fun3();
if(!bOK) break; //.........
} while(); //释放资源 free(p);
p = NULL;
return bOK;
}
2、避免空声明在编译时出现警告:
在linux内核源代码中,经常看到如下宏以避免在编译时出现警告:
#define FOO do { } while(0)
3、编写符合习惯的代码块:
你可能经常会使用如下的宏:
#define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }
然而在某些情况下将会失效,下面的代码使用if...else...
if (x > y)
exch(x,y); // 分支 1
else
do_something(); // 分支 2
但是将被解释为一个分支的if语句:
if (x > y) {
int tmp;
tmp = x;
x = y;
y = tmp;
}
; // 空语句
else // ERROR!!!
do_something();
错误出在“;”直接位于代码块的后面,解决的办法是将代码嵌入do...while(0),于是得到下面的代码:
if (x > y)
do {
int tmp;
tmp = x;
x = y;
y = tmp;
} while();
else
do_something();
于是上面的宏可以修改为:
#define exch(x,y) do {\
int tmp;\
tmp = x;\
x = y;\
y = tmp;\
} while()
4、在条件语句中使用复杂的宏:
假如一个宏包含类似如下几行代码:
#define FOO(x) \
printf("arg is %s\n", x); \
do_something_useful(x);
现在想像一下下面的代码:
if (blah == )
FOO(blah);
这将解释为:
if (blah == )
printf("arg is %s\n", blah);
do_something_useful(blah);;
我们就会发现,if语句只作用于printf(), do_something_useful() 没按照愿意一起执行,即没有像你预期的那样被包含在if代码中,于是可以使用如下的代码块:
if (blah == )
do {
printf("arg is %s\n", blah);
do_something_useful(blah);
} while ();
这样上面的宏就可以改为:
#define FOO(x) do { \
printf("arg is %s\n", blah);\
do_something_useful(blah);\
} while ()
C语言中do...while(0)用法小结的更多相关文章
- C语言中system()函数的用法总结(转)
system()函数功能强大,很多人用却对它的原理知之甚少先看linux版system函数的源码: #include <sys/types.h> #include <sys/wait ...
- C语言中do...while(0)的妙用(转载)
转载来自:C语言中do...while(0)的妙用,感谢分享. 在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个: 1.避免goto语 ...
- C/C++语言中NULL、'\0’和0的区别
注:本文参考了http://blog.csdn.net/mylinx/article/details/6873253及书籍<征服C指针>([日]前桥和弥著). NULL.'\0'和0的值是 ...
- C语言中static关键字的用法
C记得还是大一时学的,现在觉得好久没用了,又捧起来看看.今天刚看到有关static关键字,仔细地看了一遍<C和指针>这本书中的解释,现在觉得清楚多了. 首先,我们将static关键字,修饰 ...
- C语言中的extern关键字用法
在C语言中,修饰符extern用在变量或者函数的声明前,用来说明“此变量/函数是在别处定义的,要在此处引用”. 1. extern修饰变量的声明.举例来说,如果文件a.c需要引用b.c中变量int v ...
- C语言中sprintf()函数的用法
sprintf函数的用法 1.该函数包含在stdio.h的头文件中. 2.sprintf和平时我们常用的printf函数的功能很相似.sprintf函数打印到字符串中,而printf函数打印输出到屏幕 ...
- C语言中strtod()函数的用法详解
函数原型: #include <stdlib.h> double strtod(const char *nptr, char **endptr); C语言及C++中的重要函数. 名称含义 ...
- R语言中的logical(0)和numeric(0)以及赋值问题
logical(0) 不等于 numeric(0).两者都不等于NULL值,即is.null(logical(0))和is.null(numeric(0))返还值都是FALSE.这很有意思,说明长度为 ...
- C语言中do...while(0)的妙用
在linux内核代码中,经常看到do...while(0)的宏,do...while(0)有很多作用,下面举出几个: 1.避免goto语句: 通常,如果一个函数开始要分配一些资源,然后如果在中途遇到错 ...
随机推荐
- AVL树(一)之 图文解析 和 C语言的实现
概要 本章介绍AVL树.和前面介绍"二叉查找树"的流程一样,本章先对AVL树的理论知识进行简单介绍,然后给出C语言的实现.本篇实现的二叉查找树是C语言版的,后面章节再分别给出C++ ...
- Robot Framework自动化测试(五)--- 开发系统关键字
最近一直在用robot framework 做自动化测试项目,老实说对于习惯直接使用python的情况下,被框在这个工具里各种不爽,当然,使用工具的好处也很多,降低了使用成本与难度:当然,在享受工具带 ...
- UITextField-secureTextEntry
1.UITextFiled的密文输入 secureTextEntry 安全文本输入 secure:安全 Entry:入口
- C#语法糖之 cache操作类 asp.net
因为考虑到我下面我将写session cookies 等 操作类 ,与cache具有共性. 所以都统一继承了IHttpStorageObject abstract class 来保函数风格的统一 , ...
- 转载:第五弹!全球首个微信小程序(应用号)开发教程!通宵吐血赶稿,每日更新!
博卡君今天继续更新,忙了一天,终于有时间开工写教程.不罗嗦了,今天我们来看看如何实现一些前端的功能和效果. 第八章:微信小程序分组开发与左滑功能实现 先来看看今天的整体思路: 进入分组管理页面--&g ...
- WebApi 集成 Swagger
1. Swagger(俗称:丝袜哥)是什么东西? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同 ...
- ThroughRain第二次冲刺总结
团队名:ThroughRain 项目确定:<餐厅到店点餐系统> 项目背景:本次项目是专门为餐厅开发的一套订餐系统.大家有没有发现在节假日去餐厅吃饭会超级麻烦,人很多, 热门的餐厅基本没有座 ...
- 使用Swift操作NSDate类型基础
时间类型是我们在处理业务的时候使用非常频繁的一个数据类型.下面我们看一下时间NSDate的基本使用方法. 1.比较大小 我比较擅长.NET,我们知道C#里面DateTime类型可以使用"&g ...
- HTML5 Audio and JavaScript Control
IE8 以下无效 <!DOCTYPE html> <html> <head> <meta content="text/html; charset=u ...
- 解决死锁SQL
USE [master]GO/****** Object: StoredProcedure [dbo].[p_lockinfo] Script Date: 04/03/2014 15:12:40 ** ...