string
- это массив из 20 элементов char
- вы можете хранить строку длиной до 19 символов (необходимо зарезервировать один элемент для ограничителя строки) или вы можете сохранитьпоследовательность из 20 символов, которая не представляет строку (например, значение хеша или что-то в этом роде).
За исключением случаев, когда он является операндом операторов sizeof
или унарных &
, выражение типа "массив N-элементов из T
" будет преобразовано ("распад"") на выражение типа" указатель на T
", и его значением будет адрес первого элемента массива.
Итак, если вы передали string
в качестве аргумента функции, например:
f( string );
то, что функция на самом деле получает, является значением указателя:
void f( char *somestring ) { ... }
В контексте объявления параметра функции (и только в этом контексте), T a[N]
и T a[]
оба обрабатываются как T *a
, так что вы можете объявить f
любым из
void f( char somestring[20] ) { ... }
или
void f( char somestring[] ) { ... }
.
Оператор индекса []
определен для работы с выражениями указателей, а также с выражениями массивов, поэтому вы все равно можете использовать []
для индексации в somestring
, как и любой другой массив:
void f( char *somestring )
{
int i = 0;
while ( somestring[i++] )
{
// do something interesting with somestring[i]
}
}
Итак, если void f( char *somestring )
совпадает с void f( char somestring[] )
, то что мы делаем из
void f( char *somestring[] )
?
В этом случае ясно, что somestring
должен быть массивом указателей на char
, что-то вроде
char *strings[] = {"foo", "bar", "bletch", ... };
Каждый strings[i]
хранит адрес соответствующего строкового литерала, а несодержимое самой строки.По тому же правилу, приведенному выше, прототип также может быть записан как
void f( char **somestring ) { ... }
или
void f( char *somestring[N] ) { ... }
Единственное, что somestrings
- это , а не , в данном случае2D массив char
.Если бы strings
было объявлено
#define N ... // number of strings
#define M ... // maximum length of string
char strings[N][M+1] = {"foo", "bar", "bletch", ... };
, то, если мы передадим strings
в f
, он будет "затухать" до
void f( char (*somestrings)[M+1] ) { ... }
Тип strings
- это «N-элементный массив из M + 1-элементного массива char
», поэтому выражение «затухает» в «указатель на M + 1-элементный массив из char
».