표현 대 진술


431

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

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


4
당신이 선택한 답변이 모호합니다. 식은 또한 무언가를합니다. 값으로 평가됩니다. 나는 모호하지 않은 대답을 제공했다.
Shelby Moore III

4
@ShelbyMooreIII-모호하지 않으며 잘못되었습니다. 받아 들여지는 대답은 비공식적으로 표현되지만, 그 표현은 이해하기 쉽도록하며 가장 중요한 것은 그것이 전달하는 의미가 정확합니다.
저스틴 모건

@JustinMorgan 슬프게도, 받아 들여진 대답의 정의는 대부분의 현대 언어에 C와 같은 언어가 포함되어 있기 때문에 명백히 잘못되었습니다 ( "값으로 평가"/ "코드 라인"). 라인과 관련이 있습니다. 몇 가지 설명이 있지만 짧은 대답은 혼란스럽고 오도됩니다.
FrankHB

답변:


520

표현 : 가치로 평가되는 것. 예 : 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은 모두 구문 설명이없는 언어이며 표현식 만 있습니다. 클래스 구조의 루핑 및 조건부 양식조차도 표현식으로 간주되며 값은 있지만 흥미로운 것은 아닙니다.


9
내가 여기서 당신을 잘못 해석하지 않는다면, 당신은 "(setf (third foo) 'goose)"는 "문이없는"Lisp이기 때문에 진술이 아니라 표현이라고 주장하는 것 같습니다. 왜냐하면 Lisp는 C보다 10 년 이상 오래 되었기 때문에 "표현과 문장 사이의 경계를 흐리게하는 가장 초기의 언어"였습니다. 그 세부 사항을 나에게 설명해 주시겠습니까?
cjs 2016 년

2
@ 커트 샘슨, 당신은 별도의 질문으로 그 질문을 했습니까?
Kelly S. French

5
제가 잘못 본게 아니라면, callfunc(x = 2);전달 xcallfunc, 없습니다 2. 경우 x부동이다 callfunc(float),하지 호출됩니다 callfunc(int). 그리고 C에서 + +, 당신은 전달하는 경우 x=yfunc, 그리고 func그것을 변경, 그것을 참조를 받아 변경 x하지 y.
가브리엘

위의 답변에서, "Haskell, ...은 구문 문장이없는 모든 언어이며, 표현 만 있습니다"라고 쓰여 있습니다. 왜 wherehaskell의 절이 진술이 아닌 표현으로 간주 되는지 궁금 합니다. learnyouahaskell.com/syntax-in-functions#where
skgbanga

@ skgbanga 나는 where실제로 표현식이나 문장이 아니라 함수 선언의 일부 라고 생각 합니다.
Akangka

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


2
명령문이 무엇인지에 대한 논리가 잘못되었습니다. 선언적 프로그램도 실행할 수 있지만 선언적 프로그램에는 명령문이 없습니다. 성명서는 "부작용" 이며, 즉 "부작용" 이다. cf. 내 대답 .
Shelby Moore III

15

식은 값을 반환하는 반면 문은 그렇지 않습니다.

예를 들어:

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

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


6
확실한 진술은 연결될 수 있습니다. {stmt1; stmt2; stmt3;}은 체인이며 (화합물) 문장이기도합니다.
휴 알렌

5
foo.voidFunc(1);void 값을 가진 표현식입니다. while그리고 if진술입니다.
tzot 2009

비 연쇄 진술에 대해 궁금합니다. "if (x> 1) return;"과 같은 것 두 문장을 연결하는 것으로 간주됩니까?
Simon Tewsi

1
@SimonTewsi 나는 이것이 return하위 진술 로 간주 된다고 생각합니다 .
RastaJedi

@SimonTewsi 여기의 return 문은 암시 적으로 if 문 블록 안에 있으므로 if 문의 일부이며 연결되지 않습니다. 컴파일러는 단일 행 블록이므로 중괄호를 생략 할 수 있습니다.
user2597608

9

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

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

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


8

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

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


5

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

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

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

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

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

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


명령문의 유형은 맨 아래 유형입니다. Void하단 유형이 아닙니다. 내 답변을 참조하십시오 .
Shelby Moore III

1
하지 않 null가 입력 바닥 유형 (단일 값을 null)? 하지 않을까요 void더 등이 될 단위 유형 (하지만 단일 값 액세스와 함께)을?
Mark Cidade

경우 void결코 반환 (예를 들어, 함수 함수의 반환 유형 throw오류 S), 그것은이다 바닥 유형 . 그렇지 않은 경우 void는 IS 단위 유형은 . 분기 할 수없는 명령문의 단위 유형이 올바른 것입니다. 그러나 발산 할 수있는 진술은 최하위 유형입니다. Halting Theorem으로 인해 우리는 일반적으로 함수가 분기되지 않는다는 것을 증명할 수 없으므로 단위가 허구라고 생각합니다. 하단 유형은 값을 가질 수 없으므로 단일 값을 가질 수 없습니다 null.
Shelby Moore III

1
내가 3 년 전에 말한 것에 관해서는, 나는 여전히 선언문이 void 유형이나 다른 유형 을 가지고 있다고 생각하는지 모른다 . 친숙한 문장 기반 언어에서는 값을 저장하거나 반환하는 모든 것 (예 : 식, 변수, 멤버 및 함수) 만 유형을 가질 수 있습니다. 나는 일반적으로 하단 유형을 빈 세트 (값 없음)로 생각하므로 온톨로지로 존재하지 않는 것은이 유형을 갖습니다. null값은 정말입니다 pseudovalue 참조가 존재하지 않는 무언가를 말한다 것을 나타내는.
Mark Cidade

1
Mark 나는 당신의 반응의 합리성을 고맙게 생각했습니다. 당신은 기본적으로 내 입에서 단어를 빼 냈고 나는 당신에게 단위 점을 올리는 것이 옳았다는 것을 분명히 인정했기를 바랍니다. 우리는 동의한다고 생각합니다. 나는 이것을 언급하는 것을 귀찮게하지 않을 것이지만, 여기의 일부 사람들은 내가 부정적이라고 생각하는 것 같습니다. 나는 사실이 되려고 노력하고 있습니다.
쉘비 무어 III

4

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


그래서 성명서는 무엇을 하는가? 아무것도?
Shelby Moore III

1
무언가를 할 수는 있지만 아무것도 평가하지 않습니다. 즉, 결과를 변수에 할당 할 수 없지만 식을 사용하면됩니다.
Matthew Schinckel

그리고 이에 따라 내 성명서에 따라 투표 결과에 따라 진술에 부작용이 있어야합니다. 성명서에는 어떤 다른 유틸리티가있을 수 있습니까? NO-OP가 문장으로 간주 되더라도 (구문 분석 후 구문이 지워지고 의미 체계가 여기서 논의되는 것이기 때문에 의미 체계에서는 그렇지 않습니다.) 진술의 일반적인 유용성은 도대체입니다.
쉘비 무어 III

1
@ShelbyMooreIII 문은 아무것도하지 않거나 부작용이 없습니다. 예를 들어, {}진술입니다. 따옴표로 단어를 넣어도 변경되지 않습니다. 문장은 의미론을 가진 구문 구조입니다. "시맨틱 레이어"와 같은 것은 없습니다. 당신은 실행을 언급하는 것 같습니다 . 당신은 당신이 정확하려고 노력하고 있지만 당신은 그것에 실패했습니다. "감독자들의 무지"에 대한 귀하의 불만은 순수한 가정입니다. 다운 보터의 정신 상태에 대한 정보가 없습니다.
Jim Balter

예, 지적으로 부정직 한 사람을 제외하고는 모두 잘못입니다. {}C # 언어 사양의 문으로 정의됩니다.
짐 발터

4

표현 기반 언어에 관한 몇 가지 사항 :


가장 중요 : 모든 것이 값을 반환


모든 것이 표현식이므로 코드 블록과 표현식을 구분하기위한 중괄호와 중괄호 사이에는 차이가 없습니다. 그러나 어휘 범위 지정을 막지는 않습니다. 예를 들어, 정의에 포함 된 표현식과 그 안에 포함 된 모든 명령문에 대해 로컬 변수를 정의 할 수 있습니다.


식 기반 언어에서는 모든 것이 값을 반환합니다. 처음에는 조금 이상 할 수 있습니다. 무엇을 (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

몇 가지 더 복잡한 예 :

  • 일부 함수 호출과 같은 것들은 실제로 의미있는 값을 반환하지 않습니다 (부작용 만 생성하는 것입니까?). OK, Done 또는 Success와 같은 일반적인 값을 호출 OpenADoor(), FlushTheToilet()하거나 TwiddleYourThumbs()반환합니다.
  • 하나의 큰 식 내에서 여러 개의 연결되지 않은식이 평가되면 큰 식에서 마지막으로 평가 된 값이 큰 식의 값이됩니다. 의 예를 들어 (FOR i = 1 TO 10 DO (print i)), for 루프의 값은 "10"이며, (print i)i를 문자열로 반환 할 때마다식이 10 번 평가됩니다. 10마지막 답인 return , 마지막 답변

모든 것이 표현이라는 사실이 많은 것을 '인라인'할 수 있기 때문에 표현 기반 언어를 최대한 활용하려면 약간의 사고 방식이 필요합니다.

간단한 예를 들면 다음과 같습니다.

 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
)

2

문은 형식이있는 특수한 식의 경우입니다 void. 언어가 진술을 다르게 취급하는 경향은 종종 문제를 야기하며, 제대로 일반화되면 더 나을 것입니다.

예를 들어 C #에는 매우 유용한 Func<T1, T2, T3, TResult>오버로드 된 일반 대리자 집합이 있습니다. 그러나 우리는 또한 상응하는 Action<T1, T2, T3>세트 를 가져야하며 , 불행한 분기점을 처리하기 위해 범용 고차 프로그래밍을 지속적으로 복제해야합니다.

간단한 예-다른 함수를 호출하기 전에 참조가 null인지 확인하는 함수 :

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

의 가능성 컴파일러 거래 할 수 TResult있는가 void? 예. 필요한 것은 return 다음에 유형식이 있어야한다는 것입니다 void. 의 결과는 default(void)유형 void이고 전달되는 기능 은 형식 과 같아야합니다 Func<TValue, void>(과 동일 Action<TValue>).

다른 많은 답변은 식과 같은 문장을 연결할 수 없다는 것을 암시하지만이 아이디어의 출처는 확실하지 않습니다. 우리는 ;그 다음에 나오는 문을 이진 접두사 연산자로 생각할 수 있으며 , 두 가지 유형의 표현식을 취하여 void단일 유형의 표현식으로 결합합니다 void.


문장은 특별한 표현이 아닙니다. 일부 언어 (예 : 대부분의 C 후속 언어)에서는 실제로 다른 방법입니다.
Akangka

2

명령문-> 순차적으로 따르는 지시 사항
표현식-> 값을 리턴하는 평가

명령문은 기본적으로 알고리즘의 단계 또는 명령어와 유사하며, 명령문 실행의 결과는 명령어 포인터 (어셈블러에서 소위)의 실현입니다.

표현은 첫눈에 실행 순서를 의미하지 않으며 그 목적은 값을 평가하고 반환하는 것입니다. 명령형 프로그래밍 언어에서 식의 평가에는 순서가 있지만 명령형 모델 때문일 뿐이지 만 본질이 아닙니다.

진술의 예 :

for
goto
return
if

(모두 실행 라인이 다른 라인으로 진행되었음을 나타냄)

식의 예 :

2+2

(그것은 실행의 아이디어를 의미하는 것이 아니라 평가의 의미를 암시합니다)


부작용은 어떻습니까?
Austin Henley

@AustinHenley는 이에 대한 요구 사항이 없습니다. 실제로 표현에는 부작용이있을 수 있습니다.
Akangka

1

,

명령문은 모든 C # 프로그램이 구성되는 절차 적 빌딩 블록입니다. 명령문은 로컬 변수 또는 상수를 선언하거나, 메소드를 호출하거나, 오브젝트를 작성하거나, 변수, 특성 또는 필드에 값을 지정할 수 있습니다.

중괄호로 묶인 일련의 명령문은 코드 블록을 형성합니다. 메소드 본문은 코드 블록의 한 예입니다.

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

C #의 문은 종종 식을 포함합니다. C #의 표현식은 리터럴 값, 간단한 이름 또는 연산자와 피연산자가 포함 된 코드 조각입니다.

,

식은 단일 값, 개체, 메서드 또는 네임 스페이스로 평가할 수있는 코드 조각입니다. 가장 간단한 두 가지 표현 유형은 리터럴과 간단한 이름입니다. 리터럴은 이름이없는 상수 값입니다.

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

i와 s는 모두 지역 변수를 식별하는 간단한 이름입니다. 이러한 변수가 표현식에 사용되면 변수 값이 검색되어 표현식에 사용됩니다.


차라리 글을 if(number >= 0) return true; else return false;쓰거나 더 좋을 것입니다 bool? IsPositive(int number) { if(number > 0) return true; else if(number < 0) return false; else return null;}:)
Mahdi Tahsildari

1

나는 statement형식적인 논리적 인 의미에서 단어 의 의미를 선호합니다 . 계산에서 하나 이상의 변수 상태를 변경하여 해당 값에 대해 참 또는 거짓 진술을 할 수있게하는 것은 하나입니다.

새로운 용어 나 단어가 소개되거나 기존 단어가 '목적'이거나 사용자가 설명하는 내용에 대해 기존의, 확립 된 또는 '적절한'용어를 모르는 경우 컴퓨팅 세계와 과학에는 항상 혼란 스러울 것입니다


1

나는 여기에 대한 답변에 실제로 만족하지 않습니다. C ++ (ISO 2008) 문법을 살펴 보았습니다 . 그러나 교훈과 프로그래밍을 위해 두 요소를 구별하기에 답이 충분할 수 있습니다 (실제로는 더 복잡해 보입니다).

명령문은 0 개 이상의 표현식으로 구성되지만 다른 언어 개념 일 수도 있습니다. 다음은 문법에 대한 확장 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 ++에서 문장으로 간주되는 다른 개념을 볼 수 있습니다.

  • expression-statement 는 스스로 설명합니다 (구문은 0 개 이상의 표현식 으로 구성 될 수 있으며 문법을주의 깊게 읽으면 까다 롭습니다)
  • case예를 들어 라벨이 붙은 문장입니다
  • 선택 - 문 의는 if if/else,case
  • 반복 - 문 의는 while, do...while,for (...)
  • 점프 문 의는 break, continue, return, (표현을 반환 할 수 있습니다)goto
  • declaration-statement선언 의 집합입니다
  • try-blocktry/catch블록을 나타내는 문장입니다.
  • 문법에 더 많은 것이있을 수 있습니다.

이것은 표현식 부분을 보여주는 발췌 부분입니다.

expression:
        assignment-expression
        expression "," assignment-expression
assignment-expression:
        conditional-expression
        logical-or-expression assignment-operator initializer-clause
        throw-expression
  • 표현은 종종 할당이거나 포함
  • 조건부 식 (소리가 오해의 소지가) 연산자의 사용을 의미한다 ( +, -, *, /, &, |, &&, ||, ...)
  • 던지기 표현 -어? throw절은 너무 표현이다

0

문장은 문법적으로 완전한 문장입니다. 식은 아닙니다. 예를 들어

x = 5

"x gets 5"로 읽습니다. 이것은 완전한 문장입니다. 코드

(x + 5)/9.0

"x + 5를 9.0으로 나눈 값"이라고 읽습니다. 이것은 완전한 문장이 아닙니다. 진술

while k < 10: 
    print k
    k += 1

완전한 문장입니다. 루프 헤더가 아닙니다. "k <10 동안"은 대체 조항입니다.


while스칼라와 같은 언어입니다. 입력과 문법을 혼동하고 있습니다. 내 답변을 참조하십시오 .
Shelby Moore III

scala의 while 루프는 다음과 같습니다. tutorialspoint.com/scala/scala_while_loop.htm 술어가없고 본문이없는 루프는 문법적으로 완전한 문장이 아닙니다. 완전한 표현이 아닙니다. 식으로 완성하려면 몸이 필요합니다.
ncmathsadist

while시체가있는 는 여전히 스칼라에서 표현입니다. 부작용이 발생하면 성명서가 될 수 있습니다. 내 대답은 유일한 것입니다. 이해할 수없는 모든 독자들에게 죄송합니다.
Shelby Moore III

문법적으로 완성되었다는 것은 무슨 뜻입니까? C에서는(x + 5)/9.0 분명히 진술로 혼자 설 수 있습니다. 또한 문법적으로 완전하다고해서 유효한 프로그램을 의미하는 경우 C는 명령문을 단일 프로그램으로 단독으로 허용하지 않습니다.
Akangka

문법적으로 완전한 : 완전한 문장을 구성합니다.
ncmathsadist

0

여기 내가 찾은 가장 간단한 대답 중 하나가 여름입니다.

Anders Kaseorg의 원래 답변

명령문은 일부 조치를 수행하는 완전한 코드 행이며 표현식은 값으로 평가되는 코드의 섹션입니다.

연산자를 사용하여 표현식을 "수평 적으로"더 큰 표현식으로 결합 할 수있는 반면, 명령문은 순차적으로 또는 블록 구조를 사용하여 "수직으로"결합 할 수 있습니다.

모든 표현식을 명령문으로 사용할 수 있지만 (표현식을 평가하고 결과 값을 무시하는 효과) 대부분의 명령문을 표현식으로 사용할 수 없습니다.

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


0

이러한 개념의 사실상의 기초는 다음과 같습니다.

Expressions : 인스턴스를 값으로 평가할 수있는 구문 범주.

성명서 : 표현의 평가와 평가의 결과 값 (있는 경우)이 포함될 수있는 구문 범주는 사용 가능하지 않을 수 있습니다.

초기 수십 년 동안 FORTRAN의 초기 맥락 외에도, 수용된 답변의 표현과 진술의 정의는 분명히 틀 렸습니다.

  • 표현식은 평가되지 않은 피연산자가 될 수 있습니다. 가치는 결코 그들로부터 만들어지지 않습니다.
    • 엄격하지 않은 평가의 하위 표현식은 확실히 평가되지 않을 수 있습니다.
      • 대부분의 C와 유사한 언어에는 소위 단락 평가 규칙이있어 부작용에도 불구하고 일부 하위 표현식 평가를 조건부로 건너 뛰어 최종 결과를 변경하지 않습니다.
    • C와 일부 C와 같은 언어는 평가되지 않은 피연산자라는 개념을 가지고 있으며 이는 언어 사양에서 규범 적으로 정의 될 수도 있습니다. 이러한 구성은 평가를 확실하게 피하기 위해 사용되므로 프로그램 변환 후 동작을 변경하지 않고 남아있는 컨텍스트 정보 (예 : 유형 또는 정렬 요구 사항)를 정적으로 구별 할 수 있습니다.
      • 예를 들어, sizeof연산자 의 피연산자로 사용 된 표현식 은 평가되지 않습니다.
  • 명령문은 라인 구성과 관련이 없습니다. 언어 사양에 따라 표현식 이상의 기능을 수행 할 수 있습니다.
    • 현대 포트란, 이전 FORTRAN의 직계 후손으로,의 개념을 가지고 실행 문 의 및 비 실행 문 들.
    • 마찬가지로 C ++는 선언을 번역 단위의 최상위 하위 범주로 정의합니다. C ++의 선언은 명령문입니다. (이것은 C에서 사실이 아니다) 도있다 표현 문 포트란의 실행 문처럼들.
    • 식과의 비교를 위해 "실행 가능"문만 중요합니다. 그러나 문장이 그러한 명령형 언어로 번역 단위를 형성하는 구조로 이미 일반화되어 있다는 사실을 무시할 수 없습니다. 보시다시피, 카테고리의 정의는 매우 다양합니다. (아마도) 이들 언어들 사이에서 유지되는 공통 속성은 진술이 어휘 순서 (대부분의 사용자의 경우 왼쪽에서 오른쪽으로, 위에서 아래로) 로 해석되어야한다는 것 입니다.

(BTW, 나는 DMR이 그러한 의견을 가지고 있는지를 기억할 수 없기 때문에 C에 관한 자료들에 대한 답변에 [인용 필요]를 추가하고 싶다. 그렇지 않다면 그렇지 않다. : 특히 쉼표 연산자 대 명령문.)

(다음의 이론적 근거는 원래의 질문에 대한 직접적인 반응은 아니지만 이미 여기에 답변 된 내용을 명확히해야 할 필요가 있다고 생각합니다.)

그럼에도 불구하고, 범용 프로그래밍 언어에서 특정 범주의 "문"이 필요하다는 것은 의심의 여지가 있습니다.

  • 명령문은 일반적인 디자인의 표현식보다 의미 적 기능이 더 높다는 보장이 없습니다.
    • 많은 언어들이 이미 깨끗하고 깔끔하며 일관된 전체 디자인을 얻기 위해 문장 개념을 성공적으로 버렸습니다.
      • 그러한 언어에서, 표현은 구식 문장이 할 수있는 모든 것을 할 수 있습니다 : 결과를 명시 적으로 지정하지 않은 채로 표현이 평가 될 때 사용되지 않은 결과를 삭제하십시오 (예 : R n RS 체계에서), 또는 특별한 값 (예 : 정규식 평가에서 생산할 수없는 단위 유형 값).
      • 표현 평가의 어휘 순서 규칙은 명시 적 시퀀스 제어 연산자 (예 : begin스킴) 또는 모나 딕 구조의 구문 설탕 으로 대체 될 수 있습니다 .
      • 다른 종류의 "문"의 어휘 순서 규칙은 유사한 구문 기능을 얻기 위해 구문 확장 (예 : 위생 매크로 사용)으로 파생 될 수 있습니다. (그리고 실제로 더 많은 일을 할 수 있습니다 .)
    • 반대로, 진술은 평가를 구성하지 않기 때문에 이러한 기존 규칙을 가질 수 없습니다. "하위 평가"라는 일반적인 개념은 없습니다. (있는 경우에도 기존의 표현 평가 규칙에서 복사하여 붙여 넣는 것보다 훨씬 많은 것이있을 수 있습니다.)
      • 일반적으로 문을 보존하는 언어에는 계산을 표현하는식이 있으며 해당 하위 범주의 식 평가에 유지되는 문의 최상위 하위 범주가 있습니다. 예를 들어, C ++에는 소위 expression-statement 가 하위 범주로 포함되어 있으며 폐기 된 값 식 평가 규칙을 사용하여 이러한 상황에서 전체 식 평가의 일반적인 경우를 지정합니다. C #과 같은 일부 언어는 사용 사례를 단순화하기 위해 컨텍스트를 세분화하기로 선택하지만 사양이 더 부풀어 오른다.
  • 프로그래밍 언어 사용자의 경우 문장의 중요성으로 인해 더 혼동 될 수 있습니다.
    • 언어에서 표현 규칙과 표현을 분리하려면 언어를 배우기 위해 더 많은 노력이 필요합니다.
    • 순진한 어휘 순서 해석은보다 중요한 개념 인 식 평가를 숨 깁니다. (이것은 아마도 가장 문제가 될 것입니다.)
      • 명령문에서 전체 표현식의 평가조차 어휘 순서에 제한이 있으며 하위 표현식은 (필수적으로) 필요하지 않습니다. 사용자는 진술과 관련된 규칙 외에 궁극적으로 이것을 배워야합니다. ( ++i + ++iC에서 초보자 가 무의미한 포인트를 얻는 방법을 고려하십시오 .)
      • Java 및 C #과 같은 일부 언어는 하위 표현식의 평가 순서가 평가 규칙의 무지를 무시하도록 제한합니다. 훨씬 더 문제가 될 수 있습니다.
        • 이것은 이미 식 평가의 아이디어를 배운 사용자에게 과장된 것 같습니다. 또한 사용자 커뮤니티가 언어 디자인의 희미한 정신 모델을 따르도록 권장합니다.
        • 언어 사양이 더욱 부풀어 오른다.
        • 보다 복잡한 프리미티브가 도입되기 전에 평가에 대한 비결정론의 표현성을 놓치면 최적화에 해 롭습니다.
      • C ++ (특히 C ++ 17)과 같은 몇 가지 언어는 위의 문제에 대한 타협으로 평가 규칙의보다 미묘한 컨텍스트를 지정합니다.
        • 언어 사양이 크게 부풀어 오른다.
        • 이것은 일반 사용자에게 단순성과 완전히 반대됩니다 ...

그렇다면 왜 진술입니까? 어쨌든, 역사는 이미 엉망입니다. 대부분의 언어 디자이너는 신중하게 선택하지 않는 것 같습니다.

더구나, 그것은 PL 시스템 역사에 익숙하지 않은 일부 유형 시스템 애호가들에게도 유형 시스템이 운영 의미론에 대한보다 필수적인 규칙 설계와 관련하여 중요한 것들을 가져야한다는 오해를 제공합니다.

진지하게, 유형에 따른 추론은 많은 경우에 그렇게 나쁘지는 않지만, 특히이 특별한 것에서는 건설적이지 않습니다. 전문가조차도 문제를 해결할 수 있습니다.

예를 들어, 누군가는 잘 정의 된 연속성을 전통적인 처리에 대한 중심 논거로 잘 타이핑하는 특성 강조합니다 . 결론은 다소 합리적이고 구성 함수에 대한 통찰력은 괜찮지 만 ( 그러나 여전히 본질에 너무 순진하지만 ),이 주장은 _Noreturn any_of_returnable_types인코딩하기 위해 (C11에서) 실제로 "사이드 채널"접근 방식을 완전히 무시하기 때문에 건전하지 않다 Falsum. 엄밀히 말하면, 예측할 수없는 상태의 추상 시스템은 "충돌 된 컴퓨터"와 동일하지 않습니다.


0

명령문 지향 프로그래밍 언어에서 코드 블록은 명령문 목록으로 정의됩니다. 즉, 명령문은 구문 오류를 일으키지 않고 코드 블록 안에 넣을 수있는 구문입니다.

Wikipedia는 단어 문장을 유사하게 정의합니다.

컴퓨터 프로그래밍에서, 명령문은 수행 할 조치를 표현하는 명령형 프로그래밍 언어의 구문 단위입니다. 그러한 언어로 작성된 프로그램은 하나 이상의 문장으로 구성됩니다.

후자의 진술에 주목하십시오. (이 경우 "프로그램"은 C와 Java 모두 문장으로 구성된 프로그램을 거부하기 때문에 기술적으로 잘못되었습니다.)

Wikipedia는 단어 표현을 다음과 같이 정의합니다.

프로그래밍 언어의 표현은 그 가치를 결정하기 위해 평가 될 수있는 구문 적 실체이다

그러나 Kotlin에서는 throw new Exception("") 표현식이지만 표현식으로 평가할 때 예외를 throw하고 값을 반환하지 않으므로 false입니다.

정적으로 유형이 지정된 프로그래밍 언어에서 모든 표현식에는 유형이 있습니다. 그러나이 정의는 동적으로 유형이 지정된 프로그래밍 언어에서는 작동하지 않습니다.

개인적으로, 표현식을 연산자 또는 함수 호출로 구성하여 더 큰 표현식을 생성 할 수있는 구문으로 정의합니다. 이것은 실제로 Wikipedia의 표현에 대한 설명과 유사합니다.

프로그래밍 언어가 해석하고 (특정 우선 순위 및 연관 규칙에 따라) 하나 이상의 상수, 변수, 함수 및 연산자의 조합으로 다른 값을 생성 ( "상태 저장 환경에서"리턴)합니다.

그러나 다음과 같은 함수 executeSomething이 주어지면 문제는 C 프로그래밍 언어입니다.

void executeSomething(void){
    return;
}

executeSomething()표현 입니까 , 아니면 진술입니까? 내 정의에 따르면, 이것은 Microsoft의 C 참조 문법에 정의 된대로,

어떤 식 으로든 void 유형이있는 표현식의 (존재하지 않는) 값을 사용할 수 없으며, void 표현식 (암시 적 또는 명시 적 변환에 의한)을 void 이외의 유형으로 변환 할 수 없습니다

그러나 같은 페이지는 그러한 구문이 표현식이라는 것을 분명히 나타냅니다.


-6

사전 답변을 개선하고 검증하려면 해당되는 경우 컴퓨터 과학 유형 이론에서 프로그래밍 언어 용어의 정의를 설명해야합니다.

표현식에는 Bottom 유형 이외의 유형이 있습니다. 즉 값이 있습니다. 명령문에는 단위 또는 하단 유형이 있습니다.

이것으로부터, 명령문은 값을 반환 할 수 없거나 할당 할 수없는 단위 유형의 값만 반환하기 때문에 부작용을 만들 때 프로그램에만 영향을 줄 수 있습니다. void진술의 평가 지연을 위해 C 또는) (예 : 스칼라)를 저장할 수 있습니다.

분명히 a @pragma또는 a /*comment*/는 유형이 없으므로 진술과 구별됩니다. 따라서 부작용이없는 유일한 유형의 진술은 작동하지 않을 것입니다. 비 작동은 향후 부작용에 대한 자리 표시 자로서 만 유용합니다. 진술로 인한 다른 조치는 부작용이 될 수 있습니다. 다시 말하지만 컴파일러 힌트 @pragma는 유형이 없기 때문에 명령문이 아닙니다.


2
구별은 표현 유형과 관련이 없습니다. 구문 적으로 정의 된 명령문에는 여러 언어에서 전혀 유형이 없습니다. 내가 이론적으로 같은 조건으로 유형을 지정하려면에 대한 아니에요 있지만, 다른에 대한 치료 @pragma또는 /*comment*/논리적으로 일관성이 있습니다.
FrankHB

-11

가장 정확하게, 문장은 "부작용" (즉, 명령 적 )을 가져야 하며 표현식은 유형 (즉, 맨 아래 유형이 아님)을 가져야 합니다 .

문장유형은 단위 유형이지만, 정리 중단으로 인해 단위는 허구이므로 하단 유형 이라고 말하십시오 .


Void정확하게 최하위 유형이 아닙니다 (가능한 모든 유형의 하위 유형이 아님). 완전히 사운드 타입 시스템이없는 언어로 존재 합니다 . 그것은 snobbish statement처럼 들릴 수 있지만 분산 주석과 같은 완전성 은 확장 가능한 소프트웨어를 작성하는 데 중요합니다.

이 문제에 대해 Wikipedia의 의견을 살펴 보겠습니다.

https://ko.wikipedia.org/wiki/Statement_(computer_science)

컴퓨터 프로그래밍에서 명령문은 수행 해야 할 동작 을 나타내는 명령형 프로그래밍 언어 의 가장 작은 독립형 요소입니다 .

많은 언어 (예 : C)는 실행 가능한 코드 만 포함하는 명령문과 식별자를 선언하는 정의를 사용하여 명령문과 정의를 구별하지만 표현식은 값으로 만 평가됩니다.


5
진술은 부작용이 없어도됩니다. 예를 들어, 파이썬 pass에서는 문장입니다. 그것은 no-op이며, 아무것도 평가하지 않습니다.
Matthew Schinckel

9
-1 잘못되었습니다. 성명은하지 않습니다 부작용을 가지고. C # 언어 사양 의 섹션 1.5를 참조하십시오 . 뿐만 아니라 그것은 하지 않는 문을 지정 해야 부작용을 가지고 있지만 그것은 또한 없습니다 수있는 몇 가지 문장이 나열되어 어떤 부작용.
NullUserException

2
@NullUserException 해당 섹션을 읽었습니다. 선언, 표현식, 선택, 반복 및 점프 문은 모두 부작용을 일으킬 수 있습니다. 그러나 RT 표현식이 있으면 명령문이 아닙니다. 사양이 표현과 표현을 동일시한다는 것을 알고 있지만이 질문은 그 차이점을 요구했습니다. 따라서 질문에 답이 없거나 C # 사양을 문자 그대로 사용하고 있습니다. 가장 많이 투표 된 답변은 내가 한 일을 말하려는 것입니다. 그러나 "무언가를한다"는 의미가 없습니다. "부작용"은 "무언가를한다"라는 의미있는 방법입니다. 우리는 단지 역류하는 것이 아니라 생각해야합니다.
Shelby Moore III

13
@ShelbyMooreIII 당신이 맞아요. 공식 문서가 잘못되었습니다 . Eric Lippert 이외의 SO에서 활동중인 가장 존경받는 C # 포스터 인 Marc Gravell과 Jon Skeet은 잘못되었습니다 . 저와 당신을 억압하고 우리의 입장을 설명하는 의견을 남긴 다른 모든 사람들은 잘못되었습니다 . 네 말이 맞아 당신은 그들이 말하고있는 것을 아는 유일한 사람입니다. 왜냐하면 당신은 다른 모든 SO보다 훨씬 똑똑하기 때문입니다.
NullUserException

3
문장, 표현, 캐스트, 변환 등과 같은 개념의 정확한 정의를 아는 것은 일상적인 프로그래밍 작업의 99.999 %에 영향을 미치지 않습니다. 생각해 . 또한 대부분의 사람들은 Haskell과 Scala에 관심이 없습니다.
NullUserException
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.