Differences when using ** in C

前端 未结 11 870
半阙折子戏
半阙折子戏 2020-12-24 10:50

I started learning C recently, and I\'m having a problem understanding pointer syntax, for example when I write the following line:

int ** arr = NULL;


        
相关标签:
11条回答
  • 2020-12-24 11:39

    The type of

    int ** arr;
    

    only have one valid interpretation. It is:

    arr is a pointer to a pointer to an integer
    

    If you have no more information than the declaration above, that is all you can know about it, i.e. if arr is probably initialized, it points to another pointer, which - if probably initialized - points to an integer.

    Assuming proper initialization, the only guaranteed valid way to use it is:

    **arr = 42;
    int a = **arr;
    

    However, C allows you to use it in multiple ways.

    • arr can be used as a pointer to a pointer to an integer (i.e. the basic case)

    int a = **arr;
    

    • arr can be used as a pointer to a pointer to an an array of integer

    int a = (*arr)[4];
    

    • arr can be used as a pointer to an array of pointers to integers

    int a = *(arr[4]);
    

    • arr can be used as a pointer to an array of pointers to arrays of integers

    int a = arr[4][4];
    

    In the last three cases it may look as if you have an array. However, the type is not an array. The type is always just a pointer to a pointer to an integer - the dereferencing is pointer arithmetic. It is nothing like a 2D array.

    To know which is valid for the program at hand, you need to look at the code initializing arr.

    Update

    For the updated part of the question:

    If you have:

    void foo(char** x) { .... };
    

    the only thing that you know for sure is that **x will give a char and *x will give you a char pointer (in both cases proper initialization of x is assumed).

    If you want to use x in another way, e.g. x[2] to get the third char pointer, it requires that the caller has initialized x so that it points to a memory area that has at least 3 consecutive char pointers. This can be described as a contract for calling foo.

    0 讨论(0)
  • 2020-12-24 11:40

    C syntax is logical. As an asterisk before the identifier in the declaration means pointer to the type of the variable, two asterisks mean pointer to a pointer to the type of the variable.

    In this case arr is a pointer to a pointer to integer.

    There are several usages of double pointers. For instance you could represent a matrix with a pointer to a vector of pointers. Each pointer in this vector points to the row of the matrix itself.

    One can also create a two dimensional array using it,like this

     int **arr=(int**)malloc(row*(sizeof(int*)));  
     for(i=0;i<row;i++) {
     *(arr+i)=(int*)malloc(sizeof(int)*col); //You can use this also. Meaning of both is same. //
      arr[i]=(int*)malloc(sizeof(int)*col); }
    
    0 讨论(0)
  • 2020-12-24 11:45

    There is one trick when using pointers, read it from right hand side to the left hand side:

    int** arr = NULL;

    What do you get: arr, *, *, int, so array is a pointer to a pointer to an integer.

    And int **arr; is the same as int** arr;.

    0 讨论(0)
  • 2020-12-24 11:46

    How can I know if :

    • arr is a pointer to a pointer of an integer

    It is always a pointer to pointer to integer.

    • arr is a pointer to an array of pointers to integers
    • arr is a pointer to an array of pointers to arrays of integers

    It can never be that. A pointer to an array of pointers to integers would be declared like this:

    int* (*arr)[n]
    

    It sounds as if you have been tricked to use int** by poor teachers/books/tutorials. It is almost always incorrect practice, as explained here and here and ( with detailed explanation about array pointers) here.

    EDIT

    Finally got around to writing a detailed post explaining what arrays are, what look-up tables are, why the latter are bad and what you should use instead: Correctly allocating multi-dimensional arrays.

    0 讨论(0)
  • 2020-12-24 11:47
    int ** arr = NULL;
    

    It's tell the compiler, arr is a double pointer of an integer and assigned NULL value.

    0 讨论(0)
提交回复
热议问题