2014-10-22 8 views
5

높은 수준의 OOP 언어 인 C#과 Java에서 최근 C에서 머리를 긁기 시작했습니다. 나는 C가 약간 이상하다고 생각합니다. 심지어 OOP 언어 그러나 아래이 쉼표 사용은 표현식에서 작동하지만 선언에서 실패하는 이유는 무엇입니까?

int i=0,1,2; 

/* 
Error : expected identifier or ‘(’ before numeric constant 
int i = 0, 1, 2; 
      ^
*/ 

을에 잘못된 구문처럼 보이는 놀라운 작품

다음 오류를 제공하고 직관적 인 것 같습니다 : 그래서 아래 명확히 할

int i; 
i = 0,1,2; //works 

가 왜 동작입니다 ? 그러한 행동이나 파싱 전문성을 지키기위한 그들의 중요성은 무엇입니까? 동등

+4

@ Mahesha999 실제로 _bigger_ 질문 일 것입니다 : 왜 지구상에 그런 것을 써야합니까? 문법에는 _ "declaration \ declaration-specifiers; \ declaration-specifiers init-declarator-list;"_ 그게 전부입니다. 그런 코드를 작성하는 것이 직관적이라고 생각합니까 (쉼표 연산자에 _intuitive_가 있으면)? –

+0

@DebasishJana이 답변은 다른 누구도 얻지 못했던 것으로 설명하면서 선언문이 작동하지 않는 이유를 설명하지 않습니다. –

+0

@AdrianoRepetti 표현식과 선언에서','사이의 구별이 여기에있는 답안에서 분실 된 것 같습니다. 그것이 질문의 흥미로운 부분입니다. –

답변

7

이것은 실제로 복잡한 문법의 세부 사항에 의존하기 때문에 까다로운 질문입니다. 그것을 이해하는 가장 좋은 방법은 draft standard입니다. Annex A언어 구문 요약을 참조 할 수 있습니다.

i = 0,1,2; 

가되는 식입니다

int i=0,1,2; 

이 선언하고 있습니다 :

기본적인 아이디어는 점이다.선언 콤마 우리는 좌측 (부작용 대개 )를 평가 한 결과를 버린다 후 오른쪽 등을 평가합니다 comma operator 가질 수 식에서

...

쉼표 연산자가 아닌 문법적 구분 기호입니다.

다음과
int i=0,1,2; 
     ^^^^ 

C99 표준에서 관련 문법대로 : 그래서

init-declarator-list: 
    init-declarator 
    init-declarator-list , init-declarator <--- here comma is just a seperator 
init-declarator: 
    declarator 
    declarator = initializer 

,는 선언자를 분리하고 12 이후이 선언의 맥락에서 선언자하지 않은 잘못된 구문입니다 이 경우 ,으로 구분합니다. 선언자 또는 선언자 = 이니셜 라이저12선언자이 아니므로 잘못된 구문이 있습니다.

그것은 초기화할당 표현 수 있습니다 가치가 아무것도하지만 우리는 (()에서 쉼표 연산자로 끝날 수 있지만이 표현은, 베어 쉼표 연산자에 우리에게 경로를 제공하지 않습니다 ~ 주 표현식)하지만 구분 기호처럼 보이지는 않습니다. 섹션 6.5.17에서 발현 관련 문법

이다 :

expression: 
    assignment-expression 
    expression , assignment-expression 

콤마 연산자의 설명은 다음과 같이은 :

콤마 연산자의 왼쪽 피연산자 평가 공백으로 표현; 평가 후 시퀀스 포인트가 있습니다. 그런 다음 오른쪽 피연산자가 계산됩니다. 결과는 그 유형 및 값을 갖는 [...]을 콤마 연산자lowest precedence 다음 식을 갖는 것을주의

:.

(i = 0),1,2; 
:

i = 0,1,2; 

가 동등을

이므로 i의 값은 0이되고 이후 평가 결과는 버려집니다.

+0

+1 나는 여전히 질문의 요지를 보지 못하지만 확실한 이유는 그 이유를 설명하는 대답에 대한 답이다. –

+0

@AdrianoRepetti 내가 OP가 비슷한 문맥처럼 보이는 구문에서 작동하지 않는 이유를 얻으려고하는 것을 이해합니다. C 또는 C++에서 충분히 길게 찌르면 분명한 답변이없는 이러한 기이함을 많이 발견하게됩니다. –

+0

예하지만 이번에는 너무 이상하게 보이지 않았습니다. 어쨌든 ... –

9
i = 0,1,2; 

이것은 할당 : 오른쪽 먼저 할당 i = 0 다음 식 1 왼쪽에서 (가장 낮은 우선 순위를 갖는)

(i = 0), 1, 2; 

콤마 연산자는 피연산자를 평가 2 그리고 그 결과를 버립니다.

번째 예

int i=0,1,2; 

초기화된다. 합법적 인 초기화 int i = 0, j = 0;과 비교하십시오.

당신이 사용하는 경우 그것은 작동합니다

int i=(0,1,2); 
+1

그리고 과제물과 함께 작동합니다! 하지만 왜? ??? 쉼표가 허용되거나 할당 및 초기화가 허용되거나 허용되지 않는 곳의 정확한 사양은 무엇입니까? – Mahesha999

+0

실제로는'operator ', (operator, (0,1), 2)와 같은'(0,1,2)'의 결과를'i'에 할당합니다. – qdii

+0

@qdii, '(i = 0), 1, 2'을합니다. – zch

0

1

int i, j; 
    i = 3,0,1,2; 
    printf("%d\n", i); => prints 3 

2

i = 3,j =7; 
    printf("%d, %d\n", i, j); => prints 3 and 7 

i = 3,0,1,2;3 to i을 할당 한 다음 01을 실행. 언급 한 두 번째 예제를 확인하십시오.

또한 시도하십시오. i=3;0;1;2; 오류를보고하지 않습니다. 그냥 (i=3), (0), (1) and (2)을 실행합니다.