In C, what does a variable declaration with two asterisks (**) mean?

后端 未结 5 1817
我在风中等你
我在风中等你 2020-12-12 20:57

I am working with C and I\'m a bit rusty. I am aware that * has three uses:

  1. Declaring a pointer.
  2. Dereferencing a pointer.
  3. Multi
相关标签:
5条回答
  • 2020-12-12 21:15

    It declares a pointer to a char pointer.

    The usage of such a pointer would be to do such things like:

    void setCharPointerToX(char ** character) {
       *character = "x"; //using the dereference operator (*) to get the value that character points to (in this case a char pointer
    }
    char *y;
    setCharPointerToX(&y); //using the address-of (&) operator here
    printf("%s", y); //x
    

    Here's another example:

    char *original = "awesomeness";
    char **pointer_to_original = &original;
    (*pointer_to_original) = "is awesome";
    printf("%s", original); //is awesome
    

    Use of ** with arrays:

    char** array = malloc(sizeof(*array) * 2); //2 elements
    
    (*array) = "Hey"; //equivalent to array[0]
    *(array + 1) = "There";  //array[1]
    
    printf("%s", array[1]); //outputs There
    

    The [] operator on arrays does essentially pointer arithmetic on the front pointer, so, the way array[1] would be evaluated is as follows:

    array[1] == *(array + 1);
    

    This is one of the reasons why array indices start from 0, because:

    array[0] == *(array + 0) == *(array);
    
    0 讨论(0)
  • 2020-12-12 21:20

    This is a pointer to a pointer to char.

    0 讨论(0)
  • 2020-12-12 21:28

    It declares aPointer as a pointer to a pointer to char.

    Declarations in C are centered around the types of expressions; the common name for it is "declaration mimics use". As a simple example, suppose we have a pointer to int named p and we want to access the integer value it's currently pointing to. We would dereference the pointer with the unary * operator, like so:

    x = *p;
    

    The type of the expression *p is int, so the declaration of the pointer variable p is

    int *p;
    

    In this case, aPointer is a pointer to a pointer to char; if we want to get to the character value it's currently pointing to, we would have to dereference it twice:

    c = **aPointer;
    

    So, going by the logic above, the declaration of the pointer variable aPointer is

    char **aPointer;
    

    because the type of the expression **aPointer is char.

    Why would you ever have a pointer to a pointer? It shows up in several contexts:

    • You want a function to modify a pointer value; one example is the strtol library function, whose prototype (as of C99) is
      long strtol(const char * restrict str, char ** restrict ptr, int base);  
      
      The second argument is a pointer to a pointer to char; when you call strtol, you pass the address of a pointer to char as the second argument, and after the call it will point to the first character in the string that wasn't converted.

    • Remember that in most contexts, an expression of type "N-element array of T" is implicitly converted to type "pointer to T", and its value is the address of the first element of the array. If "T" is "pointer to char", then an expression of type "N-element array of pointer to char" will be converted to "pointer to pointer to char". For example:
      
          void foo(char **arr)
          {
            size_t i = 0;
            for (i = 0; arr[i] != NULL; i++)
              printf("%s\n", arr[i]);
          }
      
          void bar(void)
          {
            char *ptrs[N] = {"foo", "bar", "bletch", NULL};
            foo(ptrs); // ptrs decays from char *[N] to char **
          }
      
      

    • You want to dynamically allocate a multi-dimensional array:
      
      #define ROWS ...
      #define COLS ...
      ...
      char **arr = malloc(sizeof *arr * ROWS);
      if (arr)
      {
        size_t i;
        for (i = 0; i < ROWS; i++)
        {
          arr[i] = malloc(sizeof *arr[i] * COLS);
          if (arr[i])
          {
            size_t j;
            for (j = 0; j < COLS; j++)
            {
              arr[i][j] = ...;
            }
          }
        }
      }
      
    0 讨论(0)
  • 2020-12-12 21:29

    C and C++ allows the use of pointers that point to pointers (say that five times fast). Take a look at the following code:

    char a;
    char *b;
    char **c;
    
    a = 'Z';
    b = &a; // read as "address of a"
    c = &b; // read as "address of b"
    

    The variable a holds a character. The variable b points to a location in memory that contains a character. The variable c points to a location in memory that contains a pointer that points to a location in memory that contains a character.

    Suppose that the variable a stores its data at address 1000 (BEWARE: example memory locations are totally made up). Suppose that the variable b stores its data at address 2000, and that the variable c stores its data at address 3000. Given all of this, we have the following memory layout:

    MEMORY LOCATION 1000 (variable a): 'Z'
    MEMORY LOCATION 2000 (variable b): 1000 <--- points to memory location 1000
    MEMORY LOCATION 3000 (variable c): 2000 <--- points to memory location 2000
    
    0 讨论(0)
  • 2020-12-12 21:32

    It means that aPointer points to a char pointer.

    So

    aPointer: pointer to char pointer
    
    *aPointer :pointer to char
    
    **aPointer: char
    

    An example of its usage is creating a dynamic array of c strings

    char **aPointer = (char**) malloc(num_strings);

    aPointer gives you a char, which can be used to represent a zero-terminated string.

    *aPointer = (char*)malloc( string_len + 1); //aPointer[0]
    *(aPointer + 1) = (char*)malloc( string_len + 1); //aPointer[1]
    
    0 讨论(0)
提交回复
热议问题