Home c++ Transfer a two-dimensional static array to the function

Transfer a two-dimensional static array to the function

Author

Date

Category

There is a problem in the transfer of a two-dimensional static array to the

function

int ** transp (int ** m, int a, int b)

tried to just pass as int ** array
int A [3] [4];
TRANSP (A, 3, 4);

[Error] CANNOT Convert ‘int (*) [3]’ to ‘int **’

  1. How to properly convey static array to the function. In this case, the function should also take dynamic arrays. Overload, templates and STL do not offer.
  2. Static 2D arrays are stored in memory linearly. Dynamic stored linearly stored or not?
  3. What communication has a static 2D array with pointers?

Answer 1, Authority 100%

If you have an array declared as

int a [3] [4];

The non-displaced function accepting this array as an argument may look like, for example, as

void f (int (* a) [4], size_t n);

and call as

f (a, 3);

or it can be declared as

void f (int (& amp; a) [3] [4]);

and call as

f (a);

As for this function

int ** transp (int ** m, int a, int b);

then you can not transfer an array into it, declared as

int a [3] [4];

That is, you can pass, using various tricks, but most likely the function will not work as you assume.

There is such a universal approach. It is to interpret any two-dimensional array, like one-dimensional, and transmit the size of each dimension of the array.

For example,

void f (int a [], size_t m, size_t n);
// ...
INT A [3] [4];
f (reinterpret_cast & lt; int * & gt; (a), 3, 4);

Here is a demonstration program

# include & lt; iostream & gt;
#InClude & lt; Iomanip & gt;
Void F (int A [], Size_t M, Size_t n)
{
  For (Size_t i = 0; i & lt; m; i ++)
  {
    for (Size_t j = 0; j & lt; n; j ++) a [I * n + j] = i * n + j;
  }
}
INT MAIN ()
{
  const size_t m = 3;
  Const Size_t n = 4;
  int a [m] [n];
  f (reinterpret_cast & lt; int * & gt; (a), m, n);
  For (Size_t i = 0; i & lt; m; i ++)
  {
    for (Size_t j = 0; j & lt; n; j ++) std :: cout & lt; & lt; STD :: SETW (2) & LT; & LT; A [i] [j] & lt; & lt; '';
    STD :: COUT & LT; & LT; STD :: ENDL;
  }
  Return 0;
}

Its conclusion on the console

0 1 2 3
 4 5 6 7
 8 9 10 11

If you write a program on C, and not on C++, then there are arrays of variable length, and therefore it would be easier for you.

in C++ for these purposes it is better to use the standard class std :: vector

For example,

std :: vector & lt; std :: vector & lt; int & gt; & gt; V (3, std :: vector & lt; int & gt; (4));

As for your question

2) Static 2D arrays are stored in memory linearly. Dynamic
Stored also linear or not?

That if you will distribute it in memory as a two-dimensional array, then naturally its elements will be stored linearly on lines. For example

int (* a) [4] = new int [3] [4];

and as for this issue

3) What connection has a static 2D array with pointers?

then any array in (with rare exceptions) is implicitly converted into a pointer to its first element.


Answer 2, Authority 50%

In gcc to do this is quite simple.

You can transfer function in the dimension of the matrix (enough only the “lower”) and refer to elements in the indices esteststvennym way. For example:

void func (int n_lines, int n_columns, int array [] [n_columns]) {
   array [0] [0] = array [n_lines - 1] [n_columns - 1];
}

Unfortunately g ++ (and C++) does not support such a transfer function matrices. Therefore, the easiest way (having the knowledge that all the elements of the matrix are stored in memory in sequence, first the first line, followed by the second, and so on) to pass to the function address of the first element of the matrix, as a function of the regard it as a one-dimensional array.
Naturally, recalculate the indices will have the most.

Here is an example file, which presents both versions of the program and the results of its run:

avp @ avp-ubu1: hashcode $ cat c1.c
#Include & lt; stdio.h & gt;
#ifdef __cplusplus
#Include & lt; iostream & gt;
#Endif
static int aa [4] [3] = {
 {11, 12, 13},
 {21, 22, 23},
 {31, 32, 33},
 {41, 42, 43}
};
#ifdef __cplusplus
Void.
func_matrix (int n, int m, int * x)
{
 x [0] = x [(n - 1) * m + m - 1];
 for (int i = 0; i & lt; n; i ++)
  for (int j = 0; j & lt; m || puts ( "");! j ++)
   STD :: COUT & LT; & LT; x [i * m + j] & lt; & lt; '';
}
#ELSE.
Void.
func_matrix (int n, int m, int x [n] [m])
{
 int i, j;
 x [0] [0] = x [n - 1] [m - 1];
 for (i = 0; i & lt; n; i ++)
  for (j = 0; j & lt;! m || puts ( ""); j ++)
   printf ( "% d", x [i] [j]);
}
#Endif
int
Main (Int AC, char * AV [])
{
#ifdef __cplusplus
 func_matrix (4, 3, & amp; aa [0] [0]);
#ELSE.
 func_matrix (4, 3, aa);
#Endif
}
avp @ avp-ubu1: hashcode $ gcc c1.c & amp; & amp; ./a.out
43 December 13
21 22 23.
31 32 33
41 42 43
avp @ avp-ubu1: hashcode $ g ++ c1.c & amp; & amp; ./a.out
43 December 13
21 22 23.
31 32 33
41 42 43
avp @ avp-ubu1: hashcode $

If you still have questions, ask.

UPD

Here’s a variation with pointers to the string “dense” matrix.

Take the static matrix, making it an array of pointers, pass it to the transpose function that makes the heap “dense” transposed matrix and returns a new array of pointers to its line.

# include & lt; stdio.h & gt;
#Include & lt; stdlib.h & gt;
int **
make_lines_ptrs (int * mx, int a, int b)
{
 int ** p = (int **) malloc (a * sizeof (int *));
 for (int i = 0; i & lt; a; i ++)
  p [i] = mx + i * b;
 return p;
}
int **
transp (const int * const * m, int a, int b)
{
 int * mx = (int *) malloc (a * b * sizeof (int));
 for (int i = 0; i & lt; a; i ++)
  for (int j = 0; j & lt; b; j ++)
   mx [j * a + i] = m [i] [j];
 return make_lines_ptrs (mx, b, a);
}
Void.
pri_mx (const int * const * m, int a, int b)
{
 for (int i = 0; i & lt; a; i ++)
  for (int j = 0; j & lt;! b || puts ( ""); j ++)
   printf ( "% d", m [i] [j]);
}
static int aa [4] [3] = {
 {11, 12, 13},
 {21, 22, 23},
 {31, 32, 33},
 {41, 42, 43}
};
int
Main (Int AC, char * AV [])
{
 int ** pl = make_lines_ptrs (& amp; aa [0] [0], 4, 3);
 pri_mx (pl, 4, 3);
 int ** tr = transp (pl, 4, 3);
 pri_mx (tr, 3, 4);
}

Well, the memory before exiting you already own free?


Answer 3, Authority 10%

template & lt; int aRows, int aCols & gt;
void func (int (* data) [aRows] [aCols]) {}
...
int a [5] [3] = {0};
func (& amp; a);

except for the transfer of the values ​​of the array get its dimensions through aRows and aCols.

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions