【问题标题】:Returning a Character String from #define Function从#define 函数返回一个字符串
【发布时间】:2013-12-17 23:54:11
【问题描述】:

我知道你可以从 C 中的普通函数返回一个字符串,就像这段代码一样

#include <stdio.h>

char* returnstring(char *pointer) {
    pointer="dog";
    return pointer;
}

int main(void)
{
    char *dog = NULL;
    printf("%s\n", returnstring(dog));
}

但是,我找不到能够在 #define 函数中返回字符串的方法,就像这段代码中一样

#include <stdio.h>

#define returnstring(pointer) { \
   pointer="dog"; \
   return pointer; \
}

int main(void)
{
    char *dog = NULL;
    printf("%s\n", returnstring(dog));
}

我知道有一些解决方法(比如使用第一个程序)。我只想知道有没有可能

【问题讨论】:

  • 简短回答:你不能。不要混淆,类宏函数的行为不像函数。

标签: c string function c-preprocessor


【解决方案1】:

IMO 认为“#define 函数”是错误的处理方式。

#define 是一种钝器,相当于文本查找/替换。它对 C++ 作为一门语言几乎一无所知,并且替换是在您查看任何真实代码之前完成的。

你写的不是一个函数,它是一段看起来像一个的文本,它放在你写别名的地方。

如果你想#define 你刚刚做了什么,那很好(我没有专门检查你的例子,但一般来说,使用#define 进行函数调用并替换参数是可能的),但在做之前三思而后行所以除非你有一个惊人的理由。然后再考虑,直到你决定不这样做。

【讨论】:

    【解决方案2】:

    您不能从宏中“返回”。你最好的(呃......可以说是“最好的”,但无论如何)的赌注是以这样一种方式制定你的宏,它评估你想要成为结果的表达式。例如:

    #define returnstring(ptr) ((ptr) = "hello world")
    
    const char *p;
    printf("%s\n", returnstring(p));
    

    如果你有多个表达式语句,你可以用可怕的逗号分隔它们:

    #define even_more_dangerous(ptr) (foo(), bar(), (ptr) = "hello world")
    

    如果您使用的是 GCC 或兼容的编译器,您还可以利用称为“语句表达式”的 GNU 扩展来将整个(非表达式)语句嵌入到您的宏中:

    #define this_should_be_a_function(ptr) ({ \
        if (foo) { \
            bar(); \
        } else { \
            for (int i = 0; i < baz(); i++) { \
                quirk(); \
            } \
        } \
        ptr[0]; // last statement must be an expression statement \
    })
    

    但如果你到了这一点,你真的可以只写一个适当的函数。

    【讨论】:

      【解决方案3】:

      #defined 宏不会返回任何内容。粗略地说,C 预处理器将宏调用替换为宏体的文本,并将参数文本替换为它们的位置。如果您希望宏将指针分配给"dog" 并计算指针,您可以这样做:

      #define dogpointer(p) ((p)="dog")
      

      【讨论】:

        【解决方案4】:

        问题是returnstring,因为宏没有按照它说的去做;它还将值分配给参数。该函数按照它说的做,即使它(有点奇怪)使用它的参数作为临时变量。

        函数相当于:

        char* returnstring(char *ignored) {
            return "dog";
        }
        

        函数宏与:

         #define returnstring(pointer) pointer = "dog"
        

        这引出了问题,为什么不叫它assign_string

        或者为什么不直接拥有:

          #define dogString "dog"
        

        然后写:

        int main(void)
        {
            char *dog = NULL;
            printf("%s\n", dog = dogString);
        }
        

        assignString 的函数是:

        char* assignstring(char **target{
            *target= "dog";
            return *target;
        }
        

        然后你可以有一个宏:

        assign_string_macro(pointer) assignstring(&pointer)
        

        最终,如果您想“在#define 函数中返回字符串”,那么您只需要:

        #define returnstring(ignored) "dog"
        

        【讨论】:

          猜你喜欢
          • 2013-04-14
          • 1970-01-01
          • 2011-09-04
          • 2012-03-30
          • 2014-01-30
          • 1970-01-01
          • 2012-02-26
          • 1970-01-01
          相关资源
          最近更新 更多