Intereting Posts
Можно ли запрограммировать только для Windows Phone 7 в стандартном C ++? Расширение типов перечислений Расширение с вариационными шаблонами Как получить индекс типа в пакете с вариационным типом? g ++ рассматривает возвращаемый строковый литерал как const char pointer not const char array Использует alloca () для массивов переменной длины лучше, чем использование вектора в куче? Плагин c ++: передать объект через границу (эмуляция) Файлы с отображением памяти, управляемый указатель на файл и смещение PCC-S-02015, не удалось открыть файл include Список файлов заголовков в проекте Visual Studio C ++, созданный cmake Предупреждение Анонимное пространство имен внутри структуры с помощью указателя функции Явный конструктор копирования Копирование полученных объектов с использованием только указателей базового classа (без исчерпывающего тестирования!) – C ++ Можете ли вы создать std :: map унаследованных classов? Связь между streamом сервера и интерфейсом man-machine (MMI)

Почему вы не можете объявить переменную внутри части выражения цикла while?

Приведен следующий синтаксис:

while (int i = get_data()) { } 

Но следующее:

 do { } while (int i = get_data()); 

Мы можем понять, почему в рамках проекта стандарта:

[N4140/6.4]

1 […]

  состояние :
      выражение
      attribute-specifier-seq opt decl-specifier-seq declarator = initializer-clause
      attribute-specifier-seq opt decl-specifier-seq declarator braced-init-list 

2 Правила условий применяются как к операторам выбора, так и к операторам for и while (6.5). […]

[N4140/6.5]

1 Операторы итерации задают цикл.

  итерация-заявление: 
              while ( условие )
              do statement while ( выражение ); 

Вместо этого вы вынуждены делать что-то некрасивое, как:

 int i = get_data(); do { } while ((i = get_data())); // double parentheses sic 

В чем причина этого?

Похоже, что определение области охвата будет проблемой, какова будет область действия i объявленной во while действия инструкции do while ? Было бы неестественно иметь переменную, доступную в цикле, когда декларация фактически находится ниже самого цикла. У вас нет этой проблемы с другими циклами, так как объявления появляются перед телом цикла.

Если мы посмотрим на проект стандарта C ++, см. Раздел 6.5.1 Оператор while, который для оператора while, который:

 while (T t = x) statement 

эквивалентно:

 label: { // start of condition scope T t = x; if (t) { statement goto label; } } // end of condition scope 

а также:

Переменная, созданная в состоянии, уничтожается и создается с каждой итерацией цикла.

Как мы сформулируем это для do while дела?

и как cdhowie указывает, если мы посмотрим на раздел 6.5.2 Оператор do, который он говорит ( акцент мой ):

В операторе do подстановка выполняется несколько раз, пока значение выражения не станет ложным. Тест выполняется после каждого выполнения инструкции.

что означает, что тело цикла оценивается до того, как мы даже достигнем объявления.

Хотя мы могли бы создать исключение для этого случая, это нарушит наш интуитивный смысл, что в целом точка объявления для имени – это после того, как мы увидим полное объявление ( с некоторыми исключениями, например, переменные-члены classа ) с нечеткими преимуществами. Точка декларации описана в разделе 3.3.2 .

Есть несколько причин, почему это было бы трудно разрешить.

Язык придерживается общего правила, согласно которому все должно быть объявлено выше точки использования. В этом случае переменная, объявленная в do-while , будет объявлена ниже ее ожидаемой естественной области (тела цикла). Предоставление этой переменной в цикле потребовало бы специальной обработки циклов do-while . Несмотря на то, что мы знаем примеры такого специального обращения (например, в classах членов-членов classа можно увидеть всех членов classа, включая те, которые указаны ниже ), вероятно, не так много практического смысла в выполнении циклов do-while .

В случае do-while эти специальные правила обработки также потребуют поиска значимого способа обработки инициализации переменных, объявленных таким образом. Обратите внимание, что на языке C ++ время жизни такой переменной ограничено одной итерацией цикла, т. Е. Переменная создается и уничтожается на каждой итерации. Это означает, что для цикла do-while переменная всегда останется неинициализированной, если вы не вводите какое-либо правило, которое каким-то образом перенесет инициализацию в начало тела цикла. По моему мнению, это будет довольно сложно.

Было бы очень неестественно иметь объявление i после блока и затем иметь доступ к нему в блоке. Декларация for и в while – это хорошие короткие руки, которые используют ограниченную область применения для переменной, которая необходима в логике цикла.

Чистое сделать так:

 int i; do { i = get_data(); // whatever you want to do with i; } while (i != 0); 

Это происходит потому, что все остальное следует за практикой объявления переменных перед их использованием, например:

 public static void main(String[] args){ // scope of args } for(int i=1; i<10; i++){ // scope of i } { ... int somevar; //begin scope of var ... //end of scope of var } 

Это связано с тем, что вещи разбираются сверху вниз, и потому, что в соответствии с этим соглашением вещи остаются интуитивными, поэтому вы можете объявить некоторое время (int var <10), потому что область этого var будет областью внутри цикла после объявления.

Делать пока не имеет смысла объявлять переменную, потому что область действия будет заканчиваться, в то же время она будет проверяться, потому что это когда этот блок закончен.

Добавь это

 #define do(cond) switch (cond) do default: 

в начале вашего кода.

Теперь вы можете написать

 do (int i = get_data()) { // your code } while ((i = get_data())); 

Важно, чтобы этот #define не нарушал исходный синтаксис ключевого слова do в цикле do-while.

Однако я признаю, что это неясно.

Ваш первый синтаксис действителен, а второй – нет. Тем не менее, ваш цикл while будет работать навсегда, даже если ваша функция get_data () возвращает 0. Не уверен, что это именно то, что вы хотите.