? : 연산자는 C에서 정확히 어떻게 작동합니까?


10

다음 코드에서 컴파일러가 작동하는 방법에 대한 질문이 있습니다.

#include<stdio.h>

int main(void)
{
  int b=12, c=11;
  int d = (b == c++) ? (c+1) : (c-1);
  printf("d = %i\n", d);
}

나는 결과가 왜 확실하지 않다 d = 11.


1
왜 확실하지 않습니까? 다른 무엇을 기대하고 왜?
Gerhardh

2
정확한 의미론을 기억하지는 않지만 정의되지 않은 동작을 관찰하고있을 수 있습니다.
chepner

3
아니요, @chepner, 선택한 대안을 평가하기 전에 3 항의 조건을 평가 한 후 시퀀스 지점이 있습니다. 그것은 내가 생각하는 UB 벡터를 피합니다.
John Bollinger

그래, 컴파일러가 어디에서 선택할 수 있을지 잘 모르겠다.
chepner

답변:


6

에서 int d = (b == c++) ? (c+1) : (c-1);:

  • 의 값은 c++현재 값인 c11입니다. 별도로 c12가 증가합니다.
  • b == 11b12 이므로 false 입니다.
  • 때문에 (b == c++)거짓, (c-1)사용됩니다. 또한 c이 시점까지 12 의 증분을 완료해야합니다.
  • 이후 c12, c-111이다.
  • d 해당 값인 11로 초기화됩니다.

5

C 표준 (6.5.15 조건부 연산자)에 따름

4 첫 번째 피연산자가 평가됩니다. 평가와 두 번째 또는 세 번째 피연산자 (둘 중 평가되는 것)의 평가 사이에 시퀀스 지점이 있습니다. 두 번째 피연산자는 첫 번째 피연산자가 0과 같지 않은 경우에만 평가됩니다. 세 번째 피연산자는 첫 번째 피연산자가 0과 동일한 경우에만 평가됩니다. 결과는 두 번째 또는 세 번째 피연산자 (둘 중 평가되는 것)의 값이며 아래에 설명 된 유형으로 변환됩니다 .110)

따라서이 선언의 표현을 초기화 할 때

int d = (b == c++) ? (c+1) : (c-1);

변수는 b변수의 값과 비교 c후 증가 연산자 그것을 증가 전에 피연산자의 값을 반환하기 때문이다.

값이 서로 같지 않기 때문에 ( b12 c로 설정되고 11로 설정 됨) 하위 표현식 (c-1)이 평가됩니다.

인용문에 따르면 연산자의 상태를 평가 한 후 시퀀스 포인트가 있습니다. 이는 증분 후 연산자를 변수에 적용한 후 조건 평가 후 c12을 가짐을 의미 합니다 c. 결과적으로 변수 d는 값 1( 12 - 1)으로 초기화됩니다 .


2
유일한 정답-이 특정 사례는의 시퀀스 포인트를 언급하여 답변해야합니다 ?:. 일반적으로 C에서는 ++동일한 피연산자에서 다른 연산과 결합 하는 것이 정의되지 않은 동작입니다. 그리고이 코드 ?:는 다양한 특수 눈송이 규칙이 있기 때문에 예측 가능하게 작동합니다 .
Lundin

4

조건이 거짓 Beacuse, 그러므로 false경우이 발생합니다 c-1,하지만 당신은 증가 이후 c로 조건에 c++따라서 c지금이다 12. 따라서 결과는 12-1이며 11입니다.

편집 : OP로 오해 된 것은 포스트 증가입니다.

실제로 실제로 일어나는 일은 다음과 같습니다.

#include<stdio.h>
int main(void)
{
  int b=12, c=11;
  int d;

  if (b == c) { // 12 == 11 ? -> false
    c = c + 1;
    d = c + 1;
  } else { // this executes since condition is false
    c = c + 1; // post increment -> c++ -> c = 12 now
    d = c - 1; // 12 - 1 = 11 -> d = 11
  }
  printf("d = %i\n", d);
}

1
OP는 c++조건에 따라 작업 순서를 참조한다고 생각합니다 . 조건이 false이지만 증가 된 버전이 아닌의 원래 값이 c계산에 사용됩니다 c - 1.
chepner

1
나는 sincce 12 == 11 + 1 인 것이 사실이라고 생각했습니다.
J0S

그러나 새로운 c 값이 사용 되었기 때문에 사실이 아닙니다.
Eraklon

나는 오해 사이에있을 수 있습니다 생각 c++하고++c
ChatterOne

@ N00b c++는 증분 연산자입니다. 의 값 c++은 11이며 제작의 부작용이 c == 12있습니다. ++c(12)의 값 것이다
chepner

4

일반적인 if 문으로 변환하면 코드는 다음과 같습니다.

int b=12, c=11;
int d;

if (b == c++)
   d = c+1;
else
   d = c-1;

여기서 단서 는 조건을 확인한 c가 증가한다는 것 입니다. 따라서 else상태 를 입력 하지만 c는 이미 12의 값을 갖습니다.


1

삼항 연산자를 참조하십시오 .

통사론

질환 ? value_if_true : value_if_false

그래서 당신은 썼습니다

int d = (b == c++) ? (c+1) : (c-1);

이 경우 결과가 11이되면 'c'값이 증가하고 (c + 1 = 12) 그 후에 만 ​​'d'값을 c (12) -1 (11)로 설정하기 때문에 결과는 11이됩니다.

예를 들어 사용한 경우 :

int d = (b == ++c) ? (c+1) : (c-1);

명령문을 확인하기 전에 "c"값이 증가하므로 true이고 "d"값은 c (12) +1 (13)입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.