如何从C中的函数返回多个值

时间:2014-04-02 04:43:12

标签: c pointers

为什么main中的指针不会更新为以'xavier'开头的字符串而不是返回其初始值!

这是我的功能:

char * getValue(char * tag, char * query)
{
    char * end = strstr(query, "&");
    while (* query != '=')
    {
        query++;
    }

    query++;
    // print the query string after the pointer has been incremented through while loop

    printf("%s \n", query);

    // get the size of the substring I want
    int size = strlen(query) - strlen(end);
    printf("%d \n", size);

    // allocate memory for it and link it to pointer 'value'
    char * value = malloc(sizeof(char) * (size + 1));
    memcpy(value, query, size);
    value[size] = '\0';

    printf("%s \n", value);
    return value;
}

int main(int argc, char * argv[])
    {
    char * tag = "Username=";
    char * query = "Username=Xavier&Password=Bachelor&Submit=+Create";

    char * value = getValue(tag, query);
    // Username=Xavier&Password=Bachelor&Submit=+Create This is the result after the f() of the printf
    // Xavier&Password=Bachelor&Submit=+Create This is what I want...
    printf("%s \n", query);

    return EXIT_SUCCESS;
    }

6 个答案:

答案 0 :(得分:2)

您是否尝试使用其他对象? 具有许多属性的Object。因此,当您返回一个对象时,您可以获取或设置许多值

答案 1 :(得分:1)

您没有从函数中捕获返回值。你可以做......

printf("%s \n", getValue(tag, query));

答案 2 :(得分:1)

C语言有"传递值"函数参数的语义。

执行main函数时

getValue(tag, query)

参数表达式 tagquery减少到它们的值。这些值现在与它们来自的变量分离:这些值的副本进入函数,在那里它们用于初始化参数tagquery

char * getValue(char * tag, char * query) { ... }

这些参数与tag函数中的querymain无关,即使它们具有相同的名称。这些参数是getValue函数的局部变量,与value变量和end变量完全相同。与valueend类似,它们是在函数开始执行时新创建的。与valueend不同,它们是特殊的:作为参数,它们使用从main接收的参数值进行初始化。当getValue返回时,所有这些局部变量都被销毁(尽管不是它们所指向的!)。

当你递增query指针时,你只是改变了局部变量,当该函数完成时它就消失了。

您的程序也会泄漏内存:getValue函数会分配空间并使用value局部变量来跟踪此空间并将一些字符存储到其中。然后它通过return value语句返回该指针。此时,getValue函数停止执行,value变量不再存在,但malloc的内存继续存在:指针值从函数返回。然后,先前挂起的main函数继续执行,但是,它会忽略getValue调用返回的值。该内存已无法访问:程序已丢失其从malloc获取的指针的最后一个剩余副本,并且根本无法引用该内存,更不用说使用free释放它了功能。这种情况被称为"内存泄漏"。

答案 3 :(得分:1)

C++中你可以在函数定义中使用变量的地址而不是变量,就像这样

char * getValue(char * tag, char * &query)

在普通C中,您只能使用指向指针的指针来实现相同的功能:

char * getValue(char * tag, char ** query)

当然,在功能budy中你应该使用dereference,例如。使用*query代替query,您应该将此函数称为getValue(tag, &query)

答案 4 :(得分:1)

要修改参数,需要将指针传递给要修改的值。

  1. 由于您想要修改指针,您需要将指针传递给指针
  2. 这更多是一个观点问题,但许多程序员认为使用参数有点难看。它可能导致难以理解的代码。为了缓解这种情况,参数名称应反映出它的含义,例如,如下所示。
  3. 通常,总是让任何指针参数成为指向 const 的指针,除非您确实需要修改它指向的内容。使用字符串尤其重要,因为字符串文字是只读的,并且通常指向字符串文字的指针是const。如果你的函数接受指向非const的指针,那么你应该得到编译器警告或错误(取决于你究竟做了什么)。
  4. 由于问题代码中至少未使用tag,因此您应该收到编译器警告(如果不这样做,则应该发出警告!)。
  5. 修复所有这些功能:

    char * getValue(const char * tag, const char **query_in_out)
    {
        (void)tag; // remove compiler warning about unused parameter
    
        char * end = strstr(*query_in_out, "&");
        while (**query_in_out != '=')
        {
            (*query_in_out)++;
        }
    
        (*query_in_out)++;
        // print the (*query_in_out) string after the pointer has been incremented through while loop
    
        printf("%s \n", *query_in_out);
    
        // get the size of the substring I want
        int size = strlen(*query_in_out) - strlen(end);
        printf("%d \n", size);
    
        // allocate memory for it and link it to pointer 'value'
        char * value = malloc(sizeof(char) * (size + 1));
        memcpy(value, *query_in_out, size);
        value[size] = '\0';
    
        printf("%s \n", value);
        return value;
    }
    

    通过传递要修改的指针的地址进行调用:

    char * value = getValue(tag, &query);
    

    PS。如上所述,C字符串文字通常是只读的,所以你应该真的这样:

    const char * tag = "Username=";
    const char * query = "Username=Xavier&Password=Bachelor&Submit=+Create";
    

    这样,你可以修改这些指针,使它们指向不同的东西(比如你的getValue函数),但你不能不小心修改它们指向的数据(这会使程序崩溃)字符串文字,在现代操作系统上。)

答案 5 :(得分:0)

如果要返回多个值,则必须定义结构并返回该类型的对象。

我认为你在你的计划中混淆了。你可能想在main中这样做。

query = getValue(tag, query);

如果您没有捕获返回值,您希望如何更新任何内容?