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 10bool 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; }
View Code
这里最大的问题是代码冗余,每增加一个操作,就要做相应的错误处理,非常不灵活,于是想到了一下的goto:
#defien N 10bool 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; }
View Code
代码冗余是解决了,但是引入了C语言中比较微妙的goto语句,虽然正确的使用goto语句可以大大提高程序的灵活性与简洁性,但是会使我们的程序捉摸不定,为了既避免使用goto语句,又能消除代码冗余,可以考虑使用下面的 do...while(0):
#defien N 10bool 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(0);//释放资源 free(p);p = NULL;return bOK; }
View Code
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(0); elsedo_something();
于是上面的宏可以修改为:
#define exch(x,y) do {\int tmp;\tmp = x;\x = y;\y = tmp;\} while(0)
4、在条件语句中使用复杂的宏:
假如一个宏包含类似如下几行代码:
#define FOO(x) \printf("arg is %s\n", x); \do_something_useful(x);
现在想像一下下面的代码:
if (blah == 2)FOO(blah);
这将解释为:
if (blah == 2)printf("arg is %s\n", blah);do_something_useful(blah);;
我们就会发现,if语句只作用于printf(), do_something_useful() 没按照愿意一起执行,即没有像你预期的那样被包含在if代码中,于是可以使用如下的代码块:
if (blah == 2)do {printf("arg is %s\n", blah);do_something_useful(blah);} while (0);
这样上面的宏就可以改为:
#define FOO(x) do { \printf("arg is %s\n", blah);\do_something_useful(blah);\} while (0)
C语言中do...while(0)用法小结相关推荐
- scanf在c语言中的作用,c语言中scanf的基本用法
前言 scanf()是C语言的格式输入函数,和printf函数一样被声明在stdio.h头文件中,它的基本使用很简单: 1 int a; 2 scanf("%d",&a); ...
- c语言中 char怎样用,C语言中char*和char[]用法区别分析
C语言中char*和char[]用法区别分析 本文实例分析了C语言中char* 和 char []的区别.分享给大家供大家参考之用.具体分析如下: 一般来说,很多人会觉得这两个定义效果一样,其实差别很 ...
- C语言中atoi()函数的用法
C语言中atoi()函数的用法 一.学习要点: 1.int atoi(const char *str)把参数str所指向的字符串转换为一个整数: 二.代码 #include<stdio.h> ...
- python语言中with as的用法使用详解
本篇文章主要介绍了python语言中with as的用法使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 With语句是什么? 有一些任务,可能事先需要设置,事后做 ...
- c语言memcopy_C语言中memcpy 函数的用法详解
C语言中memcpy 函数的用法详解 memcpy(内存拷贝函数) c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址 ...
- c语言time函数的作用,c语言中time函数的用法
c语言中time函数的用法 c语言中time函数的用法的用法你知道吗?下面应届毕业生小编就跟你们详细介绍下c语言中time函数的用法的用法,希望对你们有用. c语言中time函数的用法的用法如下: 头 ...
- c语言sinx的作用,C语言中 sinx cosx 的用法
#include #include int main() { double pi=acos(-1.0); double angle; scanf("%lf",&angle) ...
- div c语言,c语言中的div的用法是什么?
c语言中的div的用法: 函数名: div 功 能: 将两个整数相除, 返回商和余数 用 法: div_t (int number, int denom); 程序例: # include #inclu ...
- 在c语言中for的作用,c语言中for语句的用法
C语言语言中FOR的用法 for 是一个循环语句,和while是类似的,for一般的用法有: for(i=0;i<10;i++) { printf("hello world" ...
最新文章
- 学习webpack记录(一)
- Notepad++V6.8.1.0中文版
- 深入浅出Mybatis系列(八)---mapper映射文件配置之select、resultMap good
- Shell脚步学习指南提点
- PHP $_SERVER详解
- 机器学习第五回——学习方法与学习曲线
- Ubuntu终端快捷复制粘贴
- .net core mvc中使用ef
- Base64 混淆加密+迭代次数,Base64前后端加解密不一致、Base64 js加解密结果与java加解密结果不一致,Base64中文加密乱码
- 语音识别入门第七节:语言模型
- KISSY基础篇乄KISSY之IO(1)
- Spark Scala当中reduceByKey(_+_) reduceByKey((x,y) => x+y)的用法
- 分享些发表技术类文章的平台
- #1082 : 然而沼跃鱼早就看穿了一切
- Android Adapter接口的实现类总结
- js替换关键词为链接,只替换一次,要避开超链接或图片
- vscode json文件配置
- 复旦大学游记(r10笔记第88天)
- Netty的UDP广播发送与接收
- 线性代数 or 量子力学 ? (外传:傅里叶级数 与 傅里叶变换学习笔记)