尝试传递结构数组,但出现“无法将'struct'转换为'struct *'的错误

时间:2018-08-25 17:58:30

标签: c++ arrays data-structures parameter-passing

当我尝试将此结构数组传递到函数AthleticContest()中时,我不断收到此错误:

  

无法将“人”转换为“人*”

有人可以告诉我我做错了什么吗?我在函数中传递了错误的信息吗?

struct person
{
    int athletic;
    int smarts;
    int spirit;
    int contestVal;
};

int AthleticContest(person subjects[])
{
     cout << "Athletic Contest!!!" << endl << endl;
     for (int hh = 0; hh < 3; hh++)
     {
         int result = subjects[hh].athletic;
         subjects[hh].contestVal = result;
         cout << "Contestant # " << (hh+1) << ") " << subjects[hh].contestVal  << endl;
     }
     int winner;
     int tempWin = -1;
     for (int hh = 0; hh < 3; hh++)
     {
        if (subjects[hh].contestVal > tempWin)
        {
            tempWin = subjects[hh].contestVal;
            winner = hh;
        }
        else if (subjects[hh].contestVal == tempWin)
        {
            if (randomInt() > 4)
                winner = hh;
        }
    }
    cout << "Winner is Contestant # " << (winner+1)   << endl;

    return winner;
}

int main()
{
    person subject[10];

    subject[0].athletic = 5;
    subject[0].smarts   = 3;
    subject[0].spirit   = 1;
    subject[1].athletic = 1;
    subject[1].smarts   = 3;
    subject[0].spirit   = 5;
    subject[1].athletic = 3;
    subject[1].smarts   = 5;
    subject[0].spirit   = 1;

    AthleticContest(subject[2]);
}

2 个答案:

答案 0 :(得分:4)

错误

main()中调用函数时:

    AthleticContest(subject[2]);

您将单个person作为参数传递,它是数组的第三个元素(索引为2的元素)。因此,编译器理解您尝试传递此类型为person的对象。

但是函数的参数声明为大小不确定的数组类型(即person[])。 C ++将此类数组参数视为它们的指针(指向其第一个元素),就像person*一样。

这就是为什么您收到此错误消息的原因:这些类型不兼容

解决方案

要摆脱此错误,一种解决方法是将指针传递到subject,例如:

    AthleticContest(&subject[2]);  // passes the pointer to the third element
    // or 
    AthleticContest(subject);  // passes the pointer to the first element of the original array

但是,要非常小心,因为您的函数的设计风险很大:您希望参数是指向至少3个连续元素的数组的指针。因此,如果您使用&subject[8]进行调用,它将尝试访问subject[10],这将超出范围。如果您使用&subject[2]进行调用,它将使用garbege信息,因为您只初始化了前两个元素,而不是第3,第4和第6个元素。

更好的解决方案

目前尚不清楚,为什么只用3个元素来做constest。更好的选择是调用方说要使用多少个参赛者(调用方知道数组的大小)。

main()中:

    AthleticContest(subject, 2);  // 2 is the number of contestants in array

您的函数将定义为:

int AthleticContest(person subjects[], int participants)
{
     cout << "Athletic Contest!!!" << endl << endl;
     for (int hh = 0; hh < participants; hh++)
     ... 
     for (int hh = 0; hh < participants; hh++)
     ...
}

更好的解决方案

您最好选择std::vector而不是C ++数组。它们的行为类似于数组:

    vector<person> subject(2);  // create a vector of 2 items
    subject[0].athletic = 5;
    ...

但是它们更加方便,因为它们可以动态变化并随着您添加新参与者而增长:

    person hbolt = {4, 2, 1, 0}; 
    subject.emplace_back (hbolt);   // one more participant
    AthleticContest(subject);

您的函数可以通过引用或值来获取向量。让我们参考一下,因为您打算修改其内容,并且可能希望在返回后使用此修改后的数据:

int AthleticContest(vector<person> &subjects)
{
    ...
}

最大的优点是,您始终可以知道向量的大小:

for (int hh = 0; hh < subjects.size(); hh++)
...

这里是online demo

当然,如果您不想接受向量中的所有参与者,则必须考虑函数的参数:您是否希望第二个参数n并始终采用n个第一个元素向量?还是您希望n个参与者但以任意偏移量开始?在这两种情况下,明智的做法是检查索引是否永不超出范围。

答案 1 :(得分:0)

您需要更改以进行编译的一件事:您正在将 reference 传递给数组的单个元素,而不是数组本身。

您可能还要检查的另一件事是更改AthleticContest()的签名,以便它在C ++中成为接收固定大小的数组或person作为参数的正确选择。

固定编译后,您的代码如下所示:

#include <iostream>

using namespace std;

struct person
{
    int athletic;
    int smarts;
    int spirit;
    int contestVal;
};

template <std::size_t size>
int AthleticContest(person (&subjects)[size])
{
    cout << "Athletic Contest!!!" << endl << endl;
     for (int hh = 0; hh < 3; hh++)
     {
         int result = subjects[hh].athletic;
         subjects[hh].contestVal = result;
         cout << "Contestant # " << (hh+1) << ") " << subjects[hh].contestVal  << endl;
     }
     int winner;
     int tempWin = -1;
     for (int hh = 0; hh < 3; hh++)
     {
        if (subjects[hh].contestVal > tempWin)
            {
             tempWin = subjects[hh].contestVal;
             winner = hh;
            }
            else if (subjects[hh].contestVal == tempWin)
            {
             if (5 > 4)
             winner = hh;
            }
      }
        cout << "Winner is Contestant # " << (winner+1)   << endl;

    return winner;
}

int main()
{
    person subject[10];

    subject[0].athletic = 5;
    subject[0].smarts   = 3;
    subject[0].spirit   = 1;
    subject[1].athletic = 1;
    subject[1].smarts   = 3;
    subject[0].spirit   = 5;
    subject[1].athletic = 3;
    subject[1].smarts   = 5;
    subject[0].spirit   = 1;

    AthleticContest(subject);
}