Попытка передать массив структур, но я получаю "не могу преобразовать" struct "в ошибку" struct * " - PullRequest
0 голосов
/ 25 августа 2018

Я получаю эту ошибку, когда пытаюсь передать этот массив структур в функцию 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 голосов
/ 25 августа 2018

Одна вещь, которую вам нужно изменить для компиляции: вы передаете ссылку на один элемент массива вместо самого массива.

Еще одна вещь, которую вы можете проверить, это изменить свою подпись на 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);
}
0 голосов
/ 25 августа 2018

Ошибка

Когда вы вызываете свою функцию в 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 элементами. Лучшим вариантом было бы, чтобы вызывающая сторона указала, сколько участников должно использоваться (вызывающая сторона знает размер массива).

In 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++)
...

Вот демоверсия онлайн .

Конечно, если вы не хотите брать всех участников вектора, вам нужно подумать об аргументе (ах) вашей функции: вы бы предпочли второй аргумент n и всегда принимали n первых элементов вектор? Или вы предпочитаете n участников, но начинаете с произвольного смещения? В обоих случаях было бы разумно проверить, чтобы индексирование никогда не выходило за пределы.

...