C ++에서 쉼표 연산자의 다른 동작이 반환됩니까?


83

다음은 쉼표 연산자에 유의하세요 .

#include <iostream>
int main() {
    int x;
    x = 2, 3;
    std::cout << x << "\n";
    return 0;
}

출력 2 .

그러나 return쉼표 연산자와 함께 사용 하는 경우 다음 과 같습니다.

#include <iostream>
int f() { return 2, 3; }
int main() {
    int x;
    x = f();
    std::cout << x << "\n";
    return 0;
}

출력 3 .

쉼표 연산자가 다르게 작동하는 이유는 무엇 return입니까?


답변:


140

받는 따르면 운영자 우선 순위 , 콤마 연산자는 보다 낮은 우선 가지고 operator=있으므로 x = 2,3;등가이다 (x = 2),3;. (연산자 우선 순위는 우선 순위에 따라 연산자가 다른 연산자보다 더 단단하거나 느슨한 방식으로 인수에 바인딩되는 방식을 결정합니다.)

쉼표식이 (x = 2),3아니라 여기에 2,3있습니다. x = 2처음에 평가되고 (그리고 그 부작용이 완료 됨) 결과가 폐기 된 다음 3평가됩니다 (실제로 아무 작업도 수행하지 않음). 그래서의 값 x2. 주 3전체 쉼표 표현 (즉,의 결과는 x = 2,3)에 할당하는 데 사용되지 않습니다 x. (변경 그것은하는 x = (2,3);, x할당됩니다 3.)

를 들어 return 2,3;, 쉼표 표현은 2,3, 2다음 평가의 결과는 폐기하고 3평가에 의해 반환되는 전체 쉼표 표현의 결과로 반환 return 문 이상.


에 대한 추가 정보

표현식은 계산을 지정하는 일련의 연산자와 해당 피연산자입니다.

x = 2,3;is expression statement , x = 2,3은 여기에있는 표현식입니다.

세미콜론이 뒤에 오는 표현식은 명령문입니다.

통사론: attr(optional) expression(optional) ; (1)

return 2,3;점프 문 ( return 문 )이며 2,3여기에있는 표현식입니다.

통사론: attr(optional) return expression(optional) ; (1)


1
좋은 설명. 그러나 실용적인 응용 프로그램이 있습니까? 아니면 그냥 오류?
Jean-François Fabre

7
@ Jean-FrançoisFabre IMO는 혼란스럽고 전혀 유용하지 않습니다.
songyuanyao

11
for이상하게도 수치 계산에서 코드를 더 명확하게 만들 수있을 때 루프 에서 한두 번 사용되는 것을 보았습니다 .
Bathsheba

6
@ Jean-FrançoisFabre : Bathesheba가 말했듯 i += 1, j += 2이 for 루프 와 같은 것을 작성할 수 있습니다 . 누군가는 C ++ 문법 (또는이 부분이 거기에서 복사 되었기 때문에 C 문법)이 이미 충분히 복잡하다고 결정했습니다. 콤마의 우선 순위가 당신이 쓸 때 할당보다 높지만 당신이 쓸 때 더 낮다는 것을 정의하려고 시도하지 않고 이미 충분히 복잡 x = 2, 3합니다 x = 2, y = 3!
Steve Jessop

1
@Holger : 세미콜론은 명령문을 종료하며 연산자가 아닙니다. 이것은 더 명확하게하기 위해 대답을 조정할 수있는 것입니다. "x = 2, 3"은 연산자가 2 개인 표현식이며 for (;;)를 지원하는 이유로 =이 우선 순위가 높습니다. (다른 사람들이 말했듯이.) 그러나 "return 2, 3;" "2, 3"표현식이 포함 된 명령문입니다. 기술적 으로 "반품"이라는 키워드에 대한 우선 순위 는 없습니다 . ( 효과적으로 는 표현식을 받아들이는 문장의 일부이기 때문에 마지막으로 구문 분석 됩니다 . 표현식의 어떤 연산자보다 "우선 순위"가 낮습니다 .)
Micha Berger

32

쉼표 ( 표현식 분리 라고도 함 ) 연산자는 왼쪽에서 오른쪽으로 평가됩니다. 그래서 return 2,3;동일합니다 return 3;.

의 평가 x = 2,3;이다 (x = 2), 3;때문에 연산자 우선 순위 . 평가는 여전히 왼쪽에서 오른쪽으로 이루어지며 전체 표현식은 값 2를 x가정하는 부작용과 함께 값 3을 갖습니다 .


2
표현식 분리 연산자 에 대해 좀 더 편집하고 더 자세히 설명해 주 시겠습니까? @songyuanyao의 답변에 대한 의견에서 언급했듯이 이유 return 2,3return (2,3)동일 함을 이해할 수 있습니다 . 나는 전자가이어야한다고 믿었다 (return 2),3.
xyz

@BiagioFesta는 그 부분을 잘 설명합니다.
밧세바

1
@ prakharsingh95 return 2는 표현식 이 아니라 문 (예 :로 형성된 것과 같은 for,while,if)입니다. 예를 들어 f(return 2)또는 2+return 2. 따라서 (return 2),3구문 적으로 유효하지 않습니다.
chi

@chi 네, 맞습니다. 나는 기다리고 있었다 의미 return 2, 3하는 해석 으로 (return 2), 3.
xyz

2
C ++의 문법에 따라 @ prakharsingh95는 return(a) return expression_opt ; 및 (b) return braced-init-list 경우에만 발생할 수 있습니다 ;.
MM

20

이 진술 :

  x = 2,3;

두 가지 표현 으로 구성됩니다 .

> x = 2
> 3

이후 운영자 우선 순위 , =콤마보다 우선 순위를 가지고 ,, 그래서 x = 2계산되고 이후 3 . 다음 x과 같아야합니다 2.


에서 return대신 :

int f(){ return 2,3; }

언어 구문은 다음과 같습니다.

return <expression>

메모 return 는 표현의 일부가 아닙니다.

따라서이 경우 두 표현식은 다음과 같이 평가됩니다.

> 2
> 3

그러나 두 번째 ( 3) 만 반환됩니다.


2
UV'd. 매우 까다 롭지 만 <expression>문법적 관점에서 명시 적으로 선택 사항으로 표시하면 좋을 것 입니다.
밧세바

2
의 구문 분석 트리에는 5 개의 표현식이 있습니다 x=2,3. 리터럴 2과 모두 3식별자와 마찬가지로 구문 분석 트리의 맨 아래에 x있습니다. 이들은 모두 개별적으로 유효한 표현식입니다. 우선 조작 수단 =발생 하부 파싱 트리에서 두 표현을 결합 x2네번째로 표현 x=2. 마지막으로 다섯 번째 표현식은 두 변을 결합하는 쉼표 연산자 x=23. 그러나 연산자 우선 순위 가 평가 순서 를 결정한다고 잘못 설명했습니다 . 그렇지 않습니다. 평가 순서는 순서 지정 규칙에 따라 결정됩니다.
MSalters

2
나는 반환 식의 일부가 아닌 것을 언급 위해 투표
다니엘 주르에게

@MSalters 나는 당신과 동의하지만, 난 그냥 잘못 "이라는 단어를 사용 하기 때문에를 대신"의 " 이후 ". 내 영어가 너무 완벽하지 않은 것! ;-=
Biagio Festa

2
여기서 "매크로 표현"은 전문 용어입니까? 전 처리기의 의미에서 "매크로 표현식"도 존재할 때 사용하는 것이 약간 혼란스러워 보입니다.
senshin

2

괄호로 우선 순위를 강조하는 단순한 접근 방식을 적용하십시오.

( x = 2 ), 3;

return ( 2, 3 );

이제 우리는 왼쪽에서 오른쪽으로 같은 방식으로 작동하는 이항 연산자 ""를 볼 수 있습니다.


1
까다로운 부분은 그 실현 x = 2, 3을위한 동안, 표현 자체 return가입니다 return <expression>. 그래서 당신은 그들을 (x = 2, 3)(2, 3).
xyz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.