Я пытаюсь передать динамический 2-D массив в функцию, и он выдает ошибку. Я попытался явно указать размеры массива, и это сработало, но динамический не работает, никаких указателей (каламбур не предназначен)
#include <iostream>
#include <vector>
using namespace std;
void print_2d_array(int arr_size, int (*arr)[5]){
for(int i = 0; i < arr_size; ++i){
for(int j = 0; j < arr_size; ++j)
cout << arr[i][j] << "\t";
cout << endl;
}
}
int main(){
vector<int> x{10,15,20,30,40};
int arr[x.size()][x.size()];
for(int i = 0; i < x.size(); ++i)
arr[i][i] = 0;
print_2d_array(5, arr);
return 0;
}
Я перепробовал все три метода, которые были подробно описаны здесь Передача 2D массива в C
Если вместо создания экземпляра массива, как показано выше, я использую что-то вроде
arr[5][5];
это работает как ожидалось. Я получаю следующую ошибку
error: cannot convert ‘int (*)[(<anonymous> + 1)]’ to ‘int (*)[5]’ for argument ‘2’
to ‘void print_2d_array(int, int (*)[5])’
print_2d_array (5, обр);
Массив переменной длины (VLA) не является частью стандарта C ++. Он является частью стандарта C99 и обычно реализуется как расширение для C ++ в различных компиляторах.
Обычно нормально использовать VLA в программе C ++, когда вы выделяете массив. Но у вас будут проблемы, когда вам нужно будет передать массив, потому что нет типа аргумента, который является VLA, чтобы вы могли передавать его в качестве аргументов функциям в C ++. (Вот почему, когда вы вручную вставляете функцию, код работает нормально, что позволяет избежать передачи массива в функцию.) Вы должны передать массив как указатель на функцию и, возможно, использовать reinterpret_cast
до и внутри функции для преобразования VLA в указатель и преобразования его обратно. Это просто ужасный код.
При кодировании на C ++ просто используйте идиоматический способ C ++. Поскольку вы уже используете vector
Вы можете просто использовать vector<vector<int>>
(vector<vector<int> >
если не с использованием C ++ 11, а из способа инициализации x
вы используете C ++ 11) в качестве двумерного массива. Ваш код должен быть изменен, как показано ниже:
#include <iostream>
#include <vector>
using namespace std;
void print_2d_array(int arr_size, vector<vector<int>> &arr){
for(int i = 0; i < arr_size; ++i){
for(int j = 0; j < arr_size; ++j)
cout << arr[i][j] << "\t";
cout << endl;
}
}
int main(){
vector<int> x{10,15,20,30,40};
vector<vector<int>> arr(x.size(), vector<int>(x.size()));
// No need to use this to initialize:
// for(int i = 0; i < sizeof(x); ++i)
// arr[i][i] = 0;
print_2d_array(5, arr);
return 0;
}
Обратите внимание, что это также исправило вашу проблему arr
не был правильно инициализирован.
Если вы собираетесь использовать C, то с VLA все в порядке, и это будет так (и не то, чтобы я не исправил вашу инициализацию, которая только инициализировала диагональные элементы. Вы должны использовать компилятор C, а не C ++, чтобы скомпилируйте это.):
#include <stdio.h>
void print_2d_array(int arr_size, int arr[][arr_size]){
for(int i = 0; i < arr_size; ++i){
for(int j = 0; j < arr_size; ++j)
printf("%d\t", arr[i][j]);
printf("\n");
}
}
int main(){
int x[] = {10,15,20,30,40};
int arr[sizeof(x)][sizeof(x)];
// bad initialization:
for(int i = 0; i < sizeof(x); ++i)
arr[i][i] = 0;
print_2d_array(5, arr);
return 0;
}
Хорошо, если вы решили использовать C ++, но не любите vector, следующая простейшая вещь — использовать примитивные указатели, что не рекомендуется.
#include <iostream>
#include <vector>
using namespace std;
void print_2d_array(int arr_size, int **arr){
for(int i = 0; i < arr_size; ++i){
for(int j = 0; j < arr_size; ++j)
cout << arr[i][j] << "\t";
cout << endl;
}
}
int main(){
vector<int> x {10,15,20,30,40};
int **arr = new int*[x.size()];
for (int i = 0; i < x.size(); ++i) {
arr[i] = new int[x.size()];
for (int j = 0; j < x.size(); ++j) {
arr[i][j] = 0;
}
}
print_2d_array(5, arr);
for (int i = 0; i < x.size(); ++i) {
delete[] arr[i];
}
return 0;
}
Сохраните свои проблемы и используйте контейнеры. Вы используете современный C ++.
(Ответ предполагает, что вы не можете определить размер массива перед запуском. Хотя это не так в вашем примере — размер должен быть 5, и нет причин использовать VLA.)
Прежде всего,
int arr[x.size()][x.size()];
не является допустимым C ++. Размеры массива должны быть известны во время компиляции.
Если вы используете компилятор, который поддерживает массивы переменной длины, в качестве расширения, вы можете использовать этот оператор. Но тогда тип переменной не int (*)[5]
что и ожидается print_2d_array
,
Вы можете использовать вложенный std::array
если вы знаете размеры во время компиляции.
Вы можете использовать вложенный std::vector
если нужно вычислить размеры во время выполнения.
Обновление в ответ на комментарий ОП
Возьмите упрощенную версию программы.
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> x{10,15,20,30,40};
int arr[x.size()][x.size()];
return 0;
}
Команда для компиляции:
g++ -Wall -std=c++11 socc.cc -o socc -pedantic
Ошибки / предупреждения:
socc.cc: In function ‘int main()’:
socc.cc:8:31: warning: ISO C++ forbids variable length array ‘arr’ [-Wvla]
int arr[x.size()][x.size()];
^
socc.cc:8:31: warning: ISO C++ forbids variable length array ‘arr’ [-Wvla]
socc.cc:8:9: warning: unused variable ‘arr’ [-Wunused-variable]
int arr[x.size()][x.size()