简体   繁体   中英

pointer pointing to an entire array

struct grid {
    int width, height;
    void *cells[];
};
typedef struct grid grid;

int main(){
    enum { width = 2, height = 10 };
    grid *g = malloc(sizeof(grid) + width * height * sizeof(void *));
    void *(*cells)[10] = &g->cells;
}

My professor taught us about this cool way to allocate a flexible array and then assign a pointer that points to an entire array of pointers

void *(*cells)[10] = &g->cells; <-- This line

So i tried this method

 char *array[10];
 char *(*pointer)[2] = &array;

And it just gave me a compiler error

warning: incompatible pointer types initializing
      'char *(*)[2]' with an expression of type 'char *(*)[10]'
       [-Wincompatible-pointer-types]
       char *(*pointer)[2] = &array;

If anyone could explain to me the functionality of a "pointer to an entire array" that would be useful. Thank you

Lets take your correct declaration first:

 void *(*cells)[10] = &g->cells; 

To understand this, recognize first that cells is the identifier being declared, and from there follow precedence rules:

  1. (*cells) says that cells is a pointer, and the rest of the declaration describes the pointed-to thing. The parentheses are simply to enforce precedence, just like in an arithmetic expression.
  2. The [10] applies next, because brackets have higher precendence than unary * . This says, then, that (*cells) is an array with 10 elements.
  3. That leaves the void * out front, which gives the type of each element.

And if we look at &g->cells , it is a pointer to an array of an unspecified number of void * .

Now consider your code:

 char *array[10]; char *(*pointer)[2] = &array; 

Following similar procedure, we get that pointer is declared as a pointer to an array of 2 char * . So far, so good. Now, what are you trying to assign to it? Why, it's a pointer to an array of 10 char * . That's a pointer to a different, incompatible type.

In the first case, the initializer's type is a pointer to an "incomplete type" that is compatible with the type to which the pointer points. (It is incomplete because the array length is unspecified; it is compatible because in all other respects it matches the other type.) The pointed-to thing could be an array of the length implicitly asserted by the assignment, and C will treat the pointer as if it were.

In the second case, C can see that the two pointers definitely point to objects of different size, and that therefore the assignment is definitely incorrect. You would need a cast or a change to the type of pointer to make it accept the initialization.

&array is the address of an array containing 10 pointers to char

pointer is a pointer to an array containing 2 pointers to char

2 != 10 , hence the warning.

There's a handy website that helps to understand difficult c decelerations.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM