0

i'm making this code with some function that has a matrix param.This is the code:

#include <stdio.h>

void print_matrix(int **matrix){
  int i;
  int j;
  int rows=sizeof(matrix)/4;
  int columns=sizeof(matrix[0])/4;
  for(i=0;i<rows;i++){
    for(j=0;j<rows;j++){
      printf("%7d",matrix[i][j]);
    }
    printf("\n");
  }
}

int funzione(int **matrix, int rows, int columns){
  if (rows!=columns){printf("mi dispiace , non è una matrixe NxN\n");return 1;}
  else{
    int i;
    int j;
    int copia_diagonale_principale[rows];
    for(i=0;i<rows;i++){
      for(j=0;j<rows;j++){
        if (i==j){
          copia_diagonale_principale[i]=matrix[i][j];
          matrix[i][j]=matrix[i][rows-j];
          matrix[i][rows-j]=copia_diagonale_principale[i];

        }
      }
    }
    return 0;
  }

}

void main(void){

  int my_matrix[][3]={{1,2},{3,4},{5,6}}; //example

  int my_matrix_rows=sizeof(my_matrix)/4;
  int my_matrix_columns=sizeof(my_matrix[0])/4;
  printf("prima\n\n");
  print_matrix(my_matrix);
  funzione(my_matrix,my_matrix_rows,my_matrix_columns);
  printf("prima\n\n" );
  print_matrix(my_matrix);

}

The param of print_matrix is a pointer to pointers, but when i call the print_matrix with my_matrix in param an error (warning) appear:

main.c: In function 'main':
main.c:44:16: warning: passing argument 1 of 'print_matrix' from incompatible pointer type [-Wincompatible-pointer-types]
   print_matrix(my_matrix);
                ^~~~~~~~~
main.c:3:25: note: expected 'int **' but argument is of type 'int (*)[3]'
 void print_matrix(int **matrix){
                   ~~~~~~^~~~~~
main.c:45:12: warning: passing argument 1 of 'funzione' from incompatible pointer type [-Wincompatible-pointer-types]
   funzione(my_matrix,my_matrix_rows,my_matrix_columns);
            ^~~~~~~~~
main.c:16:20: note: expected 'int **' but argument is of type 'int (*)[3]'
 int funzione(int **matrix, int rows, int columns){
              ~~~~~~^~~~~~
main.c:47:16: warning: passing argument 1 of 'print_matrix' from incompatible pointer type [-Wincompatible-pointer-types]
   print_matrix(my_matrix);
                ^~~~~~~~~
main.c:3:25: note: expected 'int **' but argument is of type 'int (*)[3]'
 void print_matrix(int **matrix){
                   ~~~~~~^~~~~~

so i'm thinking, matrix and pointer to pointers are the same thing?

i think "yes, of course" , because pointers works as arrays, like in this test.c:

#include <stdio.h>

void print_vect(int *vector){
  printf("%d\n",vector[1] );
}

void main(void){
  int my_vect[]={14,2,3};
  print_vect(my_vect);
}

Thank you for reading the long question, i'm new to C.

Jokey
  • 71
  • 6
  • 1
    *"matrix and pointer to pointers are the same thing"* - Clearly not, or you wouldn't be seeing that stack of warnings and errors. An array of arrays (which is what `matrix` is in `main`) is *not* an array of pointers, fundamentally because an array is not a pointer, though it converts to a temporary pointer in expression contexts, which is all your test program demonstrates. Further, I *guarantee* you `sizeof(matrix)/4;` in your print function is *not* doing what you think it does. You can't find the size of a sequence using `sizeof` given only it's base address. – WhozCraig Nov 10 '19 at 18:56
  • 1
    _"matrix and pointer to pointers are the same thing?"_ -- NO; _"i think "yes, of course"..."_ -- that test is irrelevant – paddy Nov 10 '19 at 18:57

1 Answers1

1

When you have a matrix like int m[3][3], all of its contents are loaded contiguously in memory. You can use m as a pointer to the start of this block of memory but there are no other pointers involved. In order to look up m[2][1] the runtime will actually look up the integer at (3*2 + 1) * sizeof(int) bytes from the start of the block.

If instead you organize your data using an array of pointers to arrays, m[2][1] would tell the runtime to look up the pointer at offset 2 in the array of pointers, then go to that address and look at the integer at offset 1. The storage locations for the data of the first row of this "matrix" could be very far away from the storage locations for the second row.

These data structures really are not like each other at all as far as the function that receives one of them is concerned. In order to use the data structure you just passed to it, the function needs to know how to look up things in the "matrix". You tell it this by the function signature. Then, having told the function to look things up in a certain way, the compiler tries to stop you from passing a data structure that requires a completely different way to look things up. The reason is that the function will use the method you told it in the signature and will get wrong results, possibly even a fatal error at runtime.

We just have this syntactic device m[i][j] that makes the looking up of an individual entry appear the same to you.

David K
  • 3,147
  • 2
  • 13
  • 19