Выражение против утверждения

Сделайте SELECT с предложением GROUP BY. Скажем, name - это столбец, в котором вы хотите найти дубликаты:

SELECT name, COUNT(*) c FROM table GROUP BY name HAVING c > 1;

Это вернет результат с именем name в первом столбце , и количество раз, сколько раз это значение появляется во втором.

421
задан Matthew Murdoch 4 July 2012 в 09:39
поделиться

11 ответов

Выражение: Что-то, что оценивает к значению. Пример: оператор 1+2/x
: строка А кода, который делает что-то. Пример: GOTO 100

На самых ранних языках программирования общего назначения, как ФОРТРАН, различие было совершенно ясно. В ФОРТРАНЕ оператор был одной единицей выполнения, вещь, которую Вы сделали. Единственная причина это не назвали "строкой", состояла в том, потому что иногда это охватывало несколько строк. Выражение самостоятельно ничего не могло сделать..., что необходимо было присвоить его переменной.

1 + 2 / X

ошибка в ФОРТРАНЕ, потому что он ничего не делает. Необходимо было сделать что-то с тем выражением:

X = 1 + 2 / X

ФОРТРАН не имел грамматики, поскольку мы знаем это today— та идея была изобретена, наряду с Формой Бэкуса-Наура (BNF), как часть определения Алгола 60. В той точке семантический различие ("имеют значение" по сравнению с, "делает что-то"), хранился в [1 115] синтаксис : один вид фразы был выражением, и другой был оператором, и синтаксический анализатор мог сказать им независимо.

Разработчики более поздних языков размыли различие: они позволили синтаксическим выражениям делать вещи, и они позволили синтаксические операторы, которые имели значения. Самым ранним популярным примером языка, который все еще выживает, является C. Разработчики C поняли, что никакой вред не был причинен, если Вам разрешили оценить выражение и выбросить результат. В C каждое синтаксическое выражение может быть превращенным в оператор только путем прикрепления точки с запятой вдоль конца:

1 + 2 / x;

полностью законный оператор даже при том, что абсолютно ничего не произойдет. Точно так же в C, выражение может иметь побочные эффекты — это может изменить что-то.

1 + 2 / callfunc(12);

, потому что callfunc мог бы просто сделать что-то полезное.

, Как только Вы позволяете любому выражению быть оператором, Вы могли бы также позволить оператор присваивания (=) в выражениях. Вот почему C позволяет Вам сделать вещи как [1 126]

callfunc(x = 2);

, Это оценивает выражение x = 2 (присвоение значения 2 к x) и затем передает это (2) к функции callfunc.

Это размывание выражений и операторов происходит во всех C-производных (C, C++, C# и Java), которые все еще имеют некоторые операторы (как while), но которые позволяют почти любому выражению использоваться в качестве оператора (в C# только присвоение, назовите, увеличьте, и декрементные выражения могут использоваться в качестве операторов; см. ответ Scott Wisniewski ).

Наличие двух "синтаксических категорий" (который является техническим именем для вида вещи, которая операторы и выражения) может привести к дублированию усилия. Например, C имеет две формы условного выражения, форма оператора

if (E) S1; else S2;

и форма выражения

E ? E1 : E2

, И иногда люди хотят дублирование, которое не является там: в стандарте C, например, только оператор может объявить новый локальный variable— но эта способность достаточно полезна, что компилятор C GNU обеспечивает расширение GNU, которое позволяет выражению объявить локальную переменную также.

Разработчикам других языков не нравился этот вид дублирования, и они видели рано на что, если выражения могут иметь побочные эффекты, а также значения, то синтаксический различие между операторами и выражениями не все это useful— таким образом, они избавились от него. Haskell, Значок, Lisp и ML являются всеми языками, которые не имеют синтаксического statements— у них только есть выражения. Даже класс структурировал цикличное выполнение, и условные формы считают выражениями, и у них есть values— но не очень интересные.

510
ответ дан scohe001 4 July 2012 в 09:39
поделиться

Выражения могут быть оценены для получения значения, тогда как операторы не возвращают значение (они имеют тип пусто ).

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

Ориентированный на оператор на языки требуют, чтобы все процедуры были списком операторов. Ориентированные на выражение языки, который является, вероятно, всеми функциональными языками, являются списками выражений, или в tha случае LISP, одно долгое S-выражение, которое представляет список выражений.

, Хотя оба типа могут быть составлены, большинство выражений может быть составлено произвольно, пока типы совпадают. Каждый тип оператора поступает по-своему создания других операторов, если они могут сделать это все. Foreach и если операторы требуют или единственного statment или что все зависимые операторы входят в блок операторов, один за другим, если подоператоры не допускают свои собственные подоператоры.

Операторы могут также включать выражения, где выражение действительно не включает операторов. Одним исключением, тем не менее, было бы лямбда-выражение, которое представляет функцию, и так может включать что-либо, что функция может iclude, если язык только не допускает ограниченные лямбды, как лямбды отдельного выражения Python.

На основанном на выражении языке, все, в чем Вы нуждаетесь, является отдельным выражением для функции, так как все управляющие структуры возвращают значение (многие из них возвращают NIL). Нет никакой потребности в операторе возврата, так как оцененное в последний раз выражение в функции является возвращаемым значением.

5
ответ дан Mark Cidade 4 July 2012 в 09:39
поделиться

Просто: выражение оценивает к значению, оператор не делает.

5
ответ дан Matthew Schinckel 4 July 2012 в 09:39
поделиться

Можно найти это на Википедия , но выражения оценены к некоторому значению, в то время как операторы не имеют никакого оцененного значения.

Таким образом, выражения могут использоваться в операторах, но не наоборот.

Примечание, что некоторые языки (такие как Lisp, и я верю Ruby и многим другим) не дифференцируют оператор по сравнению с выражением... на таких языках, все - выражение и может быть объединено в цепочку с другими выражениями.

8
ответ дан Mike Stone 4 July 2012 в 09:39
поделиться

Выражение - что-то, что возвращает значение, тогда как оператор не делает.

Для примеров:

1 + 2 * 4 * foo.bar()     //Expression
foo.voidFunc(1);          //Statement

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

14
ответ дан Patrick 4 July 2012 в 09:39
поделиться

Я хотел бы сделать маленькое исправление к ответу Joel выше.

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

, Например, компилятор C# отметит следующий код как синтаксическую ошибку:

1 + 2;

53
ответ дан Scott Wisniewski 4 July 2012 в 09:39
поделиться
  • выражение - что-либо, что приводит к значению: 2 + 2
  • оператор является одним из основных "блоков" выполнения программы.

Примечание, которое в C, "=" является на самом деле оператором, который делает две вещи:

  • возвраты значение правого подвыражения.
  • копии значение правого подвыражения в переменную на левой стороне.

Вот является извлечение из ANSI C грамматикой. Вы видите, что C не имеет многих различных видов операторов..., большинство операторов в программе является операторами выражения, т.е. выражением с точкой с запятой в конце.

statement
    : labeled_statement
    | compound_statement
    | expression_statement
    | selection_statement
    | iteration_statement
    | jump_statement
    ;

expression_statement
    : ';'
    | expression ';'
    ;

http://www.lysator.liu.se/c/ANSI-C-grammar-y.html

21
ответ дан Mark Harrison 4 July 2012 в 09:39
поделиться

Некоторые вещи об основанных на выражении языках:

<час>

самый важный: Все возвращает значение

<час>

нет никакого различия между фигурными скобками и не заключает в фигурные скобки для разграничивания блоков кода и выражений, так как все - выражение. Это не предотвращает лексический обзор хотя: локальная переменная могла быть определена для выражения, в котором содержится его определение, и все операторы содержатся в этом, например.

<час>

На основанном на выражении языке, все возвращает значение. Это может быть немного странно сначала - Что делает (FOR i = 1 TO 10 DO (print i)) возврат?

Некоторые простые примеры:

  • (1) возвраты 1
  • (1 + 1) возвраты 2
  • (1 == 1) возвраты TRUE
  • (1 == 2) возвраты FALSE
  • (IF 1 == 1 THEN 10 ELSE 5) возвраты 10
  • (IF 1 == 2 THEN 10 ELSE 5) возвраты 5

Пара более сложных примеров:

  • Некоторые вещи, такие как некоторые вызовы функции, действительно не имеют значимого значения для возврата (Вещи, которые только производят побочные эффекты?). Вызов OpenADoor(), FlushTheToilet() или TwiddleYourThumbs() возвратит своего рода приземленное значение, такой как хорошо, Сделанный, или Успех.
  • , Когда несколько расцепляемых выражений оценены в рамках одного большего выражения, значение последней вещи, оцененной в большом выражении, становится значением большого выражения. Для взятия примера [1 118] значение для цикла равняется "10", это заставляет (print i) выражение быть оцененным 10 раз, каждый раз возвращаясь i как строка. Заключительное время посредством возвратов 10, наш окончательный ответ
<час>

Это часто требует, чтобы небольшое изменение мышления получило все возможное от основанного на выражении языка, так как то, что все - выражение, позволяет 'встроить' много вещей

Как быстрый пример:

 FOR i = 1 to (IF MyString == "Hello, World!" THEN 10 ELSE 5) DO
 (
    LotsOfCode
 )

совершенно допустимая замена для не основанный на выражении

IF MyString == "Hello, World!" THEN TempVar = 10 ELSE TempVar = 5 
FOR i = 1 TO TempVar DO
(    
    LotsOfCode  
)

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

, Конечно, это может привести к безумию. Как часть проекта хобби в основанном на выражении языке сценариев под названием MaxScript, мне удалось придумать эту строку монстра

IF FindSectionStart "rigidifiers" != 0 THEN FOR i = 1 TO (local rigidifier_array = (FOR i = (local NodeStart = FindsectionStart "rigidifiers" + 1) TO (FindSectionEnd(NodeStart) - 1) collect full_array[i])).count DO
(
    LotsOfCode
)
3
ответ дан 4 July 2012 в 09:39
поделиться

Оператор является особым случаем выражения, один с void тип. Тенденция языков рассматривать операторы по-другому часто вызывает проблемы, и было бы лучше, если бы они были правильно обобщены.

, Например, в C# у нас есть очень полезное Func<T1, T2, T3, TResult> перегруженная группа универсальных делегатов. Но у нас также должно быть соответствие Action<T1, T2, T3> набор также, и программирование высшего порядка общего назначения постоянно должно дублироваться для контакта с этим неудачным раздвоением.

Тривиальный пример - функция, которая проверяет, является ли ссылка нулевой прежде, чем звонить на другую функцию:

TResult IfNotNull<TValue, TResult>(TValue value, Func<TValue, TResult> func)
                  where TValue : class
{
    return (value == null) ? default(TValue) : func(value);
}

компилятор мог иметь дело с возможностью TResult являющийся void? Да. Все, что это должно сделать, требуют, чтобы возврат сопровождался выражением, которое имеет тип void. Результат default(void) имел бы тип void, и func, передаваемый в, должен будет иметь форму Func<TValue, void> (который был бы эквивалентен [1 110]).

Много других ответов подразумевают, что Вы не можете объединить операторы в цепочку как Вы, может с выражениями, но я не уверен, куда эта идея прибывает из. Мы можем думать ;, который появляется после операторов как двоичный инфиксный оператор, беря два выражения типа void и комбинируя их в отдельное выражение типа void.

3
ответ дан Daniel Earwicker 4 July 2012 в 20:39
поделиться
  • 1
    @DanielHilgarth - Извините, я didn' t читают его ответ перед регистрацией. Очевидная вещь сделать состоит в том, чтобы только использовать Func<Task> вместо этого, тогда можно сделать FooAsync().Then(BarAsync).Then(FubarAsync). – Lee 31 January 2013 в 18:20

Фактическое основание этих понятий:

Выражения : синтаксическая категория, экземпляр которой может быть оценен к значению.

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

, Кроме того, к очень начальному контексту для ФОРТРАНА в ранние десятилетия, и определения выражений и операторы в принятом ответе являются, очевидно, неправильными:

  • Выражения могут быть неоцененными операндами. Значения никогда не производятся от них.
    • Подвыражения в нестрогих оценках могут быть определенно не оценены. <ул.> Самый подобный языкам C <литий> имеет так называемое оценка короткого замыкания , правила условно пропустить некоторые оценки подвыражения не изменяют конечный результат несмотря на побочные эффекты.
    • у C и некоторых подобных языкам C есть понятие неоцененного операнда, который может быть даже нормативно определен в спецификации языка. Такие конструкции используются для предотвращения оценок определенно, таким образом, контекстную информацию, которой остаются (например, типы или требования выравнивания) можно статически отличить, не изменяя поведение после перевода программы. <ул.> <литий>, Например, выражение, используемое в качестве операнда sizeof оператор, никогда не оценивается.
  • Операторы не имеют никакого отношения к конструкциям строки. Они могут сделать что-то большее чем выражения, в зависимости от спецификаций языка.
    • современный Фортран, как прямой потомок старого ФОРТРАНА, имеет понятие исполняемый неисполнимый оператор s.
    • оператора s и Точно так же, C++ определяет объявления как подкатегорию верхнего уровня единицы перевода. Объявление в C++ является оператором. (Это не верно в C.) существуют также оператор выражения s как исполняемые операторы Фортрана.
    • К интересу сравнения с выражениями, только "исполняемый" вопрос операторов. Но Вы не можете проигнорировать то, что операторы уже обобщены, чтобы быть конструкциями, формирующими единицы перевода на таких императивных языках. Так, как Вы видите, определения категории варьируются много. (Вероятно), только остался, общая собственность, сохраненная среди этих языков, - то, что операторы, как ожидают, будут интерпретированы в лексическом порядке (для большинства пользователей, слева направо и от начала до конца).

(BTW, я хочу добавить [необходима цитата] к тому ответу относительно материалов о C, потому что я не могу вспомнить, имеет ли DMR такие мнения. Это кажется не, иначе не должно быть никаких причин сохранить дублирование функциональности в дизайне C: особенно, оператор запятой по сравнению с операторами.)

(Следующее объяснение не является прямым ответом на исходный вопрос, но я чувствую это необходимый, чтобы разъяснить, что что-то уже ответило здесь.)

, Тем не менее, сомнительно, что нам нужна определенная категория "операторов" на языках программирования общего назначения:

  • Операторы, как гарантируют, не будут иметь больше семантических возможностей по выражениям в обычных проектах.
    • Много языков имеют, уже успешно отказываются от понятия операторов для получения чистого, аккуратного и последовательного общего замысла. <ул.> <литий> На таких языках, выражения могут сделать все, что операторы старого стиля могут сделать: просто отбросьте неиспользованные результаты, когда выражения будут оценены, любой путем оставления результатов явно неуказанными (например, в R <глоток> n Схема RS) или наличия специального значения (как значение типа единицы) не производимый от нормальных вычислений выражения.
    • <литий> лексические правила порядка оценки выражений может быть заменен явным оператором управления последовательностью (например, begin в Схеме) или синтаксический сахар одноместных структур. <литий> лексические правила порядка других видов "операторов" может быть получен как синтаксические расширения (использующий гигиенические макросы, например) для получения подобной синтаксической функциональности. (И это может на самом деле делать больше .)
    • Наоборот, операторы не могут иметь таких стандартных правил, потому что они не сочиняют на оценке: нет только никакого такого общего понятия "оценки подоператора". (Даже если кто-либо, я сомневаюсь, может быть что-то намного больше, чем копия и вставка от существовавших правил оценки выражений.) <ул.> <литий> Как правило, операторы сохранения языков будут также иметь выражения для выражения вычислений, и существует подкатегория верхнего уровня операторов, сохраненных к вычислениям выражения для той подкатегории. Например, C++ имеет так называемое оператор выражения как подкатегория и использует отброшенное выражение правила оценки указать общие случаи полных вычислений выражения в таком контексте. Некоторые языки как C# принимают решение совершенствовать контексты для упрощения вариантов использования, но он чрезмерно увеличивает размер спецификации больше.
  • Для пользователей языков программирования, значение операторов может смутить их далее.
    • разделение правил выражений и операторов на языках требует большего усилия выучить язык.
    • наивная лексическая интерпретация порядка скрывает более важное понятие: вычисление выражения. (Это является, вероятно, самым проблематичным по всем.) <ул.> <литий> Даже оценки полных выражений в операторах являются ограничением с лексическим порядком, подвыражения не (обязательно). Пользователи должны в конечном счете изучить это помимо любых правил, связанных с операторами. (Рассмотрите, как заставить новичка понять, что ++i + ++i бессмысленно в C.)
    • <литий> Некоторые языки как Java и C# дальнейшие ограничения порядок оценок подвыражений, чтобы быть разрешающим незнания правил оценки. Это может быть еще более проблематично. <ул.> <литий>, Это кажется чрезмерно определенным пользователям, которые уже изучили идею вычисления выражения. Это также поощряет пользовательское сообщество следовать размытой умственной модели дизайна языка. <литий> Это чрезмерно увеличивает размер спецификации языка еще больше. представлены <литий>, Это вредно для оптимизации путем пропавших без вести выразительности недетерминизма на оценках перед более сложными примитивами. <литий> Несколько языков как C++ (особенно, C++ 17) указывают более тонкие контексты правил оценки как компромисс проблем выше. <ул.> <литий> Это чрезмерно увеличивает размер спецификации языка много. <литий> Это переходит полностью против к простоте средним пользователям...

Итак, почему операторы? Так или иначе история уже является путаницей. Кажется, что большинство разработчиков языка не берет свой выбор тщательно.

Хуже, это даже дает некоторым энтузиастам системы типов (кто не достаточно знаком с МН историей), некоторые неправильные представления, которые системы типов должны иметь важные вещи сделать с более существенными проектами правил об операционной семантике.

Серьезно, рассуждая в зависимости от типов не то, что плохо во многих случаях, но особенно не конструктивен в этом специальном. Даже эксперты могут завинтить вещи.

, Например, кто-то подчеркивает хорошо вводящую природу как центральный аргумент против традиционной обработки неразграниченных продолжений . Хотя заключение несколько разумно, и понимание о составленных функциях в порядке (, но все еще слишком наивный к сущности ), этот аргумент не является звуковым, потому что это полностью игнорирует "подход" канала стороны на практике как _Noreturn any_of_returnable_types (в C11) для кодирования Falsum. И строго говоря, абстрактная машина с непредсказуемым состоянием не идентична "разрушенному компьютеру".

0
ответ дан 22 November 2019 в 23:20
поделиться

Для объяснения важных различий в компоновке (цепочности) выражений и утверждений, моя любимая ссылка - это статья Джона Бэкуса о премии Тьюринга Can программирование должно быть освобождено от стиля фон Неймана? .

Императивные языки (Fortran, C, Java, ...) делают упор на операторы для структурирования программ и имеют выражения как своего рода размышления. Функциональные языки делают упор на выражения. Чисто функциональные языки имеют такие мощные выражения, что операторы могут быть полностью исключены.

Можно ли освободить программирование от стиля фон Неймана? .

Императивные языки (Fortran, C, Java, ...) делают упор на операторы для структурирования программ и имеют выражения как своего рода размышления. Функциональные языки делают упор на выражения. Чисто функциональные языки имеют такие мощные выражения, что операторы могут быть полностью исключены.

Можно ли освободить программирование от стиля фон Неймана? .

Императивные языки (Fortran, C, Java, ...) делают упор на операторы для структурирования программ и имеют выражения как своего рода размышления. Функциональные языки делают упор на выражения. Чисто функциональные языки имеют такие мощные выражения, что операторы могут быть полностью исключены.

8
ответ дан 22 November 2019 в 23:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: