programing

i = (i, ++i, 1) + 1은 무엇을 합니까?

bestcode 2022. 8. 14. 12:03
반응형

i = (i, ++i, 1) + 1은 무엇을 합니까?

정의되지 않은 동작과 시퀀스 포인트에 대한 이 답변을 읽은 후 작은 프로그램을 작성했습니다.

#include <stdio.h>

int main(void) {
  int i = 5;
  i = (i, ++i, 1) + 1;
  printf("%d\n", i);
  return 0;
}

출력은2오, 세상에, 감소가 올 줄 몰랐어요!여기서 무슨 일이 일어나고 있는 거야?

또한 위의 코드를 컴파일 할 때 다음과 같은 경고를 받았습니다.

px.c:5:8: warning: 쉼표식의 왼쪽 피연산자는 영향을 받지 않습니다.

  [-Wunused-value]   i = (i, ++i, 1) + 1;
                        ^

왜요? 하지만 아마 첫 번째 질문의 답변으로 자동적으로 대답할 수 있을 거예요.

표현 중에(i, ++i, 1)사용되는 쉼표는 쉼표 연산자입니다.

쉼표 연산자(토큰으로 나타남),)는 첫 번째 피연산자를 평가하여 결과를 폐기한 다음 두 번째 피연산자를 평가하여 이 값(및 유형)을 반환하는 바이너리 연산자입니다.

첫 번째 피연산자를 파기하기 때문에 일반적으로 첫 번째 피연산자가 바람직한 부작용이 있는 경우에만 유용합니다.첫 번째 오퍼랜드에 대한 부작용이 발생하지 않으면 컴파일러는 아무런 효과도 없는 식에 대한 경고를 생성할 수 있습니다.

그래서 위의 표현에서 가장 왼쪽은i평가되고 그 값은 파기됩니다.그리고나서++i평가되어 증가하다i1에 의해, 그리고 다시 한 번 그 식의 값++i폐기되겠지만 그 부작용은 영구적입니다.그리고나서1평가되고 표현의 값은 다음과 같습니다.1.

와 동등하다.

i;          // Evaluate i and discard its value. This has no effect.
++i;        // Evaluate i and increment it by 1 and discard the value of expression ++i
i = 1 + 1;  

위의 표현은 완전히 유효하며 쉼표 연산자의 왼쪽 오퍼랜드와 오른쪽 오퍼랜드의 평가 사이에 시퀀스 포인트가 존재하기 때문에 정의되지 않은 동작을 호출하지 않습니다.

결과

(i, ++i, 1)

1

위해서

(i,++i,1) 

평가는 다음과 같이 이루어집니다.,연산자는 평가된 값을 폐기하고 다음 중 가장 적절한 값을 유지합니다.1

그렇게

i = 1 + 1 = 2

쉼표에는 '역' 우선순위가 있습니다.이는 IBM(70년대/80년대)의 오래된 책과 C 매뉴얼에서 얻을 수 있는 것입니다.그래서 마지막 '명령어'는 부모 표현에서 사용되는 명령어입니다.

현대 C에서는 이 용도가 낯설지만 오래된 C(ANSI)에서는 매우 흥미롭다.

do { 
    /* bla bla bla, consider conditional flow with several continue's */
} while ( prepAnything(), doSomethingElse(), logic_operation);

모든 연산(함수)이 왼쪽에서 오른쪽으로 호출되는 동안 마지막 식만 조건부 'while'의 결과로 사용됩니다.이렇게 하면 조건 확인 전에 실행할 명령어 블록을 유지하는 'goto' 처리가 방지됩니다.

EDIT: 이것은 또한 왼쪽 오퍼랜드에서 모든 로직을 처리할 수 있는 처리 함수에 대한 호출을 방지하고 논리 결과를 반환합니다.과거 C에는 인라인 기능이 없었습니다.이것에 의해, 콜의 오버헤드를 회피할 수 있습니다.

★★★에서 인용C11장 , »6.5.17, 콤마 연산자

쉼표 연산자의 왼쪽 피연산자는 void 식으로서 평가됩니다.평가와 오른쪽 피연산자의 피연산자 사이에는 시퀀스 포인트가 있습니다.그런 다음 오른쪽 피연산자가 평가됩니다. 결과에는 피연산자의 유형과 값이 포함됩니다.

그럼, 당신 경우엔

(i, ++i, 1)

로 평가된다.

  1. i
  2. ++i
  3. ㅇㅇㅇㅇㅇ.1이 반환되었습니다 , 값값 、 값 , 、 값 , , , , , , 。

그래서, 마지막 진술은

i = 1 + 1;

★★★★★★★★★★★★★★★★★」i 이르다2 질문에 다 것 같아요.

  • ?i2를 수 있습니까? 2를 얻을 수 있습니까?
  • 경고 메시지가 표시되는 이유는 무엇입니까?

주의: FWIW, 왼쪽 피연산자의 평가 후에 시퀀스 포인트가 존재하기 때문에 다음과 같은 식입니다.(i, ++i, 1)UB를 호출하지 않습니다.일반적으로 잘못 생각할 수 있습니다.

i = (i, ++i, 1) + 1;

차근차근 분석해 봅시다.

(i,   // is evaluated but ignored, there are other expressions after comma
++i,  // i is updated but the resulting value is ignored too
1)    // this value is finally used
+ 1   // 1 is added to the previous value 1

2를 구합니다.그리고 이제 마지막 과제:

i = 2;

이제 덮어쓰기 전에 i에 있던 게 뭐든 간에 말이야

Wiki 페이지에서 콤마 연산자를 읽을 수 있습니다.

기본적으로는

...는 첫 번째 피연산자를 평가하고 결과를 폐기한 다음 두 번째 피연산자를 평가하여 이 값(및 유형)을 반환합니다.

즉,

(i, i++, 1)

평가하다i하고, 평가하다, 평가하다.i++하여 반환한다.1.

여기서 콤마 연산자가 무엇을 하는지 알아야 합니다.

표정:

(i, ++i, 1)

표현은요?i인 을 평가합니다.++i되고 세 표현인 " " " " 가 평가됩니다1는 식 전체에 대해 반환됩니다.

해서 이렇게 됩니다.i = 1 + 1.

질문은 바와 첫 표현입니다i전혀 효과가 없기 때문에 컴파일러가 불평합니다.

언급URL : https://stackoverflow.com/questions/30614396/what-does-i-i-i-1-1-do

반응형