Вопрос

Я спрашиваю относительно c #, но я предполагаю, что это то же самое на большинстве других языков.

У кого-нибудь есть хорошее определение выражения и заявления и в чем же заключаются эти различия?

Это было полезно?

Решение

Выражение: Что-то, что оценивается как значение.Пример: 1+2/x
Заявление: Строка кода, которая что-то делает.Пример: ПЕРЕХОД 100

В самых ранних языках программирования общего назначения, таких как FORTRAN, различие было кристально ясным.В FORTRAN оператор был одной единицей выполнения, тем, что вы делали.Единственная причина, по которой это не называлось "линией", заключалась в том, что иногда оно охватывало несколько строк.Выражение само по себе ничего не могло сделать...вы должны были присвоить его переменной.

1 + 2 / X

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

X = 1 + 2 / X

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

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

1 + 2 / x;

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

1 + 2 / callfunc(12);

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

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

callfunc(x = 2);

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

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

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

if (E) S1; else S2;

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

E ? E1 : E2

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

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

Другие советы

Я хотел бы внести небольшую поправку в ответ Джоэла выше.

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

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

1 + 2;

  • выражение - это все, что дает значение: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

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

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

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

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

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

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

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

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

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

Просто:выражение принимает значение, оператор - нет.

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

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

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

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

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

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

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


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


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


В языке, основанном на выражениях, все возвращает значение.Поначалу это может показаться немного странным - Что делает (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() вернет какое-то обыденное значение, такое как OK, Done или Success.
  • Когда несколько несвязанных выражений вычисляются в рамках одного большего выражения, значение последнего элемента, вычисленного в большом выражении, становится значением большого выражения.Возьмем, к примеру, (FOR i = 1 TO 10 DO (print i)), значение цикла for равно "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
)

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

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

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

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<TValue, void> (что было бы эквивалентно Action<TValue>).

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

Инструкции -> Инструкции для последовательного выполнения
Выражения -> Вычисление, возвращающее значение

Инструкции в основном похожи на шаги или инструкции в алгоритме, результатом выполнения инструкции является актуализация указателя инструкции (так называемого в ассемблере)

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

Примеры утверждений:

for
goto
return
if

(все они подразумевают перенос строки (инструкции) выполнения на другую строку)

Пример выражений:

2+2

(это подразумевает идею не исполнения, а оценки)

Утверждения - это грамматически законченные предложения.Выражения таковыми не являются.Например

x = 5

читается как "x получает 5". Это законченное предложение.Код

(x + 5)/9.0

гласит: "x плюс 5, все делится на 9,0". Это неполное предложение.Заявление

while k < 10: 
    print k
    k += 1

это законченное предложение.Обратите внимание, что заголовок цикла не является;"в то время как к < 10" - это подчинительное предложение.

Заявление,

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

Серия операторов, заключенная в фигурные скобки, образует блок кода.Тело метода - это один из примеров блока кода.

bool IsPositive(int number)
{
    if (number > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

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

Выражение,

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

int i = 5;
string s = "Hello World";

И i, и s - это простые имена, идентифицирующие локальные переменные.Когда эти переменные используются в выражении, значение переменной извлекается и используется для выражения.

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

Я предполагаю, что в компьютерном мире и науке в целом всегда будет возникать путаница, когда вводятся новые термины или словосочетания, существующие слова "перепрофилируются" или пользователи не осведомлены о существующей, устоявшейся или "правильной" терминологии для того, что они описывают

На самом деле я не удовлетворен ни одним из приведенных здесь ответов.Я просмотрел грамматику для C++ (ISO 2008).Однако, возможно, ради дидактики и программирования ответов может быть достаточно, чтобы различить эти два элемента (хотя реальность выглядит более сложной).

Оператор состоит из нуля или более выражений, но также может представлять собой другие языковые понятия.Это расширенная форма Backus Naur для грамматики (выдержка из утверждения):

statement:
        labeled-statement
        expression-statement <-- can be zero or more expressions
        compound-statement
        selection-statement
        iteration-statement
        jump-statement
        declaration-statement
        try-block

Мы можем увидеть другие концепции, которые считаются операторами в C ++.

  • выражение-высказываниеs является самоописывающимся (утверждение может состоять из нуля или Еще выражения, внимательно читайте грамматику, это сложно)
  • case например, это помеченный-оператор
  • оператор выбораs являются if if/else, case
  • оператор итерацииs являются while, do...while, for (...)
  • оператор переходаs являются break, continue, return (может возвращать выражение), goto
  • декларация-statement (заявление) является набором объявлений
  • попробуйте-заблокируйте является ли утверждение представляющим try/catch блоки
  • и, возможно, там будет еще кое-что по грамматике

Это отрывок, показывающий часть с выражениями:

expression:
        assignment-expression
        expression "," assignment-expression
assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator initializer-clause
        throw-expression
  • выражения часто являются присваиваниями или содержат их
  • условное выражение (звучит вводяще в заблуждение) относится к использованию операторов (+, -, *, /, &, |, &&, ||, ...)
  • бросок-выражение - э-э?тот самый throw предложение тоже является выражением

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

первоначально ответил Андерс Касеорг

Оператор - это полная строка кода, которая выполняет некоторое действие, в то время как выражение - это любой раздел кода, который принимает значение.

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

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

http://www.quora.com/Python-programming-language-1/Whats-the-difference-between-a-statement-and-an-expression-in-Python

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

Выражение имеет тип, отличный от Нижнего типа, т.е.в этом есть своя ценность.Оператор имеет тип Unit или Bottom.

Из этого следует, что оператор может иметь какой-либо эффект в программе только тогда, когда он создает побочный эффект, потому что он либо не может возвращать значение, либо возвращает только значение типа Unit, которое либо не присваивается (в некоторых языках, таких как C void) или (например, в Scala) могут быть сохранены для отложенной оценки инструкции.

Очевидно, что @pragma или /*comment*/ не имеют типа и, следовательно, отличаются от утверждений.Таким образом, единственным типом оператора, который не имел бы побочных эффектов, было бы неоперативное выполнение.Неработоспособность полезна только в качестве заполнителя для будущих побочных эффектов.Любое другое действие, вызванное заявлением, было бы побочным эффектом.Снова подсказка компилятору, например @pragma, не является утверждением, потому что у него нет типа.

Наиболее точно, оператор должен иметь "побочный эффект" (т.е. будьте императивны) и выражение должно иметь a значение тип (т. е.не самый нижний тип).

Тот Самый тип заявления является типом единицы измерения, но из-за теоремы об остановке единица измерения является фикцией, поэтому допустим, что нижний тип.


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

Давайте посмотрим, что говорит Википедия по этому поводу.

https://en.wikipedia.org/wiki/Statement_ (компьютерная наука)

В компьютерном программировании оператор - это наименьший отдельный элемент императивный язык программирования , выражающий какое - то действие подлежащий выполнению.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top