Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Хитрое объявление указателей в Си
Форум на CrossPlatform.RU > Разработка > С\С++
Litkevich Yuriy
const char * const * const listnames[] = {menu0, menu1};
как это читать?
Это указатель на указатель_на_масив?
DIMEDROLL
незнаю, но у меня не компилится такое в 2008 студии

а это компилится, и это указатель на массив
const char * const listnames[] = {"bbb", "aaa"};
Litkevich Yuriy
на шёл в списке проблем одного из компиляторов, как не поддерживаемая форма объявления. Стало быть по стандарту допустимая.
Алексей1153
а menu0, menu1 какой тип имеют ?

если я рассуждаю верно, то:

const char * const * const

- это тип элемента массива.

То есть:
    const char * const * const  i=0;   //элемент
    const char * const * const *pi=&i;  //указатель на i


два или больше "const" или "*const" подряд - эквивалентны одному. А это константный указатель на константный тип (этот указатель надо инициализировать сразу и менять далее нельзя)

    const char * const   i=0;
    const char * const  *pi=&i;


в итоге тип массива такой:

const char * const listnames[] = {"строка1", "строка2"};

-массив константных указателей на char
BRE
Цитата(Litkevich Yuriy @ 29.6.2011, 8:09) *
const char * const * const listnames[] = {menu0, menu1};
как это читать?
Это указатель на указатель_на_масив?

Это массив указателей на указатели char - по другому это двухмерный массив строк.



Цитата(DIMEDROLL @ 29.6.2011, 8:22) *
и это указатель на массив
const char * const listnames[] = {"bbb", "aaa"};

Нет, это массив указателей...
ViGOur
Цитата(Алексей1153 @ 29.6.2011, 10:21) *
const char * const listnames[] = {"строка1", "строка2"};

-массив константных указателей на char
массив константных указателей на константные указатели на константный тип char :p
Iron Bug
ViGOur прав.
Собственно, ничего сложного в объявлениях Си нет. Просто нужно с хвоста разбирать выражение и смотреть типы.
BRE
Цитата(Iron Bug @ 29.6.2011, 13:39) *
Собственно, ничего сложного в объявлениях Си нет. Просто нужно с хвоста разбирать выражение и смотреть типы.

Я бы уточнил... не с конца, а от самого идентификатора, и смотреть в операции слева и справа в зависимости от их приоритета.
Iron Bug
Цитата(BRE @ 29.6.2011, 14:51) *
не с конца, а от самого идентификатора, и смотреть в операции слева и справа в зависимости от их приоритета.

я не могу вообразить ни одного примера, чтобы не с конца. "операции" там - функции и массивы(постфиксные) и указатели и ссылки(префиксные). первые имеют приоритет над вторыми. а редкие случаи указателей на функции или массивы разруливаются обычными скобками. в общем, всё равно в итоге выйдет, что с конца :)
Litkevich Yuriy
Так надо бы раз и на всегда с этим покончить.
Есть:
1)
const1 char * listnames1

2)
const1 char * const2 listnames2

3)
const1 char * listnames3[]

4)
const1 char * const2 * const3 listnames4[]

"Читаем по слогам" (номера при const - условность):
1) указатель (* listnames1) на константный (const1) char
2) константный указатель (* const2 listnames2) на константный (const1) char
3) массив указателей (* listnames3[]) на константный (const1) char
4) константный массив (const3 listnames4[]) константных указателей (const2 *), на указатель на константный char (const1 char *)

Всё верно?

Может список пополнить ещё какими-то родственными объявлениями, кто что помнит?
Iron Bug
Цитата(Litkevich Yuriy @ 30.6.2011, 7:42) *
Может список пополнить ещё какими-то родственными объявлениями, кто что помнит?

разве что указатели на функции и массивы функций добавить.
Litkevich Yuriy
Цитата(Iron Bug @ 30.6.2011, 9:30) *
и массивы функций
чёт мне даже в голову не приходило, что и такое может быть :)
Приведи примеры пожалуйста.

Ещё не помешали бы примеры типа как в первом посте, но смесь указателей и ссылок (из реальной жизни).
Litkevich Yuriy
Цитата(Iron Bug @ 30.6.2011, 9:30) *
и массивы функций
чёт мне даже в голову не приходило, что и такое может быть :)
Приведи примеры пожалуйста.

Ещё не помешали бы примеры типа как в первом посте, но смесь указателей и ссылок (из реальной жизни).
Kagami
Техника, известная как «Чтение по спирали/по часовой стрелке» (“Clockwise/Spiral Rule”) позволяет любому программисту разобрать любое объявление языка Си - http://habrahabr.ru/blogs/cpp/100104/
Iron Bug
Цитата(Litkevich Yuriy @ 30.6.2011, 16:31) *
чёт мне даже в голову не приходило, что и такое может быть

  int (*foo)(char bar);

указатель на функцию, возвращающую int, с параметром char

int (*foo[])(char bar) = { foo1, foo2 };

массив указателей на функции, возвращающие int, с параметром char

int (*(*foo)[])(char bar);

указатель на массив указателей на функции, возвращающие int, с параметром char

ну и так далее, вариантов много. всякие там const по необходимости добавляются точно так же, как описано выше.

P.S. блин, аж сама запуталась, правила пару раз :)
Litkevich Yuriy
Цитата(Kagami @ 30.6.2011, 20:50) *
Техника, известная как «Чтение по спирали/по часовой стрелке» (”Clockwise/Spiral Rule”) позволяет любому программисту разобрать любое объявление языка Си - http://habrahabr.ru/blogs/cpp/100104/
нашёл там в комментариях интересную штуку, объясняет объявление. только нужно писать так:
int (*foo)(char)
вместо
int (*foo)(char bar)


Объявление из первого сообщения:
const char * const * const listnames[]
declare listnames as array of const pointer to const pointer to const char
Iron Bug
Цитата(Litkevich Yuriy @ 1.7.2011, 8:01) *
только нужно писать так:
int (*foo)(char)
вместо
int (*foo)(char bar)

без разницы. компилятор всё равно отбрасывает имя переменной в декларации. зато вот у подсказок будет дополнительная информация в виде названия, в котором обычно поясняется назначение переменной. когда смотришь на заголовочник, типы параметров ни о чём не говорят. когда видишь названия переменных - сразу всё становится понятно.
Алексей1153
Цитата
P.S. блин, аж сама запуталась, правила пару раз


для того и придумали его величество typedef )))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2024 IPS, Inc.