1

以下代码是否可移植?

我只是按值传递指针,我可以在调用者中更改它!

void foo(void *p)
{
    void **pp = (void**)p;
    *pp = "hahaha";
}

int main(int argc,char **argv)
{
    void *p = NULL;
    p = &p;
    printf("%p\n",p);
    foo(p);
    printf("%s\n",(char *)p);     // hahaha
    printf("%p\n",p);

    return 0;
}
4

3 回答 3

4

是的,您可以更改指针指向的内容,但您只能这样做,因为您已将指针指向自身

p = &p;

要回答您的问题,是的,这是便携式的;但不,这通常不是一个好主意。

于 2010-12-29T00:54:32.123 回答
3

您总是通过值传递指向指针的指针,使其在将其分配给自身以及将其传递给函数时看起来像是单个指针;它之所以有效,只是因为您使该指针指向自身。

你在做什么基本上是这样的:

void foo(void **p)
{
    *p = "hahaha";
}

int main(int argc,char **argv)
{
    void *p = NULL;
    printf("%p\n", &p);
    foo(&p);
    printf("%s\n",(char *)p);     // hahaha
    printf("%p\n", p);
    return 0;
}

添加了一些演员表和技巧。我会说“黑暗中的纸牌技巧”,绝对不是一个好主意,放入一个真正的程序。

要实际回答这个问题:是的,它应该是可移植的,因为标准保证每个数据指针都可以void *毫无问题地转换为 a 和从 a 转换(这是您在代码中一直所做的):

指向的指针void可以转换为指向任何不完整或对象类型的指针或从指针转换。指向任何不完整或对象类型的指针可以转换为指向void 和返回的指针;结果应与原始指针比较。

(C99,§6.3.2.3.1)

于 2010-12-29T00:56:29.920 回答
2

您实际上是在玩指向指针的指针。您仍然按值传递指针,并且不会欺骗编译器来更改调用者的值。您要更改的只是指针指向的值。

除了让自己和其他程序员感到困惑之外,在现实生活中使用并不是一个好主意。

于 2010-12-29T00:58:38.610 回答