问题引出:

我们都知道宏定义#define只是简单替换,所以遇到复杂的带参数宏,必须很小心的为需要的参数加上括号“()”;同样碰到复杂的多条语句替代,虽然加{}可以将其封装成一个整体,但同时又有另一个问题:与语法习惯的冲突。比如:

#include <stdio.h>

void print_1(void)
{
 printf("print_1\n");
}

void print_2(void)
{
 printf("print_2\n");
}

#define  printf_value()    \
  {     \
  print_1();   \  
  print_2();

}

int main( void )
{
 int i=0;
 if(i==1)
 
 else
  printf("add else word!!!");printf_value();

return 0;
}

上面的经过编译后会报错:if与else不匹配。怎么可能?将宏带入发现“printf_value();”后面确实多了一个分号,从而导致if与else的不匹配。但是去掉又不和c语言的习惯,因为C规定每条语句后面必须加分号。

  所以解决的办法就是用do{}while(0)同样只执行一次,且将其看成一个整体,同时又兼容了C的习惯,一举多得

二 用define重定义中断向量:在stm32中的中断函数比如串口中断如果你要用define重定义,然后需要将在stm32fnxx_it.c中包含相应的头文件否则容易出错

C语言-define 与do{}while(0)的更多相关文章

  1. C/C++编程笔记:C语言NULL值和数字 0 值区别及NULL详解

    在学习C语言的时候,我们常常会碰到C语言NULL值和数字 0 ,很多小伙伴搞不清楚他们之间的一个区别,今天我们就了解一下他们之间的区别,一起来看看吧! 先看下面一段代码输出什么: 输出<null ...

  2. #define SIG_DFL ((void(*)(int))0)

    在linux内的信号处理函数中,有#define SIG_DFL ((void(*)(int))0)和#define SIG_IGN ((void(*)(int))1)两个宏定义.要理解这两个宏定义, ...

  3. #define xxx do{...} while(0) 宏定义

    linux内核和其他一些开源的代码中,经常会遇到这样的代码: do{ ... }while(0) 这样的代码一看就不是一个循环,do..while表面上在这里一点意义都没有,那么为什么要这么用呢? 实 ...

  4. C语言变长数组data[0]总结

    C语言变长数组data[0] 1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内 ...

  5. vs2010编译zapline-zapline.systemoptimization 注释工程中的//#define abs(value) (value >= 0 ? value : -(value))即可

    vs2010编译zapline-zapline.systemoptimization-8428e72c88e0.zip出错 1>d:\program files (x86)\microsoft ...

  6. C# 语言规范_版本5.0 (第17章 特性)

    1. 特性 C# 语言的一个重要特征是使程序员能够为程序中定义的实体指定声明性信息.例如,类中方法的可访问性是通过使用 method-modifiers(public.protected.intern ...

  7. C# 语言规范_版本5.0 (第2章 词法结构)

    1. 词法结构 1.1 程序 C# 程序 (program) 由一个或多个源文件 (source file) 组成,源文件的正式名称是编译单元 (compilation unit)(第 9.1 节). ...

  8. C 语言 define 变参__VA_ARGS__使用

    在C语言的标准库中,printf.scanf.sscanf.sprintf.sscanf这些标准库的输入输出函数,参数都是可变的.在调试程序时,我们可能希望定义一个参数可变的输出函数来记录日志,那么用 ...

  9. 第三课,T语言数据类型(版本TC5.0)

    数据类型 TC综合开发工具里使用的是可变类型,就是在程序执行过程中,TC综合开发工具会自动把数据转换为需要的类型,转换失败会出现相应的提示但是在一些特殊的场景下,是需要做类型强制处理,那么这时就需要使 ...

随机推荐

  1. 小程序websocket用法

    // socket已经连接成功 var socketOpen = false // socket已经调用关闭function var socketClose = false // socket发送的消 ...

  2. linux中systemctl详细理解及常用命令

    linux中systemctl详细理解及常用命令 https://blog.csdn.net/skh2015java/article/details/94012643 一.systemctl理解 Li ...

  3. Oracle 11G在用EXP 导入、导出时,若有空表对导入导出中遇到的问题的解决

    11G中有个新特性,当表无数据时,不分配segment,以节省空间 解决方法: 1.insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segmen ...

  4. PMP概略学习上--基本思想和概念

    1 前言 花了10天左右的时间,对PMP(Project Management Professional,项目管理专业人士)考试认证做了一个概略学习.此次学习的目的是整体了解项目管理知识,并不是以考试 ...

  5. CefApp和CefClient的作用

    CefApp 在cefsimple中,提到了一个cefapp的类型,这个类型是一个接口类,主要目的是提供获取三种handler的接口 /// // Implement this interface t ...

  6. Oracle 11G统计信息自动收集及调整

    查询统计信息的收集所对应的task,以及当前状态 col CLIENT_NAME for a50col TASK_NAME for a20SELECT client_name, task_name, ...

  7. 截取字符,超出的用省略号代替js实现 substring

    可用到截取文字过多的问题,取0到6之间的字符,不包含6title.substring(0,6)+'...';

  8. OO博客作业-《JML之卷》

    OO第三单元小结 一.JML语言理论基础以及应用工具链情况梳理 一句话来说,JML就是用于对JAVA程序设计逻辑的预先约定的一种语言,以便正确严格高效地完成程序以及展开测试,这在不能容忍细微错误的工程 ...

  9. Spring - jdbcTemplate - 调试代码: PreparedStatementCreator 生成的语句, update 之后没有 自增id, 已解决

    1. 概述 解决 jdbcTemplate 下, update 结果不带 自增id 的问题 2. 场景 看书 Spring in Action 5th 3.1.4 listing 3.10 saveT ...

  10. JEECG屏蔽在线聊天插件

    如图所示: 找到pom.xml文件将如下代码屏蔽即可: <!-- 在线聊天工具 --> <dependency> <groupId>org.p3framework& ...