태그 보관물: c

c

“if”및 “while”과 함께 사용되는 언어에서 표현식에 괄호가 필요한 이유는 무엇입니까? 언어 ++

에서 사용할 때 C, Java 및 C와 같은 언어 ++ 모두는 전체 표현식 주위에 괄호가 필요 if, while또는 switch.

if (true) {
    // Do something
}

반대로

if true {
    // Do something
}

괄호가 중복되어 있기 때문에 이것은 이상하게 보입니다. 이 예에서는 true자체적으로 단일 표현식입니다. 괄호는 내가 아는 방식으로 그 의미를 변형시키지 않습니다. 왜이 이상한 구문이 존재하고 왜 그렇게 일반적입니까? 내가 모르는 이점이 있습니까?



답변

있을 필요가 몇 가지 조건이 끝나고 분기가 시작되는 이야기의 방법. 그렇게하는 방법에는 여러 가지가 있습니다.

일부 언어에서 더 조건문이없는 모든 스몰 토크, 자기, 신어, 이오, Ioke, Seph, 팬시에서 예. 조건부 분기는 다른 방법과 마찬가지로 일반적인 방법으로 간단하게 구현됩니다. 이 메소드는 부울 오브젝트에서 구현되며 부울에서 호출됩니다. 그런 식으로 조건은 단순히 메소드의 수신자이며 두 분기는 예를 들어 스몰 토크에서 두 가지 인수입니다.

aBooleanExpression ifTrue: [23] ifFalse: [42].

Java에 익숙한 경우 다음과 같습니다.

aBooleanExpression.ifThenElse(() -> 23, () -> 42);

Lisp 계열의 언어에서는 상황이 비슷합니다. 조건은 단지 정상적인 함수 (실제로는 매크로)이고 첫 번째 인수는 조건이고 두 번째 및 세 번째 인수는 분기이므로 일반 함수 인수 일뿐입니다. 그들을 구분하는 데 특별한 것이 필요하지 않습니다.

(if aBooleanExpression 23 42)

일부 언어는 키워드를 구분 기호로 사용합니다 (예 : Algol, Ada, BASIC, Pascal, Modula-2, Oberon, Oberon-2, Active Oberon, Component Pascal, Zonnon, Modula-3) :

IF aBooleanExpression THEN RETURN 23 ELSE RETURN 42;

Ruby에서는 키워드 또는 표현식 구분 기호 (세미콜론 또는 줄 바꿈)를 사용할 수 있습니다.

if a_boolean_expression then 23 else 42 end

if a_boolean_expression; 23 else 42 end

# non-idiomatic, the minimum amount of whitespace required syntactically
if a_boolean_expression
23 else 42 end

# idiomatic, although only the first newline is required syntactically
if a_boolean_expression
  23
else
  42
end

Go 는 브랜치가 블록이어야하고 표현식이나 문장을 허용하지 않으므로 중괄호가 필수입니다. 따라서 원하는 경우 추가 할 수 있지만 괄호는 필요하지 않습니다. Perl6과 Rust는 이와 관련하여 비슷합니다.

if aBooleanExpression { return 23 } else { return 42 }

일부 언어는 영숫자가 아닌 다른 문자를 사용하여 조건을 구분합니다 (예 : Python).

if aBooleanExpression: return 23
else: return 42

결론은 : 당신이 필요로하는 몇 가지 조건이 끝나고 분기가 시작되는 이야기의 방법. 그렇게하는 방법에는 여러 가지가 있으며 괄호는 그중 하나 일뿐입니다.


답변

괄호는 중괄호를 사용하는 경우에만 필요하지 않습니다.

if true ++ x;

예를 들어 그것들이 없으면 모호해진다.


답변

에서 괄호 if문은 산술 식 내에서 사용되는 괄호와 같은 의미가 없습니다. 산술 표현식의 괄호는 표현식을 함께 그룹화하는 데 사용됩니다. if명령문의 괄호 는 부울 표현식을 구분하는 데 사용됩니다. 즉, 부울 표현식을 나머지 if명령문 과 구별합니다 .

에서 if문 괄호 그룹화 기능을 수행하지 않는 (그래도 내 if문, 당신은 여전히 그룹 산술 식에 괄호를 사용할 수 있습니다. 괄호의 외부 세트는 다음 전체 부울 식을 구분하는 역할을한다). 컴파일러를 사용하면 컴파일러가 항상 존재하는 괄호에 의존 할 수 있으므로 컴파일러를 단순화 할 수 있습니다.


답변

다른 사람들이 이미 부분적으로 지적했듯이 이것은 표현식도 유효한 명령문이기 때문에 하나의 명령문이있는 블록의 경우 중괄호를 삭제할 수 있습니다. 이것은 다음이 모호하다는 것을 의미합니다.

if true
    +x;

다음과 같이 해석 될 수 있기 때문입니다.

if (true + x) {}

대신에:

if (true) {+x;}

여러 언어 (예 : Python)를 사용하면 괄호를 피할 수 있지만 여전히 종료 조건 마커가 있습니다.

True 인 경우 : + x

그러나 당신은 우리가 옳다 수있는 표현 인 언어 : 괄호가 필요하지 않습니다 언어를 정의 하지 유효한 문이 문제가없는 것이다.

불행히도 이것은 다음과 같은 것을 의미합니다.

 ++x;
 functionCall(1,2,3);

유효한 명령문 이 아니므 로 표현식을 작성하지 않고 이러한 조치를 수행 할 수 있도록 이상한 구문을 도입해야합니다. 이를 수행하는 간단한 방법은 다음과 같은 마커로 표현식 앞에 추가하는 것입니다 [statement].

[statement] ++x;
[statement] functionCall(1,2,3);

이제 다음과 같이 작성해야하기 때문에 모호성이 사라집니다.

if true
    [statement] ++x;

그러나 당신이 볼 수 있듯이 if조건에 (또는 :그 끝에) 괄호 를 두는 것이 모든 표현 문장에 대해 그러한 표시를하는 것보다 훨씬 낫기 때문에 그러한 언어가 널리 퍼져있는 것을 보지 못합니다 .


참고 : [statement]마커 사용은 내가 생각할 수있는 가장 간단한 구문입니다. 그러나 이러한 마커가 필요하지 않은 표현식과 명령문에 대해 완전히 구별되는 두 가지 구문을 가질 있습니다. 문제는 표현에서 동일한 작업을 수행하거나 완전히 다른 구문을 사용해야하는 명령문에서 언어가 매우 이상하다는 것입니다.

그러한 명시 적 마커없이 두 개의 별도 구문을 사용하는 것을 염두에 두어야 할 한 가지는 다음과 같습니다. 강제 문은 유니 코드 기호를 사용하도록합니다 (따라서 for문자의 유니 코드 변형을 사용하는 대신 f, or). ASCII 만.


답변

C 계열 언어는 이러한 괄호를 요구하는 것이 일반적이지만 보편적 인 것은 아닙니다.

펄 6의 더 눈에 띄는 구문 변화 중 하나는 괄호를 주위에 제공 할 필요가 없도록 그들이 문법을 수정한다는 것입니다 if, for유사한 문 ‘조건. 따라서 이와 같은 것은 Perl 6에서 완벽하게 유효합니다.

if $x == 4 {
    ...
}

그대로

while $queue.pop {
    ...
}

그러나 그것들은 단지 표현식이기 때문에 원한다면 괄호를 넣을 수 있습니다.이 경우 C, C #, Java 등 구문의 필수 부분 대신 일반 그룹화 그룹입니다.

Rust는이 부서에서 Perl 6과 비슷한 문법을 ​​가지고 있습니다 :

if x == 4 {
    ...
}

더 현대적인 C 영감 언어의 특징은 이런 것을보고 제거하는 것에 대해 궁금해하는 것 같습니다.


답변

기존 답변 중 어느 것도 제기되지 않았다는 것에 놀랐습니다.

C와 많은 C 파생물과 모양 은 할당 값이 할당 된 값 이라는 점에서 특이 합니다. 그 결과 값이 예상되는 곳에 할당을 사용할 수 있습니다.

이것은 당신이 같은 것을 쓸 수 있습니다

if (x = getValue() == 42) { ... }

또는

if (x == y = 47) { ... }

또는

unsigned int n = 0 /* given m == SOME_VALUE */;
while (n < m && *p1++ = *p2++) { n++; }

( while (n < m && *p1++ = *p2++ != 0) { n++; }C가 0이 아닌 것을 사실로 취급하기 때문에 암시 적으로 처리됩니다 . 그러나 우연히 C 표준 라이브러리의 strncpy ()에 불과하다고 생각합니다)

또는

if (x = 17);

그리고 그것은 모두 유효합니다. 구문 적으로 유효한 모든 조합이 반드시 유용한 것은 아니며 (현대의 컴파일러는 공통 오류이므로 조건부 내부의 할당에 대해 특히 경고합니다) 실제로 일부는 유용합니다.

조건식이 시작되고 끝나는 위치를 결정하는 명확한 방법이 없다면 그러한 진술을 파싱하는 것이 훨씬 어려울 것입니다.

괄호는 이미 함수 인수에서 함수 이름을 구분하는 데 사용되었으므로 키워드 인수에서 키워드를 구분하는 자연스러운 선택처럼 보였습니다.

물론 다른 구문도 동일한 작업을 수행하도록 정의 할 수 있습니다. 그러나 그렇게하면 특히 파서에서 복잡성이 증가하여 거의 동일한 것을 위해 두 가지 다른 구문 세트를 처리해야합니다. C를 설계 할 당시에는 컴퓨팅 성능 (숫자 처리 능력, 작업 메모리 및 저장 용량 측면에서)이 극히 제한적이었습니다. 가독성에 거의 또는 전혀 비용을 들이지 않고 복잡성을 줄인 것은 거의 확실히 환영받는 변화였습니다.

괄호를 사용하면 오늘날 약간 구식으로 보일지 모르지만 언어에 익숙한 사람이 있다면 같은 것을 표현할 수있는 다른 구문에 비해 가독성이 떨어집니다.


답변

그 이유는 대부분 역사입니다.

최초의 C 컴파일러가 작성 될 당시 컴퓨터에는 컴파일러 작성기를 도와주는 도구가 거의없는 “수동으로”작성된 램, CPU 및 컴파일러가 매우 제한적입니다. 따라서 복잡한 규칙은 컴파일러에서 구현하는 데 많은 비용이 들었 습니다. C ++, C #, Java 등은 모두 C 프로그래머가 쉽게 배울 수 있도록 설계 되었으므로 “필요하지 않은”변경은 없었습니다.

‘c like’언어에서 조건부 ( if, while, etc)에는 명시 적 block오프 코드가 필요하지 않으며 간단한 명령문 만 사용할 수 있습니다.

if (a == d) doIt()

또는 당신은 compound statement그것들을{}

우리는 컴파일러가 오류를 찾아서 이해할 수있는 오류 메시지를 표시하는 것을 좋아합니다.