[language-agnostic] 표현 대 진술

나는 C #과 관련하여 묻고 있지만 대부분의 다른 언어에서도 동일하다고 가정합니다.

누구든지 표현진술에 대한 좋은 정의 와 차이점이 무엇입니까?



답변

표현 : 가치로 평가되는 것. 예 : 1 + 2 / x
문 : 무언가를하는 코드 줄. 예 : GOTO 100

FORTRAN과 같은 최초의 범용 프로그래밍 언어에서 그 차이는 명백했습니다. FORTRAN에서 명령문은 실행 단위 중 하나였습니다. “라인”이라고하지 않은 유일한 이유는 때때로 여러 라인에 걸쳐 있기 때문입니다. 식 자체로는 아무것도 할 수 없었습니다. 변수에 대입해야했습니다.

1 + 2 / X

그것은 아무것도하지 않기 때문에 FORTRAN의 오류입니다. 그 표현으로 무언가를해야했습니다.

X = 1 + 2 / X

FORTRAN은 오늘날 우리가 알고있는 문법을 가지고 있지 않았습니다. 그 아이디어는 Algol-60의 정의의 일부로 Backus-Naur Form (BNF)과 함께 발명되었습니다. 그 시점에서 의미 상 구별 ( “값을 가짐”대 “무언가를 가짐”)은 구문 에 포함되어 있습니다.

후기 언어의 설계자들은 구별을 흐리게했다 : 그들은 구문 표현이 일을 할 수있게하고, 가치가있는 구문 문장을 허용했다. 여전히 살아남은 가장 대중적인 언어의 예는 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 # 전용 할당, 호출, 증분 및 감소 표현식은 명령문으로 사용될 수 있습니다 ( Scott Wisniewski의 답변 참조 ).

두 가지 “구문 적 범주”(어구 진술 및 표현의 기술적 이름 인)가 있으면 노력이 중복 될 수 있습니다. 예를 들어, C에는 두 가지 조건부 조건문이 있습니다.

if (E) S1; else S2;

그리고 표현 형식

E ? E1 : E2

때로는 사람들 은 존재하지 않는 복제를 원합니다 . 예를 들어 표준 C에서는 문장 만 새로운 지역 변수를 선언 할 수 있습니다. 그러나이 기능은 GNU C 컴파일러가 표현식을 선언 할 수있는 GNU 확장을 제공 할만큼 유용합니다. 지역 변수도 마찬가지입니다.

다른 언어의 디자이너들은 이런 종류의 복제를 좋아하지 않았으며, 표현식이 값뿐만 아니라 부작용을 가질 수 있다면, 문장과 표현 의 구문 구분이 그다지 유용하지는 않다는 것을 알았 습니다. . Haskell, Icon, Lisp 및 ML은 모두 구문 설명이없는 언어이며 표현식 만 있습니다. 클래스 구조의 루핑 및 조건부 양식조차도 표현식으로 간주되며 값은 있지만 흥미로운 것은 아닙니다.


답변

  • 표현식은 값을 산출하는 모든 것입니다. 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

둘 사이의 큰 거래는 표현식을 함께 연결할 수 있지만 명령문은 연결할 수 없다는 것입니다.


답변

wikipedia 에서 찾을 수 있지만 표현식은 일부 값으로 평가되지만 명령문에는 평가 된 값이 없습니다.

따라서 표현식은 명령문에서 사용될 수 있지만 다른 방법으로는 사용할 수 없습니다.

일부 언어 (예 : Lisp, Ruby 및 기타 여러 언어)는 문장과 표현을 구별하지 않습니다. 이러한 언어에서는 모든 것이 표현이며 다른 표현과 연결될 수 있습니다.


답변

표현과 진술의 구성 성 (연쇄 성)의 중요한 차이점에 대한 설명을 위해 내가 가장 좋아하는 참고 문헌은 John Backus의 Turing 상 논문입니다. 프로그래밍은 폰 노이만 스타일에서 해방 될 수 있습니까? .

명령형 언어 (Fortran, C, Java, …)는 프로그램 구조화에 대한 설명을 강조하며 일종의 사후 생각으로 표현합니다. 기능적 언어는 표현을 강조합니다. 순전히 기능적인 언어는 문장을 완전히 제거 할 수있는 것보다 강력한 표현을 가지고 있습니다.


답변

표현식은 값을 얻기 위해 평가 될 수 있지만 명령문은 값을 리턴하지 않습니다 ( void 유형 임).

함수 호출 표현식은 물론 명령문으로 간주 될 수 있지만 실행 환경에 리턴 값을 보유하기위한 특수 내장 변수가 없으면이를 검색 할 방법이 없습니다.

명령문 지향 언어는 모든 프로 시저가 명령문 목록이어야합니다. 아마도 모든 기능적 언어 인 표현 지향 언어는 표현 목록이거나 LISP의 경우 표현 목록을 나타내는 하나의 긴 S- 표현입니다.

두 유형을 모두 구성 할 수 있지만 유형이 일치하는 한 대부분의 표현식을 임의로 구성 할 수 있습니다. 각 유형의 진술서는 다른 모든 진술을 구성 할 수있는 방법이 있습니다. 하위 명령문이 자신의 하위 명령문을 허용하지 않는 한 Foreach 및 if 문에는 단일 명령문이 필요하거나 모든 하위 명령문이 차례로 명령문 블록에 들어갑니다.

명령문에는 표현식이 포함될 수 있으며 표현식에는 실제로 명령문이 포함되지 않습니다. 그러나 한 가지 예외는 함수를 나타내는 람다 식이므로 파이썬의 단일 식 람다와 같이 언어가 제한된 람다만을 허용하지 않는 한 함수가 포함 할 수있는 모든 것을 포함 할 수 있습니다.

식 기반 언어에서는 모든 컨트롤 구조가 값을 반환하므로 많은 함수가 NIL을 반환하므로 함수에 대한 단일 식만 있으면됩니다. 함수에서 마지막으로 평가 된 표현식이 리턴 값이므로 리턴 문이 필요하지 않습니다.


답변

간단히 말하면 표현식은 값으로 평가되지만 문장은 그렇지 않습니다.