【问题标题】:array of pointers as function parameter指针数组作为函数参数
【发布时间】:2010-12-15 16:46:08
【问题描述】:

我有一个关于 C/C++ 中的数组和指针的基本问题。

说我有:

Foo* fooPtrArray[4];

如何将fooPtrArray 传递给函数? 我试过了:

int getResult(Foo** fooPtrArray){}  //  failed
int getResult(Foo* fooPtrArray[]){} // failed

如何处理指针数组?

编辑:我曾经认为错误消息是由于传递了错误的指针数组,但从所有的响应中,我意识到这是别的东西......(指针分配)

Error msg:
Description Resource Path Location Type incompatible types in assignment of 
`Foo**' to `Foo*[4]' tryPointers.cpp tryPointers line 21 C/C++ Problem

我不太明白为什么它说:Foo* * to Foo*[4]。如果作为函数参数它们相互交换,为什么在赋值过程中会出现编译错误?

我尝试用最少的代码复制错误消息,如下所示:

#include <iostream>

using namespace std;

struct Foo
{
int id;
};

void getResult(Foo** fooPtrArray)
{
cout << "I am in getResult" << endl;
Foo* fooPtrArray1[4];
fooPtrArray1 = fooPtrArray;
}

int main()
{
Foo* fooPtrArray[4];
getResult(fooPtrArray);
}

【问题讨论】:

  • 定义“失败”。编译时失败?在运行时?如何,确切地(或模糊地,我​​不介意)?
  • 我附上了我的修剪代码,这是编译时错误。错误来自函数内部 void getResult(Foo* * fooPtrArray)

标签: c++ arrays function pointers


【解决方案1】:

两个

int getResult(Foo** fooPtrArray)

int getResult(Foo* fooPtrArray[])

还有

int getResult(Foo* fooPtrArray[4])

可以很好地工作(它们都是等效的)。

从您的问题中不清楚是什么问题。什么“失败”了?

当传递这样的数组时,传递元素计数通常也是有意义的,因为允许数组类型延迟为指针类型的技巧通常专门用于允许传递不同大小的数组

int getResult(Foo* fooPtrArray[], unsigned n);
...
Foo* array3[3];
Foo* array5[5];
getResult(array3, 3);
getResult(array5, 5);

但是,如果您总是要传递严格限制为 4 个元素的数组,那么使用不同类型的指针作为参数可能会更好

int getResult(Foo* (*fooPtrArray)[4])

在后一种情况下,函数调用如下所示

Foo* array[4];
getResult(&array);

(注意&amp; 运算符应用于数组对象)。

最后,由于这个问题被标记为 C++,在后一种情况下,也可以使用引用而不是指针

int getResult(Foo* (&fooPtrArray)[4]);
...
Foo* array[4];
getResult(array);

【讨论】:

  • 这看起来很有趣:int getResult(Foo* (*fooPtrArray)[4]) 带有两个星号和一对括号。对吗?
  • 是的,没错。但是在 C++ 中,在这种情况下,引用(而不是指针)可能更合适(请参阅答案中的附加 cmets)。
  • 能否详细说明Foo* (&amp;fooPtrArray)[4] 是如何被解析的,以及如何从函数体内调用fooPtrArray?
  • @splicer:fooPtrArray 在这种情况下是 对数组的引用,其中包含指向 Foo 的 4 个指针。在函数内部,它将以“通常”的方式使用,例如fooPtrArray[3] = 0。这与第一组变体没有什么不同,除了保留数组类型(不衰减为指针),这意味着您可以执行 sizeof fooPtrArray / sizeof *fooPtrArray 并得到 4 作为结果。同样,此参数仅与 4 元素参数兼容。
【解决方案2】:

您使用以下行声明的内容:

Foo* fooPtrArray[4];

是指向Foo 对象的指针数组(换句话说,是Foo* 的数组)。

在 C/C++ 中,数组的名称被定义为指向数组开头的指针。这是因为数组不是这些语言中的“真实”类型,而只是内存中特定类型的连续值序列。

在这种情况下,名称fooPtrArray 将是数组中的“指向第一个指针的指针”,它是存储指针数组的内存位置的开始。

因此,您上面概述的任何一个函数原型都应该可以工作。但是,当将数组传递给函数时,您总是需要同时传递大小,以便函数知道其中有多少元素。所以你应该像这样定义你的方法:

int getResult(Foo** fooPtrArray, int arraySize);

在此函数中,您可以访问数组中的各个 Foo 指针(以及随后的 Foo 对象),如下所示:

for (int i=0; i < arraySize; i++)
{
    Foo* fooPtr = fooPtrArray[i];
    if (fooPtr)
    {
        fooPtr->memberFunction();
        fooPtr->memberVariable;
    }
}

【讨论】:

    【解决方案3】:

    这两个函数签名看起来都应该可以工作。调用函数时,你会做这样的事情:

    int returnValue;
    returnValue = getResult(fooPtrArray);
    

    【讨论】:

      【解决方案4】:

      上面的编译OK:

      http://codepad.org/KOcnpmtv

      第二个也可以:

      http://codepad.org/7OSqprYI

      【讨论】:

        【解决方案5】:

        如果没有返回 int ,我看不出它如何编译?!

        @Kinopiko 你的代码不能用 C++ 编译。

        @Lily 你得到的错误信息是什么? 在您的示例中,getResult 需要返回一个 int。这可能是失败的原因。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-26
          • 2021-11-29
          • 2011-02-04
          • 2012-03-07
          • 1970-01-01
          相关资源
          最近更新 更多