На многих языках (широкий список, от C до JavaScript):
- запятые
,
отдельные аргументы (напримерfunc(a, b, c)
), в то время как - точки с запятой
;
разделяют последовательные инструкции (напримерinstruction1; instruction2; instruction3
).
Так почему же это отображение в тех же языках для циклов for :
for ( init1, init2; condition; inc1, inc2 )
{
instruction1;
instruction2;
}
вместо (что кажется мне более естественным)
for ( init1; init2, condition, inc1; inc2 )
{
instruction1;
instruction2;
}
?
Конечно, for
это ( как правило) не функция, но аргументы (то есть init
, condition
, increment
) ведут себя скорее как аргументы функции , чем последовательность инструкций.
Это связано с историческими причинами / соглашением, или есть хорошее обоснование для обмена ,
и ;
в циклах?
programming-languages
syntax
loops
Петр Мигдаль
источник
источник
;
не используем|
?» (или почему мы используем «иначе», а не «иначе»? )), что не относится к одному языку, но к большому количеству из них. Ответ, например, «это было сделано в C как сокращение для цикла while (а несколько операторов для inc были продуманы только позже), и люди не хотели менять его, чтобы избежать раздражения программистов», был бы совершенно нормальным.Ответы:
Технически, отображение не «обратное».
В действительности у нас есть другой синтаксический контекст, в котором одни и те же символы используются по-разному. Мы не сравниваем подобное с подобным, поэтому нет сопоставления и нет веских аргументов в пользу согласованного сопоставления, основанного на семантической согласованности.
Так почему бы не сделать это наоборот?
Ну, я думаю, что причины происходят от "естественного" значения
,
и;
. В английском письменном языке точка с запятой является «более сильным» разрывом, чем запятая, а символ точки с запятой более заметен, чем запятая. Эти две вещи объединяются, чтобы сделать текущую аранжировку (для меня!) Более естественной.Но единственный способ точно узнать, почему был сделан выбор синтаксиса, - это если бы разработчики C могли рассказать нам, что они думали в 1970 году. Я сомневаюсь, что у них есть четкая память о технических решениях, принятых так давно.
Я не знаю ни одного языка до C, который использовал C-подобный синтаксис для циклов for:
Донал Феллоуз отмечает, что BCPL и B не имели эквивалентной конструкции.
Эквиваленты FORTRAN, COBOL и Algol-60 (и Pascal) были менее выразительными и имели синтаксисы, которые не напоминали синтаксис «для» C.
Но такие языки, как C, C ++ и Java, появившиеся после C, явно заимствуют свой синтаксис "for" из C.
источник
,
против;
) является (слабее против сильного разрыва), а не (кортеж против делителя последовательности), верно? Тем не менее, для меня не очевидно, требуют ли аргументы или операторы более сильных разрывов (как во многих случаях для последовательности операторов, разрывы являются неявными (см., Например, JavaScript (напримерi++[line break]j++
))), но, по крайней мере, теперь я понимаю, почему текущее соглашение не "явно перевернутый".FOR i = e1 TO e2 BY e3 DO c
(выражения e1..e3, команда c), что больше напоминает синтаксис BASIC. Источникfor
синтаксис был введен в C (это не было в B или BCPL).Мы пишем циклы как:
Язык можно было бы определить так, чтобы циклы выглядели так:
Однако подумайте о том же цикле, реализованном с использованием цикла while:
Обратите внимание, что операторы
x=0
иx++
являются окончанием точкой с запятой. Они не являются выражениями, как вы бы при вызове функции. Точки с запятой используются для разделения операторов, и поскольку два из трех элементов в цикле for являются операторами, это то, что используется там. Цикл for - это просто ярлык для такого цикла while.Кроме того, аргументы не действуют как аргументы функции. Второе и третье оцениваются неоднократно. Это правда, что они не являются последовательностью, но они также не являются аргументами функций.
Кроме того, тот факт, что вы можете использовать запятые для нескольких операторов в цикле for, - это то, что вы можете делать вне цикла for.
является совершенно допустимым утверждением даже вне цикла for. Я не знаю ни одного практического использования вне цикла for. Но дело в том, что запятые всегда делят утверждения; это не особенность цикла for.
источник
x = 0; y = 0;
и (внутри фигурной скобки)x++; y++;
...;
это естественно для последовательности утверждений , не обязательно разделяющих какие-либо утверждения (так это просто, что вкусы различаются?). И в нынешнем соглашении иногда случается так, что в любом случае отдельные последовательности операторов ставятся запятыми ...(foo)?bar++, qux++:bletch
- где вы хотите, чтобы?:
выражение делало две вещи, а не одну. Возвращаемое значение, еслиfoo
истинноqux
, но обаbar
иqux
получают приращение.В C и C ++ это оператор запятой, а не просто запятая.
Грамматика для
for
цикла это что-то вродеВ случае вашего вопроса:
Обратите внимание, что оператор запятой позволяет вам выполнять несколько действий в одном выражении (как это видит компилятор). Если бы ваше предложение было реализовано, в грамматике была бы неоднозначность относительно того, когда программист намеревался написать оператор запятой или разделитель.
Короче говоря,
;
означает конец утверждения.for
Цикл является ключевым словом , за которым следует список дополнительных заявлений в окружении()
. Оператор запятой-оператора позволяет использовать,
в одном операторе.источник
for
цикла явно допускает оператор (объявление) в качестве его первой части. (C ++ допускает объявления mid-функции, в отличие от своего предшественника C89). Вы не можете обобщать такие операторы между языками, даже для 2 языков, таких как C и C ++.for ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement>
для C иfor ( for-init-statement; conditionopt ; expressionopt ) statement
для C ++ --- ';' не только означает терминатор оператора. За циклом for не следуют операторы, заключенные в ().Там нет концептуального обращения.
Точки с запятой в C представляют собой более крупные деления, чем запятые. Они разделяют заявления и декларации.
Основным делением в цикле for является то, что есть три выражения (или объявление и два выражения) и тело.
Запятые, которые вы видите в C для циклов for, не являются частью синтаксиса цикла for. Они просто проявления оператора запятой.
Запятые являются основными разделителями между аргументами в вызовах функций и между параметрами в объявлениях функций, но точки с запятой не используются. Цикл for - это специальный синтаксис; это не имеет ничего общего с функциями или вызовами функций.
источник
Может быть, это что-то особенное для C / C ++, но я публикую этот ответ, потому что синтаксис описанных вами языков в основном зависит от C-синтаксиса.
Кроме того, ранее отвеченные вопросы верны, с технической точки зрения, это также потому, что в C (и C ++) запятая на самом деле является оператором , который вы можете даже перегружать . Использование точки с запятой-оператора (
operator;()
) может затруднить написание компиляторов, поскольку точка с запятой - это терминатор аксиоматического выражения.Интересным является тот факт, что запятая широко используется в качестве разделителя во всем языке. Кажется, что оператор запятой является исключением, который в основном используется для получения
for
-loops с несколькими работающими условиями, так в чем же дело?Фактически,
operator,
он создан для того же, что и в определениях, списках аргументов и т. Д. Он был создан для разделения выражений - то, что синтаксическая конструкция,
не может сделать. Он может отделять только то, что определено в стандарте.Однако точка с запятой не разделяется - она заканчивается . И это также то, что возвращает нас к первоначальному вопросу:
Запятая разделяет выражения в трех частях цикла, тогда как точка с запятой завершает часть (инициализация, условие или запоздалая мысль) определения цикла.
Более новые языки программирования (такие как C #) могут не допускать перегрузки оператора запятой, но они, скорее всего, сохранили синтаксис, потому что его изменение кажется неестественным.
источник
for
утверждении;
символ явно используется в качестве разделителя. Он разделяет 3 синтаксические части утверждения. Нет 3-й точки с запятой, чтобы «завершить» список прогрессивных выражений. Завершается другим токеном)
.Для меня они используются более менее похожим по смыслу своим языковым смыслом. Запятые используются со списками и точками с запятой с несколькими отдельными частями.
У
func(a, b, c)
нас есть список аргументов.instruction1; instruction2; instruction3
это может быть список, но список отдельных и независимых инструкций.В то время как у
for ( init1, init2; condition; inc1, inc2 )
нас есть три отдельные части - список инициализаций, условие и список выражений приращения.источник
Самый простой способ увидеть это:
является:
Другими словами, эти x = 0 вещь на самом деле является оператором / инструкциями, а не параметром. Вы вставляете туда заявление. Следовательно, они разделяются точкой с запятой.
На самом деле нет никакого способа, которым они разделяются запятой. Когда в последний раз вы вставляете такие вещи, как х <10 в качестве параметра? Вы делаете это, если хотите, чтобы компьютер x <10 один раз, и вставляете результат этой операции в качестве параметра. Так что в мире запятых вы бы поставили x <10, если хотите передать значение x <0 в функцию.
Здесь вы указываете, что программа должна проверять x <10 каждый раз, когда проходит цикл. Так что это инструкция.
х ++ это определенно другая инструкция.
Это все инструкции. Поэтому они разделены точкой с запятой.
источник
for
switch
илиreturn
внутри определения цикла for (т.е.for(int i = 0; if(i > 1024) { return; } ; switch (i % 3) { case 0; case 1: i++; case 2: i++; } ) { ... }
) - вы не можете. Это не утверждение. Вместо этого это определено какfor ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement>
int i = 0
определенно НЕ является выражением. Набор правил, описывающих выражение, довольно сложен, учитывая, что может составлять выражение, но конструкция неTYPE NAME = EXPRESSION
соответствует ни одному из этих правил.