I stumbled upon "pointer to the entire array" and wrote a test program to clear some things out:
#include <stdio.h>
int main(){
    int x[5] = {1, 2, 3, 4, 5};
    int  *a     =  x;   // points to the 1st array element
    int (*b)[5] = &x;   // points to the 1st addres of the stream of 5 int elements
    int (*c)[5] = x;    // points to the 1st addres of the stream of 5 int elements
    printf("%p\n%p\n%p\n\n",
        (void *)a,
        (void *)b,
        (void *)c
    );
    ++a;
    ++b;
    ++c;
    printf("%p\n%p\n%p\n\n",
        (void *)a,
        (void *)b,
        (void *)c
    );
    return 0;
}
This outputs:
0x7ffed0c20690
0x7ffed0c20690
0x7ffed0c20690
0x7ffed0c20694
0x7ffed0c206a4
0x7ffed0c206a4
To me it looks like lines:
    int (*b)[5] = &x;
    int (*c)[5] = x;
achieve exact same result, because:
- they assign the same addres (in case of - *bit is the address of entire array and in case of- *cit is the address of the first array member but those two overlap) and
- assign same pointer size of 5 · - intfor- *band- *cwhich leads to the exactly same pointer arithmetics when I increment the values.
Q1: Are there any hidden differences between definitions of *b and *c that I am missing?
Q2: Does pointer arithmetics only depends on the size of the pointer?
After you pointed I noticed that I do get an error:
main.c:9:16: warning: initialization of ‘int (*)[5]’ from incompatible pointer type ‘int *’ [-Wincompatible-pointer-types]
  int (*c)[5] = x; // points to the 1st array element
 
    