I want to write a method in C which prints a 2D array. This method is void and it has these parameters as inputs: 2D array, number of rows, number of columns. I want to use the 2D matrix as a double pointer to call the function. I want to print the elements in a 2D shape. I get the following error:
error: cannot convert ‘int (*)[2]’ to ‘int**’
EDIT : changing int** list to int (*list)[2] works but is there a way which I don't have to write the column number manually, because I want this method to work for different sizes of array.
#include <iostream>
using namespace std;
void printArray2D(int** list, int row, int col) {
for (int i = 0; i < row; i ) {
for (int j = 0; j < col; j ) {
cout << list[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int list1[2][2] = { {1,2},{3,4} };
int row1 = sizeof(list1) / sizeof(list1[0]);
int col1 = sizeof(list1[0]) / sizeof(list1[0][0]);
printArray2D(list1, row1, col1);
return 0;
}
CodePudding user response:
Your array is actually flat, meaning that you have to cast its type to int*
, not to int**
. int**
refers to array of pointers to int arrays, but you have no pointers inside array.
In other words you have actually 1-dimensional array of ints (flat). Any C multi-dimensional array like int a[3][5]
or int a[3][5][7]
are all flat array, 1-dimensional in nature. [3][5]
array points to contiguous region in memory containing 3 * 5 = 15
ints, and [3][5][7]
array points to 3 * 5 * 7 = 105
ints in contiguous region of memory.
Also after casting to int*
information about dimensions is lost, hence you have to do indexing arithmetics manually through using [i * col j]
:
#include <iostream>
using namespace std;
void printArray2D(int* list, int row, int col) {
for (int i = 0; i < row; i ) {
for (int j = 0; j < col; j ) {
cout << list[i * col j] << " ";
}
cout << endl;
}
}
int main()
{
int list1[2][2] = { {1,2},{3,4} };
int row1 = sizeof(list1) / sizeof(list1[0]);
int col1 = sizeof(list1[0]) / sizeof(list1[0][0]);
printArray2D((int*)list1, row1, col1);
return 0;
}
Output:
1 2
3 4
Actually there is a C specific solution using templates that can be used to keep information about dimensions and forward this information to function, then you don't have to use manual indexing arithmetics:
#include <iostream>
using namespace std;
template <int Rows, int Cols>
void printArray2D(int const (&list)[Rows][Cols]) {
for (int i = 0; i < Rows; i ) {
for (int j = 0; j < Cols; j ) {
cout << list[i][j] << " ";
}
cout << endl;
}
}
int main()
{
int list1[2][2] = { {1,2},{3,4} };
int row1 = sizeof(list1) / sizeof(list1[0]);
int col1 = sizeof(list1[0]) / sizeof(list1[0][0]);
printArray2D(list1);
return 0;
}
Output:
1 2
3 4
Another nice solution in case if you have fixed multi-dimensional array is by using std::array. Then you don't need to forward any dimensions information, just use .size()
method of std::array
:
#include <iostream>
#include <array>
template <typename ArrT>
void printArray2D(ArrT const & list) {
for (int i = 0; i < list.size(); i ) {
for (int j = 0; j < list[i].size(); j ) {
std::cout << list[i][j] << " ";
}
std::cout << std::endl;
}
}
int main()
{
std::array<std::array<int, 2>, 2> list1 =
{ std::array{1,2}, std::array{3,4} };
printArray2D(list1);
return 0;
}
Output:
1 2
3 4