【问题标题】:C function to a macroC函数到宏
【发布时间】:2013-08-26 07:42:50
【问题描述】:

我需要在 C 中编写宏而不是函数

函数如下:

void FSTATUS(int stat,char msg[])
{
    if(stat != 0)
    {
        EMH_ask_error_text(stat, &msg);
        printf("Error : \"%d\",\"%s\"\n",stat,msg);
    }
    else 
        printf("\n -------- %s -------- \n",msg);
}

由于如何在宏中使用 if 语句的示例非常少,因此我被困在这部分中,我无法弄清楚如何将其转换为宏。任何人都可以帮我解决上面的代码。

解决方案:

我使用内联函数而不是宏

【问题讨论】:

  • 是什么让你觉得这需要一个宏???
  • 我需要将其作为宏调用以减少编译时间
  • 哦,你不会减少编译时间,如果你使用宏,你可以增加它。请记住,宏在编译之前会扩展到您的源代码中。
  • 为什么不简单地使用inline
  • 嘿内联也是一个不错的选择!谢谢@perror!

标签: c function macros


【解决方案1】:

我相信,正确的格式会有很大的不同。这就是为什么我总是对齐\'s。

#define FSTATUS(stat, msg)                                \
do                                                        \
{                                                         \
    if ((stat) != 0)                                      \
    {                                                     \
        EMH_ask_error_text((stat), &(msg));               \
        printf("Error : \"%d\",\"%s\"\n", (stat), (msg)); \
    }                                                     \
    else                                                  \ 
    {                                                     \
        printf("\n -------- %s -------- \n", (msg));      \
    }                                                     \
}                                                         \
while (0)

重要提示:确保行尾的\ 后面没有空格。空格“打破”换行符。

当然你也可以这样做:

#define FSTATUS(s, m) ((s) ? (EMH_ask_error_text((s), &(m)), printf("Error : \"%d\",\"%s\"\n", (s), (m))) : printf("\n -------- %s -------- \n", (m)))

这里逗号操作符用作if-block 中两个语句之间的分隔符。

【讨论】:

    【解决方案2】:
    #define FSTATUS(stat, msg) do \
    { \
        if((stat) != 0) \
        { \
            EMH_ask_error_text(stat, &(msg)); \
            printf("Error : \"%d\",\"%s\"\n",stat,msg); \
        } \
        else  \
            printf("\n -------- %s -------- \n",msg); \
    } while (0)
    

    注意使用do { ... } while (0) 以确保它在if/else 之间正常工作。

    还要注意在某些地方使用额外的括号以避免statmsg 是表达式时出现问题。

    当然要非常注意宏的所有缺陷——除非你有充分的理由,否则你真的不应该使用这种类型的函数宏。理想情况下,如果性能确实很关键,您应该使用内联函数,否则就坚持使用普通函数。

    【讨论】:

    • 感谢您的回答。我传递的参数是 int stat 和 char msg[] 即一个数组。那么我该如何传递一个数组??
    • 我试过 #define FSTATUS(int stat,char[] msg) 但它显示语法错误
    • @Neal:对于宏,您没有指定参数类型 - 因此您显然会丢失使用函数获得的类型检查。提供正确的论点取决于您。一般来说,这种类型的宏是一个坏主意(出于这个原因和许多其他原因),但希望你知道你在做什么......
    • 我想知道为什么 do-while 循环是必要的。你能解释一下吗?
    • @lulyon do while 循环让您可以做两件事: 1. 将宏调用写成带有 ; 的常规函数​​调用。最后,没有关于空语句的警告; 2.(在这种情况下不适用)如果您有任何仅在宏主体内需要的局部变量,它会为您提供一个块范围来定义它们。
    【解决方案3】:
    #define FSTATUS(stat,msg) \
    do {                       \
        if(stat != 0)           \
        {                        \
            EMH_ask_error_text(stat, &msg);  \
            printf("Error : \"%d\",\"%s\"\n",stat,msg); \
        }  \                     \
        else \
            printf("\n -------- %s -------- \n",msg);\
    }while(0)
    

    只需要将函数类型改为宏即可。如果你想知道为什么需要添加 do {.. } while(0) ,你可以参考这个:http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon

    【讨论】:

    • 你少了几个\s
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多