Passing 2D arrays to C like argv main

I am studying the transfer of 2D arrays to functions in C and found out that I can get a 2D array in a function as follows:

  • void test(char a[5][10])
  • void test(char (*a)[10])

The above declarations work for me, but looking at the **argv parameter of the main function, I was thinking about changing my function to void test(char **a) . But this does not work correctly. I do not understand why. Please explain.

Here is my code

 #include<stdio.h> int main(int argc, char **argv){ char multi[5][10] = { {'0','0','2','3','4','5','6','7','1','9'}, {'a','b','c','d','e','f','g','h','i','j'}, {'A','B','C','D','E','F','G','H','I','J'}, {'9','8','7','6','5','4','3','2','1','0'}, {'J','I','H','G','F','E','D','C','B','A'} }; test(multi); return 0; } void test(char (*a)[10]) // void test(char **a) does not work { printf("\na[2][1] is: %d",*(*(a + 2)+1)); } 
+4
source share
6 answers

The name of the array when passing the function will decay to the address value of its first element, and its type will be a pointer to this type of element. Since the type multi[0] is equal to char[10] , then multi will decay pointer to char[10] .

main() receives in its second parameter an array of pointers to char , so argv can be char **argv or char *argv[] .

+4
source

For multidimensional arrays, strings are stored in read-only memory cells. Therefore, we need to pass the number of columns, i.e. Calculate the number of items to jump to go to a specific line.

In the case of a pointer to pointers, strings are stored in arbitrary memory cells. You cannot find the location of a line with a pointer to the first line and index. In this case, you need as many pointers as you have.

In short, the two versions of the arguments to your function assume different memory layouts and, as such, they are incompatible.

+4
source

An array in C is essentially one-dimensional. When transmitting a multidimensional array, you must pass each dimension size, except the first, as a constant integer. And the array is passed as a pointer, not an array. Here's an alternative: passing a one-dimensional or multi-dimensional pointer along with the size of the daemons. For example: void test (char * a, int row, int column); and the index is: column * i + j; or: void test (char ** a, int row, int column);

+2
source

char (* a) [10] - a pointer to an array of characters. Operation (a + 1) will increase the value of a by 10 bytes.

char ** a is a double pointer. In this case, operation (a + 1) will increase the value of a by 4 bytes. Therefore, the statement below will lead to erroneous behavior.

printf ("\ na [2] [1]:% d", * (* (a (2 + 1) +1));

+1
source

This is not a formal explanation, but how I understand it: arrays are actually stored in memory linearly. For example, you define a 10x10 array and execute b=a[4][5] , the system will look for an element 4*10+5=45 th in memory. Therefore, you cannot pass **a and access it as a 2D array. This is a pointer without size information. Using a[4][5] program will go to find the element 4*(number of columns)+5 th. Since he does not know how many elements are in the row, he cannot do this.

0
source

You can always do something like this

 #include<stdio.h> #include<stdlib.h> void test(char **a); int main(int argc, char **argv){ char **multi = (char**) malloc (5*sizeof(char*)); char a[5][10] = {{'0','0','2','3','4','5','6','7','1','9'}, {'a','b','c','d','e','f','g','h','i','j'}, {'A','B','C','D','E','F','G','H','I','J'}, {'9','8','7','6','5','4','3','2','1','0'}, {'J','I','H','G','F','E','D','C','B','A'}}; int i,j; for(i=0;i<5;i++) { multi[i] = (char*) malloc (10*sizeof(char)); } for(i = 0;i<5;i++) { for(j = 0; j < 10 ;j++) { multi[i][j] = a[i][j]; } } test(multi); return 0; } void test(char **a) // void test(char **a) does not work { printf("\na[2][1] is: %c\n",*(*(a + 2)+1)); } 
0
source

Source: https://habr.com/ru/post/1490640/


All Articles