In my textbook, it says that we have a pointer to a pointer to the 0th element of an integer array.
Your textbook is ... badly worded, let's leave it at that. It's a pointer to a 10-element array of int.
I can kind of see where the book is coming from. Given the declaration
int (*a)[10];
the expression *a will have type int [10] (10-element array of int). However, unless that expression is the operand of the sizeof or unary & operators, it will be converted ("decay") from type int [10] to int *, and the value of the expression will be the address of the first element of the array:
Expression Type "Decays" to Value
---------- ---- ----------- -----
*a int [10] int * Address of first element of the array;
equivalent to `&(*a)[0]`.
Thus, if I call a function like
foo( *a );
what the function actually receives will be a pointer to the first element of the pointed-to array (its type will be int *, not int **).
So in effect, yes, a often winds up behaving as a pointer to a pointer to the first element of the array; however, its type is not "pointer to pointer to int", and type matters. Given:
int (*a)[10];
int **b;
then you'll get different behavior for the following:
sizeof *a vs. sizeof *b
a + i vs b + i (also applies to a++ vs b++)