Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ С\С++ _ Хитрое объявление указателей в Си

Автор: Litkevich Yuriy 29.6.2011, 7:09

const char * const * const listnames[] = {menu0, menu1};
как это читать?
Это указатель на указатель_на_масив?

Автор: DIMEDROLL 29.6.2011, 7:22

незнаю, но у меня не компилится такое в 2008 студии

а это компилится, и это указатель на массив

const char * const listnames[] = {"bbb", "aaa"};

Автор: Litkevich Yuriy 29.6.2011, 7:35

на шёл в списке проблем одного из компиляторов, как не поддерживаемая форма объявления. Стало быть по стандарту допустимая.

Автор: Алексей1153 29.6.2011, 9:21

а 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 29.6.2011, 9:45

Цитата(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 29.6.2011, 9:52

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

-массив константных указателей на char
массив константных указателей на константные указатели на константный тип char :p

Автор: Iron Bug 29.6.2011, 12:39

ViGOur прав.
Собственно, ничего сложного в объявлениях Си нет. Просто нужно с хвоста разбирать выражение и смотреть типы.

Автор: BRE 29.6.2011, 12:51

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

Я бы уточнил... не с конца, а от самого идентификатора, и смотреть в операции слева и справа в зависимости от их приоритета.

Автор: Iron Bug 29.6.2011, 14:01

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

я не могу вообразить ни одного примера, чтобы не с конца. "операции" там - функции и массивы(постфиксные) и указатели и ссылки(префиксные). первые имеют приоритет над вторыми. а редкие случаи указателей на функции или массивы разруливаются обычными скобками. в общем, всё равно в итоге выйдет, что с конца :)

Автор: Litkevich Yuriy 30.6.2011, 5:42

Так надо бы раз и на всегда с этим покончить.
Есть:
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 30.6.2011, 6:30

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

разве что указатели на функции и массивы функций добавить.

Автор: Litkevich Yuriy 30.6.2011, 13:27

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

Ещё не помешали бы примеры типа как в первом посте, но смесь указателей и ссылок (из реальной жизни).

Автор: Litkevich Yuriy 30.6.2011, 13:31

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

Ещё не помешали бы примеры типа как в первом посте, но смесь указателей и ссылок (из реальной жизни).

Автор: Kagami 30.6.2011, 17:50

Техника, известная как «Чтение по спирали/по часовой стрелке» (“Clockwise/Spiral Rule”) позволяет любому программисту разобрать любое объявление языка Си - http://habrahabr.ru/blogs/cpp/100104/

Автор: Iron Bug 30.6.2011, 19:10

Цитата(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 1.7.2011, 6:01

Цитата(Kagami @ 30.6.2011, 20:50) *
Техника, известная как «Чтение по спирали/по часовой стрелке» (”Clockwise/Spiral Rule”) позволяет любому программисту разобрать любое объявление языка Си - http://habrahabr.ru/blogs/cpp/100104/
нашёл там в комментариях http://cdecl.org/, объясняет объявление. только нужно писать так:
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 1.7.2011, 7:11

Цитата(Litkevich Yuriy @ 1.7.2011, 8:01) *
только нужно писать так:
int (*foo)(char)
вместо
int (*foo)(char bar)

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

Автор: Алексей1153 1.7.2011, 19:59

Цитата
P.S. блин, аж сама запуталась, правила пару раз


для того и придумали его величество typedef )))

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)