문제

C++에서 쉼표 연산자는 어떻게 작동하나요?

예를 들어 다음과 같이 하면:

a = b, c;  

a는 결국 b 또는 c와 같습니까?

(예, 테스트하기 쉽다는 것을 알고 있습니다. 누군가가 답을 빨리 찾을 수 있도록 여기에 문서화하면 됩니다.)

업데이트: 이 질문은 쉼표 연산자를 사용할 때 미묘한 차이를 드러냈습니다.이것을 문서화하려면 다음을 수행하십시오.

a = b, c;    // a is set to the value of b!

a = (b, c);  // a is set to the value of c!

이 질문은 실제로 코드의 오타에서 영감을 받았습니다.무엇을 의도했는가

a = b;
c = d;

로 변하다

a = b,    //  <-  Note comma typo!
c = d;
도움이 되었습니까?

해결책

그것은 같을 것입니다 b.

쉼표 연산자는 할당보다 우선순위가 낮습니다.

다른 팁

C++에서는 쉼표 연산자가 오버로드될 수 있다는 점에 주의하세요.따라서 실제 동작은 예상한 동작과 매우 다를 수 있습니다.

예로서, 부스트스피릿 기호 테이블에 대한 목록 초기화를 구현하기 위해 쉼표 연산자를 매우 영리하게 사용합니다.따라서 다음 구문을 가능하고 의미있게 만듭니다.

keywords = "and", "or", "not", "xor";

연산자 우선순위로 인해 코드는 (의도적으로!) 다음과 동일합니다.

(((keywords = "and"), "or"), "not"), "xor";

즉, 호출된 첫 번째 연산자는 다음과 같습니다. keywords.operator =("and") 나머지 프록시 객체를 반환합니다. operator,s가 호출됩니다:

keywords.operator =("and").operator ,("or").operator ,("not").operator ,("xor");

쉼표 연산자에는 가장 낮은 모든 C/C++ 연산자의 우선순위.따라서 이는 항상 표현식에 바인딩되는 마지막 항목입니다. 즉, 다음과 같습니다.

a = b, c;

다음과 같습니다:

(a = b), c;

또 다른 흥미로운 사실은 쉼표 연산자가 시퀀스 포인트.이는 다음 표현식을 의미합니다.

a+b, c(), d

세 개의 하위 표현식(a+b, 씨() 그리고 ) 순서대로 평가됩니다.부작용이 있는 경우 이는 중요합니다.일반적으로 컴파일러는 적합하다고 판단되는 순서에 따라 하위 표현식을 평가할 수 있습니다.예를 들어, 함수 호출에서:

someFunc(arg1, arg2, arg3)

인수는 임의의 순서로 평가될 수 있습니다.함수 호출의 쉼표는 다음과 같습니다. ~ 아니다 운영자;그들은 구분 기호입니다.

쉼표 연산자:

  • 우선순위가 가장 낮습니다
  • 왼쪽 결합적이다

쉼표 연산자의 기본 버전은 모든 유형(내장 및 사용자 정의)에 대해 정의되며 다음과 같이 작동합니다. exprA , exprB:

  • exprA 평가된다
  • 결과 exprA 무시된다
  • exprB 평가된다
  • 결과 exprB 전체 표현식의 결과로 반환됩니다.

대부분의 연산자에서는 컴파일러가 실행 순서를 선택할 수 있으며 최종 결과에 영향을 주지 않으면 실행을 건너뛰어야 합니다(예: false && foo() 통화를 건너뜁니다. foo).그러나 쉼표 연산자의 경우에는 해당되지 않으며 위의 단계는 항상 발생합니다.*.

실제로 기본 쉼표 연산자는 세미콜론과 거의 동일한 방식으로 작동합니다.차이점은 세미콜론으로 구분된 두 표현식이 두 개의 개별 명령문을 형성하는 반면, 쉼표로 구분하면 모두 단일 표현식으로 유지된다는 것입니다.이것이 바로 다음과 같은 시나리오에서 쉼표 연산자가 사용되는 이유입니다.

  • C 구문에는 단일이 필요합니다. 표현, 주장이 아닌.예를 들어~에 if( HERE )
  • C 구문에는 단일 명령문이 필요합니다.초기화에서는 for 고리 for ( HERE ; ; )
  • 중괄호를 건너뛰고 단일 명령문을 유지하려는 경우: if (foo) HERE ; (그러지 마세요. 정말 추악합니다!)

명령문이 표현식이 아닌 경우 세미콜론을 쉼표로 대체할 수 없습니다.예를 들어 다음은 허용되지 않습니다.

  • (foo, if (foo) bar) (if 표현이 아닙니다)
  • int x, int y(변수 선언은 표현식이 아님)

귀하의 경우에는 다음이 있습니다.

  • a=b, c;, 동등 a=b; c;, 가정 a 쉼표 연산자를 오버로드하지 않는 유형입니다.
  • a = b, c = d; 에 해당 a=b; c=d;, 가정 a 쉼표 연산자를 오버로드하지 않는 유형입니다.

모든 쉼표가 실제로 쉼표 연산자는 아닙니다.완전히 다른 의미를 갖는 일부 쉼표는 다음과 같습니다.

  • int a, b; --- 변수 선언 목록은 쉼표로 구분되어 있지만 쉼표 연산자는 아닙니다.
  • int a=5, b=3; --- 이것은 또한 쉼표로 구분된 변수 선언 목록입니다.
  • foo(x,y) --- 쉼표로 구분된 인수 목록입니다.사실은, x 그리고 y 에서 평가할 수 있다 어느 주문하다!
  • FOO(x,y) --- 쉼표로 구분된 매크로 인수 목록
  • foo<a,b> --- 쉼표로 구분된 템플릿 인수 목록
  • int foo(int a, int b) --- 쉼표로 구분된 매개변수 목록
  • Foo::Foo() : a(5), b(3) {} --- 클래스 생성자의 쉼표로 구분된 초기화 목록

* 최적화를 적용하면 이는 전적으로 사실이 아닙니다.컴파일러가 특정 코드 조각이 나머지 코드에 전혀 영향을 미치지 않는다는 것을 인식하면 불필요한 명령문을 제거합니다.

추가 자료: http://en.wikipedia.org/wiki/Comma_operator

의 가치 a 될거야 b, 그러나 값은 표현식 될거야 c.즉,

d = (a = b, c);

a는 다음과 같다 b, 그리고 d 같을 것이다 c.

b의 값은 a에 할당됩니다.C에게는 아무 일도 일어나지 않을 것이다

쉼표 연산자는 할당 연산자보다 우선순위가 낮으므로 a의 값은 b와 같습니다.

예 쉼표 연산자는 할당 연산자보다 우선순위가 낮습니다.

#include<stdio.h>
int main()
{
          int i;
          i = (1,2,3);
          printf("i:%d\n",i);
          return 0;
}

출력 :나는=3
쉼표 연산자는 항상 가장 오른쪽 값을 반환하기 때문입니다.
할당 연산자가 있는 쉼표 연산자의 경우:

 int main()
{
      int i;
      i = 1,2,3;
      printf("i:%d\n",i);
      return 0;
}

출력:나는=1
우리가 알고 있듯이 쉼표 연산자는 할당보다 우선순위가 낮습니다.....

먼저 첫 번째 것들: 쉼표는 실제로 연산자가 아닙니다. 컴파일러의 경우 의미를 갖는 토큰일 뿐입니다. 문맥 다른 토큰과 함께.

이것이 무엇을 의미하며 왜 귀찮게 합니까?

예시 1:

다른 맥락에서 동일한 토큰의 의미 차이를 이해하기 위해 다음 예를 살펴보겠습니다.

class Example {
   Foo<int, char*> ContentA;
}

일반적으로 C++ 초보자는 이 표현식이 사물을 비교할 수 있다고 생각하지만 이는 완전히 잘못된 것입니다. <, > 그리고 , 토큰은 사용 상황에 따라 다릅니다.

물론 위 예의 올바른 해석은 템플릿의 구현이라는 것입니다.

예시 2:

일반적으로 하나 이상의 초기화 변수 및/또는 루프의 각 반복 후에 수행되어야 하는 하나 이상의 표현식을 사용하여 for 루프를 작성할 때 쉼표도 사용합니다.

for(a=5,b=0;a<42;a++,b--)
   ...

쉼표의 의미는 사용 상황에 따라 다릅니다. 여기서는 쉼표의 의미입니다. for 건설.

문맥상 쉼표는 실제로 무엇을 의미하나요?

(C++에서 항상 그렇듯) 더 복잡하게 만들기 위해 쉼표 연산자 자체가 오버로드될 수 있습니다. 콘라드 루돌프 그것을 지적하기 위해).

질문으로 돌아가서, 코드

a = b, c;

컴파일러에 대한 의미는 다음과 같습니다.

(a = b), c;

왜냐하면 우선 사항 ~의 = 토큰/연산자가 우선순위보다 높습니다. , 토큰.

그리고 이것은 다음과 같은 맥락으로 해석됩니다.

a = b;
c;

(해석은 컨텍스트에 따라 달라지며 여기서는 함수/메서드 호출이나 템플릿 인스턴스화가 아닙니다.)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top