@chaikovskyiii

Как передать массив в функцию С++ ( пишет no matching function to call)?

void average (int *a){

}
int task3(){
    int start, rowCount, colCount;
    cout << "Enter 1 for inputting numbers from keyboard, or 2 for using random numbers: ";
    cin >> start;
    cout << "Enter the number of rows and columns" << endl << "Rows: ";
    cin >> rowCount;
    cout << "Columns: ";
    cin >> colCount;
    int a[rowCount][colCount];
    if (start == 1 ){
        for (int i=0; i<rowCount; i++)
            for (int j=0; j<colCount; j++)
            {cout << "a[" << i << "][" << j << "]="; cin >> a[i][j];}
    }
    else if (start == 2) {
        int Low = -100;
        int High = 100;
        srand((unsigned) time(NULL));
        for (int i = 0; i < rowCount; i++){
            for (int j = 0; j < colCount; j++)
                a[i][j] = Low + rand() % (High - Low + 1);}
        average(a);

    }
  • Вопрос задан
  • 333 просмотра
Решения вопроса 2
Adamos
@Adamos
Используя Кресты, стоит использовать и их удобства.
std::vector< std::vector< int > > a(rowCount, std::vector< int >(colCount, 0));
void average (std::vector< std::vector< int > > &a){

Так вы не нарветесь на промахи в индексах массива, например. Если умеючи.

А в вашем коде int[][], конечно, не может самопроизвольно превратиться в int*
Ответ написан
@res2001
Developer, ex-admin
Написал опус на вопрос, который вы удалили, хорошо сохранился в буфере обмена :-) а то было бы обидно.

Ваш массив пожно просто привести к указателю, по старинке (int*)a или используя касты.

Но у вас тут на самом деле 2 проблемы.
Первая - обращение к элементам массива в average используя [i][j]. Вторая - VLA.
По первой проблеме:
В С/С++ оператор индексации (array[i]) выполняет следующее действие: *(array+i).
Отсюда должно быть понятно, что раз array у вас это int*, то после array[i] вы получите int, от которого уже нельзя взять второй индекс, т.к. это просто 1 int, а не массив.

Отсюда есть несколько выходов:
1. дурацкий (самый долгий по исполнению и затратам памяти): использовать динамический массив массивов
Выглядит примерно так:
int **array = new int*[rowCount];
for(int i=0; i < rowCount; ++i)
   array[i] = new int[colCount];

Как видите array превратился в двойной указатель, теперь каждый элемент в первом измерении - это указатель на одномерный массив. Всего у вас получается rowCount + 1 выделений памяти. Не забудьте столько же раз вызвать оператор delete.
В average теперь передавайте int** и у вас будет работать оператор [][], т.к. первая индексация уже будет возвращать int*.
Не рекомендую использовать этотт способ.

2. Вычислять индекс массива вручную (не использовать индексацию):
*(array + i*colCount + j)
Это такой хардкорный стиль. Но зато работает быстро и масштабируется на массивы любой размерности без особых проблем.

3. использовать std::vector<std::vector<int>> - это то же самое, что и вариант 1, но закамуфлированный под вектор :-)

Вторая проблема это VLA (Variable Length Array).
Статические (автоматические) массивы в С++ вы можете определять, только константным размером (размером известным на этапе компиляции).
У вас же размерность массива динамическая (вводится пользователем во время выполнения программы). Отсюда следует, что вы должны использовать динамические массивы, выделенные с помощью new.
В стандарте С++ нет VLA. VLA есть только в Си и то начиная с С99.
Ваша функция task3 компилируется, только потому что в gcc/clang по умолчанию включены расширения. В расширения входит так же и возможность использовать VLA. Если задать опциями более строгое соответствие стандарту С++, то функция не соберется.
И кстати, например в микросовтовский компилятор VLA до сих пор не завезли.

Но если уж у вас есть VLA, то вы можете преобразовывать указатель в VLA массив с помощью такой кучерявой конструкции:
int (*array2)[colCount] = (int(*)[colCount]) array;

В этом случае обращаться к элементам массива можно как обычно через двойную индексацию: array2[i][j]
Когда-то делал тест на эту тему: https://ideone.com/4i6lRw
Кстати, если в average сначала передать размерности, и последним параметром массив, то по идее массив можно сразу объявить двумерным, используя ранее переданные размерности:
void average(int rowcount, int colcount, int aarray[rowCount][colCount])

Это то же VLA.

Вообще не рекомендую в С++ использовать VLA, т.к. программа становится не переносимой и зависимой от компилятора.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы