[기록을 위해이 답변을 수락하고 투표 한 이후로이 답변을 상당히 많이 편집했습니다. 그래도 여전히 기본적으로 같은 것을 말합니다.]
이 코드는 고의적으로 혼동 될 수 있습니다. 그것은 겁에 질리지 않은 dread undefined behavior의 인스턴스를 포함합니다 . 이 질문을 만든 사람이 매우, 매우 영리한지, 매우 멍청한 지 판단하는 것은 기본적으로 불가능합니다. 그리고이 코드가 당신에게 가르치거나 퀴즈를 내릴 수있는 "믿지 않는"즉, 단항 더하기 연산자가 많은 것을하지 않는다는 것은 확실히 이런 종류의 파괴적인 오해를받을만한 가치가있는 것은 아닙니다.
코드의 두 가지 혼란스러운 측면, 이상한 조건이 있습니다.
while(+(+k--)!=0)
그리고 그것이 통제하는 진술 문 :
k=k++;
두 번째 부분을 먼저 다루겠습니다.
k1만큼 증가시키고 싶은 변수가 있다면 C는 두 가지가 아니라 세 가지가 아니라 네 가지 다른 방법을 제공합니다.
k = k + 1
k += 1
++k
k++
이 현상금에도 불구하고 (또는 아마도 그로 인해) 일부 프로그래머는 혼란스럽고 뒤틀리는 기침을 유발합니다.
k = k++;
이 작업을 수행 할 수없는 경우 아무도 걱정할 필요가 없습니다. 이 표현에는 k값 ( k =부분과 k++부분) 을 변경하려는 두 가지 다른 시도가 포함되어 있으며 , C에는 어떤 수정 시도가 "승리"할 것인지에 대한 규칙이 없기 때문에 이와 같은 표현은 공식적으로 정의되지 않습니다. 그것은 한 어떤 의미를 정의하지 않지만, 전체 프로그램은 용의자 포함하는 것이다.
당신이 보면 지금 매우 신중하게,이 특정 프로그램에서 선 것을 볼 수 있습니다 k = k++(우리가 볼 수 있도록 대한 것 같은) 제어 조건이 처음에 거짓이기 때문에 루프가 0 번 실행되도록 실제로 실행되지 않습니다 . 따라서이 특정 프로그램은 실제로 정의되지 않았을 수도 있지만 여전히 병리 적으로 혼란 스럽습니다.
이러한 종류의 정의되지 않은 동작에 관한 모든 질문에 대한 정식 SO 답변 도 참조하십시오 .
그러나 당신은 그 k=k++부분 에 대해 묻지 않았습니다 . 첫 번째 혼란스러운 부분 인 +(+k--)!=0상태 에 대해 물었습니다 . 이 때문에, 이상한 모양 입니다 이상한. 실제 프로그램에서 그러한 코드를 작성하는 사람은 없습니다. 따라서 그것을 이해하는 방법을 배울 이유가 없습니다. (예, 사실, 시스템의 경계를 탐색하는 것이 좋은 점에 대해 배우는 데 도움이 될 수 있지만, 내 책에는 상상력이 있고 생각을 자극하는 탐험과 험한 탐험, 험난한 탐험 사이에 분명한 선이 있습니다.이 표현은 매우 명확합니다. 그 선의 잘못된면.)
어쨌든 살펴 보자 +(+k--)!=0. (그리고 그렇게 한 후에는 그것에 대해 모든 것을 잊어 봅시다.) 이와 같은 표현은 내부에서 밖으로 이해되어야합니다. 나는 당신이 무엇을 알고 있다고 가정
k--
그렇습니다. k현재 값을 가져 와서 나머지 표현식으로 "반환"하며, 동시에 거의 감소합니다.k . 즉, 수량을에 k-1다시 저장합니다 k.
그러면 어떻게 +해야합니까? 이것은 이진 플러스가 아니라 단항 플러스입니다. 단항 마이너스와 같습니다. 이진 빼기에서 빼기를 수행한다는 것을 알고 있습니다.
a - b
a에서 b를 뺍니다. 그리고 당신은 단항 마이너스가 물건을 부정한다는 것을 알고 있습니다 : 표현
-a
당신에게 a의 부정을 제공합니다. 단항식 +은 ... 기본적으로 아무것도 아닙니다. 양수 값을 양수로 변경하고 음수 값을 음수로 변경 한 후의 값을 +a제공합니다 a. 그래서 표현
+k--
무엇이든 준다 k-- 에게 준 것, 즉 k오래된 가치를 제공합니다.
하지만 아직 끝나지 않았습니다.
+(+k--)
이것은 +k--당신에게 주어진 +것을 취하고 단항식 을 다시 적용 합니다. 그래서 그것은 당신에게 무엇을 주 +k--었는지, 그것이 무엇이든 k--당신에게 주었던 것입니다. 그것은 k오래된 가치였습니다.
결국 조건은
while(+(+k--)!=0)
훨씬 더 평범한 조건과 정확히 같은 일을합니다
while(k-- != 0)
했을 것입니다. (또한 더 복잡한 모양의 조건과 동일한 기능 while(+(+(+(+k--)))!=0)을 수행합니다. 괄호는 실제로 필요하지 않습니다. 또한 동일한 동작 while(+ + + +k--!=0)을 수행합니다.)
어떤 "정상적인"상태인지 파악
while(k-- != 0)
까다 롭습니다. 이 루프에는 두 가지 일이 있습니다. 루프가 여러 번 실행될 수 있으므로 다음과 같이하겠습니다.
- 계속 해
k-- 해서 k작고 작게 만들지 만
- 루프 바디를 계속 수행하십시오.
그러나 우리는 k--루프를 통해 또 다른 여행을 할 것인지 결정하기 직전에 (또는 과정에서) 부분을 수행합니다. 그리고 k--값을 k낮추기 전에 이전 값 을 "반환" 한다는 것을 기억 하십시오. 이 프로그램에서 초기 값 k은 0입니다. 따라서 k--이전 값 0을 "반환"한 다음 k-1 로 업데이트 합니다. 그러나 나머지 조건은 다음과 같습니다. 그러나 != 0방금 보았 듯이 조건을 처음 테스트했을 때 0을 얻었습니다. 따라서 루프를 통과하지 않으므로 루프를 실행하려고 시도하지 않습니다. 문제가있는 진술k=k++ .
다시 말해서,이 특정 루프에서, "두 가지 일이 진행되고있다"고 말했지만, 일 1은 한 번 발생하지만 일 2는 0 번 발생한다는 것이 밝혀졌습니다.
어쨌든, 나는 왜 프로그램에 대한 불쌍한 핑계가 -1을 최종 값으로 인쇄하는 이유를 충분히 분명히 알기를 바랍니다 k. 일반적으로 저는 이런 질문에 답하기를 좋아하지 않습니다 – 부정 행위처럼 느껴집니다.하지만이 경우 운동의 전체 요점에 너무나 동의하지 않기 때문에 괜찮습니다.