2

看看函数f中奇怪的一行:

typedef char thing[1];

void f(thing t){
    thing *p;

    /* Strange line. Changing t to  &t is wrong. 
       C++ require a (thing *) cast.
     */
    p = t;

    *(*p) = 'C';
}

int main(int argc, char* argv[])
{
    thing g;
    thing *h;

    /* Works as expected. */
    h = &g;  

    g[0] = 'A';
    *(*h) = 'B';
    f(g);

    /* g[0] is now  'C' */

    return 0;
}

将f更改为

void f(thing t){
    char **p; 
    p = &t; /* note the & */
    *(*p) = 'C';
}

也有效。

我期待p=&t的是正确的指示,而不是p=t。毕竟t是 athing并且&t必须是 a thing*

那条奇怪的线发生了什么?

4

4 回答 4

4

将数组作为参数传递时,它会衰减为指针。所以f实际上得到了一个char *.
然后您尝试取消引用它两次 - 您将其视为指向另一个指针的指针,该指针指向char. 不管你怎么做,这都行不通。
如果您不强制转换,C++(和 C,如果您启用警告)会告诉您有问题。如果您进行强制转换,您实际上是在告诉编译器忽略该错误。但这仍然是错误的。

于 2012-06-24T19:22:49.417 回答
2

不,t不是thing

作为形式参数,数组类型(但不是对数组的引用)衰减为指向第一个元素的指针,而函数类型衰减为指向函数的指针。

因此,在函数中,您不是获取数组的地址,而是获取指针变量的地址,这会产生指向指针的指针。

于 2012-06-24T19:29:59.577 回答
1

只是一个替代解决方案:

您可以通过引用传递数组来防止数组到指针的衰减。这应该可以按您的意愿工作:

void f(thing& t){
    thing *p;

    p=&t;

    *(*p)='C';
}
于 2012-06-24T19:35:33.243 回答
0

让我们逐行逐句理解,希望您不理解的任何内容都变得清晰:

void f(thing t){

在这里,您没有通过引用传递数组,因此它衰减为指向数组第一个元素的指针(tis a char *)。

thing *p;

这里,p是一个指向 1 个字符的数组的指针,所以char (*p) [1].

p=t;

现在您正试图将指向字符的指针分配给指向数组的指针。类型根本不匹配(我得到类似的东西invalid conversion from char * to char (*)[1])。

*(*p)='C';

这只是简单地取消引用p以获取实际的数组,然后将其衰减为指向要取消引用的第一个元素的指针,从而有效地为您提供第一个元素。


主要:

thing g;
thing *h

现在您无需处理将其传递给函数的问题。g是一个char [1]并且h是一个char (*)[1]

h=&g;  

h是指向数组的指针,g是数组。这很有意义。

g[0]='A';

g是一个数组;这很正常。

*(*h)='B';

在这里,您正在做与 中相同的事情f()


在修改后的函数
中:首先记住t是一个指向第一个元素的指针(char *

char * *p; 

p是指向 的指针char *

p=&t; /* note the & */

您将 a 的地址分配给char *指向 的指针char *。完全正常。

*(*p)='C';

*p取消引用p以获取char *( t)。另一个取消引用为您提供了 所指向的内容t,它是数组的第一个元素。

我希望这能消除任何困惑。

于 2012-06-24T19:47:28.770 回答