gpt4 book ai didi

你想知道的do{...}while(0)的作用,都在这里了

转载 作者:我是一只小鸟 更新时间:2023-02-21 22:31:06 30 4
gpt4 key购买 nike

0、引言        

        我们在嵌入式开发的过程中,经常可以碰到在一些 宏定义 或者是代码段中使用了do {...} while(0)的语句,从语义上理解,do {...} while(0)内的逻辑就只执行一次,并没有循环执行,粗略看来,似乎画蛇添足了,那么为什么还需要在只执行一次的逻辑外面加上一层do {...} while(0)语句呢?实际上,在这些逻辑中使用do {...} while(0)的作用远大于美化你的代码,下面就来看看实际的使用场景.


1、用于定义一个作用域,避免替换的时候出错

        我们都知道,在程序中如果一些常量参数或者代码语句反复出现,就可以使用宏定义来替代。预处理阶段,对程序中所有出现的“宏名”,预处理器都会用宏定义中的字符串替代,这称为“宏替换”或“宏展开”.

        这样做可提高程序的通用性和易读性,减少不一致性,一个较好的宏名可以更好的让读者理解常量参数的含义;同时程序易于修改,我们仅需要改变一个宏定义,就可以改变整个程序中出现的所有该常量或者语句.

        但是有时可能程序代码段中, 出现多条语句重复连续的使用, 这样我们就可以尝试使用一个复杂的宏来替换。你有可能会这样定义:

                          
                            1
                          
                          
                            #define
                          
                           REPLACE_FUN() funA(); funB()
                        

   本意是在程序中当出现funA()和funB()多条语句连续使用时,使用REPLACE_FUN()来替换.

                              
                                1
                              
                              
                                if
                              
                              
                                (判断条件)

                              
                              
                                2
                              
                                   REPLACE_FUN();
                            

        但是实际上在预处理的时候,宏展开替换后变成了:

                              
                                1
                              
                              
                                if
                              
                              
                                (判断条件)

                              
                              
                                2
                              
                              
                                   funA();

                              
                              
                                3
                              
                               funB();   
                              
                                //
                              
                              
                                此处funB()一定会执行,造成逻辑错误
                              
                            

        可以看出,funB()不会按照判断条件才去执行。而是变成了一条独立的语句,而如果在宏中使用括号:

                              
                                1
                              
                              
                                #define
                              
                               REPLACE_FUN() {funA(); funB();}
                            

        我们一般的代码习惯都会在语句的末尾加上分号,因此也会出错

                              
                                1
                              
                              
                                if
                              
                              
                                (判断条件)

                              
                              
                                2
                              
                              
                                    REPLACE_FUN();

                              
                              
                                3
                              
                              
                                //
                              
                              
                                宏展开后为:
                              
                              
                                4
                              
                              
                                if
                              
                              
                                (判断条件)

                              
                              
                                5
                              
                              
                                {

                              
                              
                                6
                              
                              
                                    funA();

                              
                              
                                7
                              
                              
                                    funB();

                              
                              
                                8
                              
                               };    
                              
                                //
                              
                              
                                此处替换后多一个分号;导致编译报错
                              
                            

        因此,针对这种多条重复语句的连续使用,如果想用宏替换实现这个作用域的功能,就可以考虑使用do {...} while(0)语句:

                              
                                 1
                              
                              
                                define REPLACE_FUN() \

                              
                              
                                 2
                              
                              
                                do
                              
                              
                                { \

                              
                              
                                 3
                              
                              
                                            funA();\

                              
                              
                                 4
                              
                              
                                            funB();\

                              
                              
                                 5
                              
                                         }
                              
                                while
                              
                              (
                              
                                0
                              
                              
                                )\

                              
                              
                                 6
                              
                              
                                //
                              
                              
                                宏展开前为:         
                              
                              
                                 7
                              
                              
                                if
                              
                              
                                (判断条件)

                              
                              
                                 8
                              
                              
                                    REPLACE_FUN();

                              
                              
                                 9
                              
                              
                                //
                              
                              
                                宏展开后为:
                              
                              
                                10
                              
                              
                                if
                              
                              
                                (判断条件)

                              
                              
                                11
                              
                              
                                do
                              
                              
                                {

                              
                              
                                12
                              
                              
                                          funA();

                              
                              
                                13
                              
                              
                                          funB();

                              
                              
                                14
                              
                                    }
                              
                                while
                              
                              (
                              
                                0
                              
                              );    
                              
                                //
                              
                              
                                根据判断条件,正确执行了一次逻辑
                              
                            


2、避免goto语句的使用

         goto语句 也称为无条件转移语句,使用后可以从多重循环或者多个判断中直接跳出。对于如下例子:

                              
                                 1
                              
                              
                                void
                              
                               fun(
                              
                                int
                              
                              
                                 a)

                              
                              
                                 2
                              
                              
                                {

                              
                              
                                 3
                              
                              
                                if
                              
                              (
                              
                                1
                              
                               ==
                              
                                 a)

                              
                              
                                 4
                              
                              
                                   {

                              
                              
                                 5
                              
                                      ...
                              
                                //
                              
                              
                                todo
                              
                              
                                 6
                              
                              
                                goto
                              
                              
                                 exit;

                              
                              
                                 7
                              
                              
                                   }  

                              
                              
                                 8
                              
                              
                                if
                              
                              (
                              
                                2
                              
                               ==
                              
                                 a)

                              
                              
                                 9
                              
                              
                                   {

                              
                              
                                10
                              
                                    ...
                              
                                //
                              
                              
                                todo
                              
                              
                                11
                              
                              
                                goto
                              
                              
                                 exit;

                              
                              
                                12
                              
                              
                                   }

                              
                              
                                13
                              
                              
                                exit:

                              
                              
                                14
                              
                                  ...
                              
                                //
                              
                              
                                todo
                              
                              
                                15
                              
                                  printf(
                              
                                "
                              
                              
                                a is error
                              
                              
                                "
                              
                              
                                \n);

                              
                              
                                16
                              
                               }
                            

        但是为了程序结构的清晰,还是要尽量限制goto语句的使用, 我们可以使用do {...} while(0)结构配合break跳出单层的循环的方法来替代这种goto的用法.

                              
                                 1
                              
                              
                                int
                              
                               fun(
                              
                                int
                              
                              
                                 a)

                              
                              
                                 2
                              
                              
                                {

                              
                              
                                 3
                              
                              
                                do
                              
                              
                                {

                              
                              
                                 4
                              
                              
                                if
                              
                              (
                              
                                1
                              
                               ==
                              
                                 a)

                              
                              
                                 5
                              
                              
                                       {

                              
                              
                                 6
                              
                                        ...
                              
                                //
                              
                              
                                todo
                              
                              
                                 7
                              
                              
                                break
                              
                              
                                ;

                              
                              
                                 8
                              
                              
                                       }  

                              
                              
                                 9
                              
                              
                                if
                              
                              (
                              
                                2
                              
                               ==
                              
                                 a)

                              
                              
                                10
                              
                              
                                       {

                              
                              
                                11
                              
                                        ...
                              
                                //
                              
                              
                                todo
                              
                              
                                12
                              
                              
                                break
                              
                              
                                ;

                              
                              
                                13
                              
                              
                                       }

                              
                              
                                14
                              
                                  }
                              
                                while
                              
                              (
                              
                                0
                              
                              
                                );

                              
                              
                                15
                              
                                  ...
                              
                                //
                              
                              
                                todo
                              
                              
                                16
                              
                                  printf(
                              
                                "
                              
                              
                                a is error
                              
                              
                                "
                              
                              
                                \n);

                              
                              
                                17
                              
                               }
                            

3、定义一个单独的函数块来实现复杂的操作

        当某个函数程序功能较为复杂,在该函数的代码段中如果不再单独定义一个函数实现部分逻辑,可以 使用do {...} while(0)作为一个代码块,将想要实现的逻辑放在do {...} while(0)中, 同时在该在do {...} while(0)代码块中定义的变量,可以不用考虑和函数之前或者之后的变量名重复冲突的问题。但是为了代码的易读性,还是尽量声明不同的变量名.

                              
                                 1
                              
                              
                                int
                              
                              
                                 a;

                              
                              
                                 2
                              
                              
                                char
                              
                              
                                 b;

                              
                              
                                 3
                              
                              
                                int
                              
                              
                                 func()

                              
                              
                                 4
                              
                              
                                {

                              
                              
                                 5
                              
                              
                                int
                              
                               a = 
                              
                                3
                              
                              
                                ;

                              
                              
                                 6
                              
                              
                                char
                              
                               b = 
                              
                                5
                              
                              
                                ;

                              
                              
                                 7
                              
                              
                                do
                              
                              
                                {

                              
                              
                                 8
                              
                              
                                int
                              
                              
                                 a;

                              
                              
                                 9
                              
                              
                                char
                              
                              
                                 b;

                              
                              
                                10
                              
                                       ......
                              
                                //
                              
                              
                                todo
                              
                              
                                11
                              
                                   }
                              
                                while
                              
                              (
                              
                                0
                              
                              
                                );    

                              
                              
                                12
                              
                               }
                            

4、避免空宏的警告

        有的时候,程序为了不同的平台移植或者不同架构的限制,很多时候会先定义空宏,后续再根据实际的需要看是否定义具体内容。但是在编译的时候,这些空宏可能会给出warning,为了避免这样的warning,我们可以 使用do{...}while(0)来定义空宏, 这种情况不太常见,因为有很多编译器已经支持空宏.

                              
                                1
                              
                              
                                //
                              
                              
                                空宏
                              
                              
                                2
                              
                              
                                #define
                              
                               EMPTY_FUN

                              
                                3
                              
                              
                                //
                              
                              
                                增加do{...}while(0)来定义空宏
                              
                              
                                4
                              
                              
                                #define
                              
                               EMPTY_FUN do{}while(0) 
                              
                                //
                              
                              
                                避免了可能的编译warning
                              
                            

更多技术内容和书籍资料获取,入群技术交流敬请关注“明解嵌入式” 。

​ 。

最后此篇关于你想知道的do{...}while(0)的作用,都在这里了的文章就讲到这里了,如果你想了解更多关于你想知道的do{...}while(0)的作用,都在这里了的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com