将指针作为函数参数传递并在C中返回的基本原理

时间:2011-09-09 19:53:32

标签: c pointers

我正在检查bkhive的源代码(用C语言编写) - 一个用于从Windows NT / 2K / XP系统配置单元转储SysKey启动密钥的实用程序 - 并且想知道是否存在任何理由原作者做了:将指向struct的指针传递给函数,然后返回相同的指针。以下是相关的源代码:

main()中有一个看起来像这样的电话:

struct hive h;
char *root_key;
// Do some stuff to init
_RegGetRootKey(&h, &root_key)

哪个电话:

int _RegGetRootKey(struct hive *h, char **root_key)
{
    nk_hdr *n;
    n = (nk_hdr*) malloc(sizeof(nk_hdr));

    /* ************************************************
     * RELEVANT FUNCTION CALL
     * Why pass n as a parameter and use return value?
     * ************************************************/
    n = read_nk(n, h, 0x1020);

    if (n->id == NK_ID && n->type == NK_ROOT)
    {
        *root_key = (char *) malloc(n->name_len + 1);
        strncpy(*root_key, n->key_name, n->name_len);
        (*root_key)[n->name_len] = 0;
        free(n);
        return 0;
    }
    free(n);
    return -1;
}

哪个电话:

nk_hdr* read_nk(nk_hdr *nk, struct hive *h, int offset)
{
    memcpy(nk, h->base + offset + 4, sizeof(nk_hdr));
    nk->key_name = (h->base + offset + 4 + 76);
    return nk;
}

那么,传递struct指针然后返回它的目的是什么?该函数无法返回任何内容并在函数调用后使用n

3 个答案:

答案 0 :(得分:4)

此约定的主要好处是允许更简单的函数调用串联。如果要将一个函数的返回作为参数返回到另一个函数,让它返回指针可以使您能够在一行中编写语句。因此,而不是写这样的东西:

foo(myPtr);
bar(myPtr);

你可以这样做:

bar(foo(myPtr));

您显示的特定代码不使用此代码,但这是许多C函数中使用的约定,我想这个代码的作者现在已经习惯了。

答案 1 :(得分:1)

这允许您通过引用传递对象,然后在返回时获取更新值的句柄(即指针)...它还允许您在出现错误时传回NULL,以便您知道您通过引用传入的对象的状态不再好。例如:

struct my_struct* pass_by_ref = malloc(sizeof(my_struct));
//...some more code

if (foo(pass_by_ref) == NULL)
{
    free(pass_by_ref); //pass_by_ref is no longer any good ...
    perror();
}

答案 2 :(得分:1)

在这种情况下,似乎没有多大用处。但总的来说,我过去做过同样的事情有两个原因:

一个是函数可能重新分配指向的项的位置,在这种情况下,返回可以是传递的相同指针,或者可以用不同的值替换它。

另一个,即使指针不会改变,它也允许函数返回立即用于访问指向项目,如somefunc(item)->member = 5;等结构。它允许您将函数调用放入另一个需要相同指针的表达式中。

也可能只是让函数的使用与API中的其他函数一致,其中一些可能有理由这样做。