【问题标题】:Macro in C to call a function returning integer and then return a stringC中的宏调用一个返回整数的函数,然后返回一个字符串
【发布时间】:2015-01-23 02:20:57
【问题描述】:

我有一个返回整数值的函数。现在我想编写一个宏来调用这个函数,获取返回值并在其前面添加一个字符串并返回结果字符串。

我试过这个:

#define TEST(x)        is_enabled(x)

我在主函数中称这个宏为:

int ret = 0;
ret = TEST(2);
printf("PORT-%d\n", ret);

这非常有效。但是我希望宏返回字符串 PORT-x,其中 x 是被调用函数的返回值。我该怎么做?

编辑:

我也试过把它写成多行:

#define TEST(x)\
{\
    is_enabled(x);\
}

并在main函数中调用为:

printf("PORT-%d\n", TEST(2));

但这会产生编译时错误:

error: expected expression before â{â token

【问题讨论】:

  • 这可以通过编写一个“调用”sprintf 的宏来完成,但是您需要分配一个缓冲区并将其传递给该宏。问题是,你为什么要这样开始?因为感觉就像你试图以错误的方式解决问题。
  • 为什么不能使用strcat?为什么需要宏?
  • 你绝对应该为此编写一个函数...
  • @Gopi 我不想改变底层函数来返回一个字符串,所以我想出了一个想法,用宏来修改这个函数的输出。有那么难吗?

标签: c function macros


【解决方案1】:

使用函数,而不是宏。这里没有充分的理由使用宏。

您可以通过使用sprintf(3) 与 malloc 或缓冲区结合来解决它。有关详细信息,请参阅 Creating C formatted strings (not printing them) 或手册页。

关于您的编辑:您不需要在宏中使用大括号 {},它们会导致您的错误,因为预处理会将其转换为类似

printf("format%d", {
  is_enabled(x);
}); 

为了更好地理解宏,使用 -E 标志运行 gcc 或 clang,或者尝试阅读这篇文章:http://en.wikipedia.org/wiki/C_preprocessor

【讨论】:

  • 最后,我在函数中实现了这一点,而不是编写宏。
【解决方案2】:

这有点麻烦,因为您需要确保字符串有存储空间。老实说,现在的宏只能用于条件编译。

常量最好使用枚举类型,而宏函数通常作为内联函数更好(知道inline 是编译器的建议,而不是要求)。

如果您坚持使用宏,则可以使用静态存储来完成存储,尽管如果您使用线程会出现问题,并且会延迟/多次使用返回的字符串。

您也可以动态分配字符串,但必须在完成后释放它,并处理内存不足的情况。

也许最简单的方法是要求宏用户提供自己的存储,大致如下:

#include <stdio.h>

#define TEST2_STR(b,p) (sprintf(b,"PORT-%d",p),b)

int main (void) {
    char buff[20];
    puts (TEST2_STR(buff, 42));

    return 0;
}

哪个输出:

PORT-42

如果宏看起来有点混乱,它会使用逗号运算符,其中表达式(a, b) 计算ab,结果为b

在这种情况下,它评估sprintf(填充缓冲区)然后“返回”缓冲区。而且,即使你认为以前从未见过,你也可能错了:

for (i = 0, j = 9; i < 10; i++, j--)
    xyzzy[i] = plugh[j];

尽管大多数人认为这是 for 的一个功能,但它是一个非常不同的结构,可以在许多不同的地方使用:

int i, j, k;
i = 7, j = 4, k = 42;

while (puts("Hello, world"),sleep(1),1);

(等等)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 1970-01-01
    • 2012-03-30
    • 2015-02-03
    • 1970-01-01
    相关资源
    最近更新 更多