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
평가되어 증가하다i
1에 의해, 그리고 다시 한 번 그 식의 값++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)
로 평가된다.
i
++i
- ㅇㅇㅇㅇㅇ.
1
이 반환되었습니다 , 값값 、 값 , 、 값 , , , , , , 。
그래서, 마지막 진술은
i = 1 + 1;
★★★★★★★★★★★★★★★★★」i
이르다2
질문에 다 것 같아요.
- ?
i
2를 수 있습니까? 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
'programing' 카테고리의 다른 글
Vue 컴포넌트 Vue-Instant (0) | 2022.08.14 |
---|---|
비트 연산자와 "엔디안니스" (0) | 2022.08.14 |
인수와 함께 vuex namesched getters를 사용하는 방법 (0) | 2022.08.14 |
시각 인쇄 방법: 2009 08 08 10 10 18 : 17 : 54 . 811 (0) | 2022.08.14 |
Vue.js는 슬롯에서 컴포넌트 인스턴스로 데이터를 전달합니다. (0) | 2022.08.14 |