На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (3) [1] 2 3  все  ( Перейти к последнему сообщению )  
> Есть логика в синтаксисе С++?
    Начал я изучать С++. Хотелось бы понять логику такого синтаксиса.

    Объявление переменной:

    Имя_типа Имя_переменной;

    Здесь все понятно.

    Далее объявление указателя на переменную:

    Имя_Типа * Имя_Переменной;

    Должно же быть какое-то согласование с предыдущим правилом. Что здесь считать типом, а что именем переменой? Можно считать, что Имя_типа* есть новый производный тип, тогда все согласуется.

    Массив определяется так:

    Имя_Типа Имя_Переменной [Размер];

    Массив на указатели определяется так:

    Имя_Типа * Имя_Переменной [Размер];

    Здесь также можно считать, что Имя_типа* есть новый производный тип указателя на тип Имя_типа, тогда все согласуется.

    Указатель на массив определяется так:

    Имя_Типа (*Имя_Переменной) [Размер];

    Здесь я не вижу логики. Аналогично с ссылками на функции. Конечно, эти правила можно зазубрить, но отсутствие логики меня очень расстраивает :no-sad:

    По-моему, так было бы логичнее:

    (Имя_Типа [Размер])* Имя_Переменной;

    Т.е. все согласуется с правилом объявления переменной Имя_типа Имя_переменной;


    Может быть нужно представить, что *Имя_Переменной - это как бы прототип операции разыменования и переменная после разыменования имеет тип Имя_Типа? Хотя все равно не вижу логики в Имя_Типа (*Имя_Переменной) [Размер];

    Может все-таки кто-то может объяснить?
    Сообщение отредактировано: S.Eugene -
      Когда-то давным-давно, то ли Кернигана, то ли Ричи, то ли обоих, что вряд ли, посетила гениальная мысль: а что если определение сущности будет иметь тот же синтаксис, что и её использование? Это позволит не вводить отдельного синтаксиса для объявлений и определений, ключевых слов и разделов в программе для этого, итп. Т.е. всё просто: вот сущность, синтаксис использования которой такой-то; чтобы её определить, достаточно её "использовать" точно так же, но предварить именем типа. Гениально. Например, определение указателя int* ptr; следует читать как "операция 'разыменования указателя', применённая к ptr, имеет результатом некий int" или более кратко "разыменовый ptr есть int". Массив: "применение операции 'индексирование' к такой-то переменной даёт такой-то тип", тут только одно специальное дополнение - вторым аргументом операции индексирования должен быть размер массива.
      Постольку поскольку использование сущности обычно выполняется в неком выражении, то и определение этой сущности обычно напоминает простое выражение. А выражения, состоя их отдельных операций, естественно рассматриваются с учётом приоритетов этих операций, для дополнительного управления которыми могут использоваться скобки. Например, int *array[N], ввиду большей приоритетности [] перед *, рассматривается как "индексированный array даёт нечто, что будучи разыменованным, даёт int", а для того, чтобы получить указатель на массив int, нужно увеличить приоритетность *, применив её к array, что и делается скобками: "разыменованный array даёт нечто, что будучи индексированным, даёт int".
      Что касается последней, наиболее "логичной" записи (что в некотором смысле справедливо, впрочем), то она бессмысленна ибо не раскладывается в корректное выражение. Ты либо умножаешь некий элемент массива на переменную, либо разыменовываешь переменную и никакой операцией не связываешь её с предшествующим выражением в скобках. В первом случае умножение никак не может определять указатель, во втором случае имеет место просто синтаксическаая ошибка, что-то типа "ожидалась бинарная операция".
        Можно было ответить короче: определения переменных читаются задом-наперёд.
          Это было бы неправдой:
          ExpandedWrap disabled
            int (*getOutFunc(size_t index))(const char*, ...)
            {
             static int (*funcs[])(const char*, ...) = { printf, debugOut, logOut };
             
             return index < sizeof(funcs)/sizeof(*funcs) ? funcs[index] : NULL;
            }
          К тому же ты просил объяснений, а как ты себе представляешь объяснения иначе? "Что такое вертикальные углы? - Это те, которые равные." Так, что ли?

          P.S. S.Eugene, ой, не ты. Звиняй :wub:
          Сообщение отредактировано: Qraizer -
            Не знаю, как там с указателями на функции - их я обычно не использую, разве что при "крайней необходимости" и "с закрытыми глазами", тупой копипастой - но вот со всем остальным работает такое правило: ищешь в определении название переменной, от него идёшь сначала направо, а потом налево. Порядок меняется скобками.
            То есть смотрим:
            ExpandedWrap disabled
              int *a[12]; // массив из указателей на int
              int (*a)[12]; // указатель на массив int'ов
              int *a[12][12]; // массив массивов указателей на int
              int (*a[12])[12]; // массив указателей на массив int'ов
            Так меня "в школе" научили.
            Если это распространится на указатели на функции - буду только рад. Но мне они до фени... )
              Цитата
              Например, определение указателя int* ptr; следует читать как "операция 'разыменования указателя', применённая к ptr, имеет результатом некий int" или более кратко "разыменовый ptr есть int".
              Значит я был прав в этой догадке про как бы разыменование. Замечательно придумано.

              А как для себя объясняете, что при объявлении переменных через запятую после "разыменованной" переменной все переменные считаются указателями?

              int x,*y,z; // z - тоже указатель

              Qraizer, спасибо. А то я уж думал бросить такое кривые Си учить. На душе прям полегчало :)
              Сообщение отредактировано: S.Eugene -
                S.Eugene, лучше таки брось.
                есть языки куда как получше, тот же C#
                  Цитата S.Eugene @
                  А как для себя объясняете, что при объявлении переменных одного через запятую после "разыменованной" переменной все переменные считаются указателями?

                  :wacko:
                  Цитата S.Eugene @
                  int x,*y,z; // z - тоже указатель

                  почему z дожен быть указателем ? ты там не видишь запятой ? или правило обявления переменных н езнаешь ? тыб почитал страуструпа чтоле бы для начала, глядишь и освоил бы...

                  Добавлено
                  И вообще это какаято "женская логика" мне кажеца :blush:

                  Добавлено
                  Цитата S.Eugene @
                  По-моему, так было бы логичнее:

                  (Имя_Типа [Размер])* Имя_Переменной;

                  интересно а вчем если не секрет тут заключаеться логика ???
                    Цитата
                    есть языки куда как получше, тот же C#

                    Нравятся мне такие утверждения... :) Лучше, хуже...
                    Если бы один язык был бы лучше другого, тот который хуже исчез бы вообще. Например как случилось с бейсиком (не вижуал бейсик, а тот, где 10 goto 10 :) )
                    А раз язык есть, то он для чего-то используется и лучше приспособлен для своей задачи
                      Цитата Hsilgos @
                      лучше приспособлен для своей задачи

                      а для задач ТСа?
                        Цитата S.Eugene @
                        А как для себя объясняете, что при объявлении переменных через запятую после "разыменованной" переменной все переменные считаются указателями?

                        int x,*y,z; // z - тоже указатель
                        z тут никакой не указатель.
                          Qraizer раскрыл тему. Но вообще, синтаксис С/С++ иногда преподносит сюрпризы. Страуструпу, кстати говоря, синтаксис С не нравился, он предлагал вводить альтернативные возможности построения конструкций, но не сложилось. Хотя в новом стандарте есть некоторые подвижки.
                            Цитата D_KEY @
                            он предлагал вводить альтернативные возможности построения конструкций, но не сложилось

                            А как тут сложится, если при внесении breaking changes тут же начинаются вопли по поводу компилябельности legacy-кода? Думаю, кстати, после принятия нового стандарта дело (в этом отношении) пойдёт лучше, потому что изменения в синтаксисе некоторых конструкций наблюдаются весьма существенные. Тут ведь главное - начать! :)
                              Цитата Qraizer @
                              ...вот сущность, синтаксис использования которой такой-то; чтобы её определить, достаточно её "использовать" точно так же, но предварить именем типа. Гениально.
                              Ну, говоря "гениально", я использовал богатство и выразительность русского языка. :whistle: Бывает, что такая гениальность оборачивается ассоциациями с "высокой модой" или там "высоким искусством". Специалисты в восторге, а нормальные люди, каковых на порядки больше, в афиге.
                                Qraizer, скорее так - теоретики в восторге, а те, кому с таким синтаксисом работать - в афиге.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (3) [1] 2 3  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0721 ]   [ 16 queries used ]   [ Generated: 20.06.25, 03:51 GMT ]