Правило для C следующее:
6.3.2.1 L-значения, массивы и обозначения функций
...
3 Кромекогда это операнд оператора sizeof или унарный оператор & , или строковый литерал, используемый для инициализации массива, выражение, имеющее тип '' массив типа ''преобразуется в выражение с типом '' указатель на тип '', которое указывает на начальный элемент объекта массива и не является lvalue.Если объект массива имеет класс хранения регистров, поведение не определено.
Язык для C ++ немного отличается:
4.2 Преобразование массива в указатель [conv.array]
1 Значение l или значение типа «массив NT» или «массив неизвестных границ T» может быть преобразовано в значение типа «указатель на T».Результатом является указатель на первый элемент массива.
...
8.3.4 Массивы [dcl.array]
...
7 Согласованное правилосопровождается для многомерных массивов.Если E является n-мерным массивом ранга i × j × ... × k , то E, появляющийся в выражении, преобразуется в указатель на( n -1) -мерный массив с рангом j × ... × k .Если к этому указателю применяется оператор *, явный или неявный, как результат подписки, то результатом является указательный ( n -1) -мерный массив, которыйСам сразу превращается в указатель.
Таким образом, справедливо следующее:
Declaration Expression Type Decays to
----------- ---------- ---- ---------
T a[N] a T [N] T *
&a T (*)[N]
*a T
a[i] T
T a[M][N] a T [M][N] T (*)[N]
&a T (*)[M][N]
*a T [N] T *
a[i] T [N] T *
&a[i] T (*)[N]
*a[i] T
a[i][j] T
T a[M][N][O] a T [M][N][O] T (*)[M][N]
&a T (*)[M][N][O]
*a T [M][N] T (*)[N]
a[i] T [M][N] T (*)[N]
&a[i] T (*)[M][N]
*a[i] T [N] T *
a[i][j] T [N] T *
&a[i][j] T (*)[N]
*a[i][j] T
a[i][j][k] T
Шаблон должен быть четким для массивов более высокой размерности.
Итак, давайте проанализируем ваш словарь:
/* list of words and meanings */
char *dic[][40] = {
"atlas", "A volume of maps.",
"car", "A motorized vehicle.",
"telephone", "A communication device.",
"airplane", "A flying machine.",
"", "" /* null terminate the list */
};
Это не настроит ваш словарь так, как вы хотите;Вы в основном настроили это как массив из 1 элемента из 40 указателей на символ.Если вам нужен массив пар строк, то объявление должно выглядеть следующим образом:
char *dic[][2] =
{
{"atlas", "A volume of maps"},
{"car", "A motorized vehicle"},
{"telephone", "A communication device"},
{"airplane" , "A flying machine"},
{NULL, NULL} // empty strings and NULLs are different things.
};
Тип dic
- это «5-элементный массив из 2-элементных массивов указателя на char»,или char *[5][2]
.Если следовать правилам, приведенным выше, выражение dic
должно уменьшиться до char *(*)[2]
- указатель на массив из 2 элементов с указателем на тип char.
Функция для поиска в этом словаре будет выглядеть следующим образом:
char *definition(char *term, char *(*dictionary)[2]) // *NOT* char ***dictionary
{
while ((*dictionary)[0] != NULL && strcmp((*dictionary)[0], term) != 0)
dictionary++;
return (*dictionary)[1];
}
, и вы будете вызывать ее из своей основной функции, например
char *def = definition(term, dic);
Обратите внимание, чтоиспользовать скобки вокруг выражения *dictionary
в функции.Оператор индекса массива []
имеет более высокий приоритет, чем оператор разыменования *
, и мы не хотим напрямую вставлять в dictionary
, мы хотим вставить индекс в массив, который dictionary
указывает на .