If you have a pointer to an object of some type, such as
T *p = &obj;
so that with this pointer you can perform pointer arithmetic or dereference a pointer, you need to know the size of the object addressed by the pointer. In other words, you need to know the value of sizeof( T ) .
For example, if there is an expression ++p , the question arises: how much should the value stored in the pointer increase? Obviously, after this operation, the pointer must point to a place in memory after this object (or the next element of the array if the current object is an element of the array), that is, the pointer value must increase by the sizeof( obj ) size sizeof( obj ) . This means that the size of the object pointed to by the pointer must be known to the compiler.
Therefore, for this function
void a_f(char str[][10]) /// !!! Если менять правый индекс то программа будет выводить адреса с интервалами которые равны индексу (сейчас это зафиксированно и указатель никак не меняется!) { int i = 4; while(i >= 0) { printf("%s - %p\n", str+i, str+i); --i; } }
which is called with an argument declared as a two-dimensional array
char a[][10] = {"hello", "world", "again", "repeat", "stop"};
the function parameter declared as an array is implicitly cast to the type of the pointer to the array element. In turn, the argument, that is, the two-dimensional array a , is converted implicitly to a pointer to its first element.
The element of this two-dimensional array is, in turn, a one-dimensional array having the type char[10] Therefore, if you have a pointer to the first element of this two-dimensional array, then to change it so that it points to the next, that is, the second element of the array, its value must be increased by the size of the addressable element. The size of the addressed element, that is, a one-dimensional array, is equal to sizeof( char[10] ) . The function must know the size of this addressable array in order to properly perform operations with pointers.
Thus a parameter of a function declared as
void a_f(char str[][10]);
is cast to type
void a_f(char ( *str )[10]);
that is, a pointer to an element of the array.
In turn, an array specified as a function argument is also converted to a pointer to its first element. This can be represented as follows.
char ( *tmp )[10] = a; a_f( tmp );
Given this information about the size of the object (which is equal to sizeof( char[10] ), pointed to by the pointer char (* str) [10]), declared as a function parameter, the function can correctly calculate the expression str+i , which is equal to the value stored in str , plus a value of i * 10 * sizeof( char ) . That is, as a result, the pointer str would point to the i -th element of a two-dimensional array, the size of which element is 10 . This is the meaning of pointer arithmetic.
To make it clearer, you could introduce an alias of the type of the element of a dimensional array as follows
typedef char T[10]; // ... T a[] = {"hello", "world", "again", "repeat", "stop"};
In turn, the function declaration will look like
void a_f( T *str );
or how
void a_f( T str[] );
These two declarations declare the same function.
Therefore, the size of the object pointed by the pointer will be equal to sizeof( T ) , which, according to the alias entered, is equal to sizeof( char[10] )
[][0]and why 0. - Qwertiy ♦