Alyamin Smail
Alyamin Smail

Reputation: 63

How do you pass a 2d array as an argument?

I want to create an adjacency matrix using the code below ,but it keep showing me this error :

||=== Build file: "no target" in "no project" (compiler: unknown) ===|
D:\abSTD\graph theory\createAdjMat.cpp|6|error: array bound is not an integer constant before ']' token|
D:\abSTD\graph theory\createAdjMat.cpp|6|error: expected ')' before ',' token|
D:\abSTD\graph theory\createAdjMat.cpp|6|error: expected unqualified-id before 'int'|
||=== Build failed: 3 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
#include <bits/stdc++.h>

using namespace std;
int N, M;

void createAdjMatrix(int Adj[][N], int arr[][M]) {
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      Adj[i][j] = 0;
    }
  }

  for (int i = 0; i < M; i++) {
    int x = arr[i][0];
    int y = arr[i][1];

    Adj[x][y] = 1;
    Adj[y][x] = 1;
  }
}

void printAdjMatrix(int Adj[][N]) {
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      cout << Adj[i][j] << ' ';
    }
    cout << endl;
  }
}

int main() {
  // Number of vertices
  N = 5;

  // Given Edges
  int arr[][2] = {{1, 2}, {2, 3}, {4, 5}, {1, 5}};

  // Number of Edges
  M = sizeof(arr) / sizeof(arr[0]);

  // For Adjacency Matrix
  int Adj[N][N];

  // Function call to create
  // Adjacency Matrix
  createAdjMatrix(Adj, arr);

  // Print Adjacency Matrix
  printAdjMatrix(Adj);

  return 0;
}

Upvotes: 0

Views: 342

Answers (3)

user14611663
user14611663

Reputation:

In C++, a size of an array has to be a compile-time constant, it cannot be a variable. Furthermore, if you pass a multi-dimensional array to a function, you have to specify all dimensions except the last one. On the other hand, the last dimension is not validated by the compiler, so array of any value of last dimension can in fact be passed.

If you want to have all dimensions of the array automatically validated and inferred by the compiler, you can use templates and pass the array reference, like this:

#include <bits/stdc++.h>
    
using namespace std;

template<int M, int N>
void createAdjMatrix(int (&Adj)[M][M], int (&arr)[N][2]) {
  for (int i = 0; i < M; i++) {
    for (int j = 0; j < M; j++) {
      Adj[i][j] = 0;
    }
  }

  for (int i = 0; i < N; i++) {
    int x = arr[i][0];
    int y = arr[i][1];

    Adj[x][y] = 1;
    Adj[y][x] = 1;
  }
}
    
template<int M>
void printAdjMatrix(int (&Adj)[M][M]) {
  for (int i = 0; i < M; i++) {
    for (int j = 0; j < M; j++) {
      cout << Adj[i][j] << ' ';
    }
    cout << endl;
  }
}
    
int main() {    
  // Given Edges
  int arr[][2] = {{1, 2}, {2, 3}, {4, 5}, {1, 5}};
    
  // For Adjacency Matrix
  int Adj[5][5];

  // Function call to create
  // Adjacency Matrix
  createAdjMatrix(Adj, arr);
      
  // Print Adjacency Matrix
  printAdjMatrix(Adj);
  return 0;
}

This syntax (together with C++ 11 constexpr keyword) also makes it possible to create function returning a size of an array:

template<typename T, int N>
constexpr int ArraySize(T (&array)[N])
{
    return N;
}

And use it instead of sizeof like this:

int array[42];
// Old way to compute a size
int size_old = sizeof(array) / sizeof(array[0]);
// The C++ 11 way
int size = ArraySize(array);

Upvotes: 1

ivan_onys
ivan_onys

Reputation: 2372

The program below illustrates:

  1. How to declare 2D array/matrix type Mat2D. Note that type doesn't include dimensions.
  2. How to pass into a function by const reference as edges.
  3. How to create empty (filled with zeros) 2D matrix with given dimension adjMat in createAdjMatrix(). The first is number of rows, the second (inside 'vector()') is number of columns.
  4. How to access 2D elements. See comment in createAdjMatrix()

    #include <vector>
    
    using std::vector;
    using Mat2D = vector<vector<int>>; 
    
    Mat2D createAdjMatrix(int N, const Mat2D& edges) 
    {
      Mat2D adjMat(N, vector<int>(N));
    
      // You assign to element as adjMat[i][j] = ...
      // TODO: implement
    
      return adjMat;
    } 
    
    void printAdjMatrix(const Mat2D& adjMat)
    {
      // TODO: implement
    }
    
    int main() 
    {
      Mat2D edges = {{1, 2}, {2, 3}, {4, 5}, {1, 5}};
      auto adjMat = createAdjMatrix(5, edges);
      printAdjMatrix(adjMat);
      return 0;
    }

Upvotes: 1

A M
A M

Reputation: 15277

The biggest problem here is that you are using an invalid C++ extension and not C++.

VLAs (Variable Length Arrays) are not allowed in C++. In C++ all array dimensions need to be defined with compile time constants.

Additionally, you should never use raw pointers for owned memory and no pointer arithmetic.

And then the main topic:

Issue in Passing a 2-D array

The used syntax for passing arrays to function is wrong. In C++ arrays can be passed by reference or by pointer. Please see:

void function1(int(&m)[3][4])   // For passing array by reference
{}
void function2(int(*m)[3][4])   // For passing array by pointer
{}

int main()
{
    int matrix[3][4]; // Define 2 dimensional array

    function1(matrix);  // Call by reference
    function2(&matrix); // Call via pointer 
    return 0;
}

Of course we can do all kind of dirty designs with pointers. Even accepting pointer decays. But we should not do it.

Upvotes: 1

Related Questions