김동수 님이 쓰신 글 :
: 안녕하세요?
: 몇 년 째 집에 있는 C언어 책을 방치해두었다가
: 근래들어 공부를 하고 있습니다.
: 논리연산자 파트에 있는 예제의 결과를 보면서
: 대체 어떻게해서 이렇게 나오는건지 무척이나 궁금하더군요.
:
: #include<stdio.h>
: #include<conio.h>
: void main()
:
: {
:
: int a =5, b=3, c=1, d;
:
: d=(a=a-2)||(b=b-1);
: printf("d=%d a=%d b=%d\n", d, a, b);
:
: d=(a=a-3)&&(c=c+3);
: printf("d=%d a=%d c=%c", d, a, c);
: getch();
:
: }
:
: 입니다.
: 책의 결과에서는
: d=1 a=3 b=3
: d=0 a=0 c=1
: 라고 써있던데요.
: 왜 이런 값들이 나온지 제 머리로는 알 수가 없네요 ㅜ_ㅡ
:
: 그리고 저 예제가 틀린게 아닐까 하고 터보씨에 쳐봤는데
: Possibly incorrect assignment 이런 경고 메세지가 뜨더군요.
: -_- 대체 무엇인지요?
실력은 없지만 알고 있는 부분만 알려 드릴께요..
일단 두번째 printf문에 %c가 아니라 %d 인것 같네요..
그래서 경고문이 뜬는 것이 아닐까 조심스럽게 짐작해보는....
집에 터보씨가 없고 비주얼 씨뿔뿔이 있기에 돌려보니 괜찮다는...
일단 d=(a=a-2)||(b=b-1);이 라인은...
헤메실 필요 없이 연산자는 저희가 일반 수학에서 연산하는것이랑 같습니다..
일단 괄호 안에있는 것을 먼저 연산 하면...
a에다가 a-2 를 넣으면 a에 지금 5 가 들어가 있으므로 3 이 됩니다..
그다음 만나는 연산자인 || 연산자는 A || B 의 경우 A혹은 B두개중 한이상이 참이면 참을 의미하는 or 연산자 입니다.
여기서 참과 거짓의 경계는 일반적으로는 1 이면 참 0 이면 거짓이나...
컴퓨터는 0 이면 거짓을 0 이외의 숫자는 모두 참을 의미 합니다..
그래서 여기서는 벌써 3 이란 숫자가 나왔기 때문에 이 식은 참이 됩니다...
그래서 컴파일러는 그 뒤의 라인은 실행 할 필요가 없으므로 바로 다음 라인으로 건너 가게 됩니다..
즉 b = b-1이란 실행은 되지 않습니다..
결과는 d는 참이 되므로 d에 1이 들어 가게 됩니다..
그리고 d=(a=a-3)&&(c=c+3);란 라인은...
위와 같은 방법으로 해석해 보면
a에다가 a-3를 넣으면 a에는 아까 연산된 값인 3이 들어 있으므로 0이 됩니다..
그 다음 만나는 연산자인 && 연산자는 A && B 의 경우 A 와 B 두개 모두 참일때 참이되는 and 연산자 입니다.
그러므로 벌써 a = a -3 이란 식에서 0이란 결과가 나왔으므로
이 식은 결국에는 거짓이 되어 버립니다.
그래서 컴파일러는 뒤에 식을 실행하지 않고 바로 d 에 0을 넣고 다음 라인으로 넘어가 버립니다..
그래서 결과 값이 다음과 같이 나옵니다..
d=1 a=3 b=3
d=0 a=0 c=1
그리고 참고로
d=(a=a-2)||(b=b-1);
위의 식을
d=(a=a-5)||(b=b-1);
로 수정한다면 (a=a-5)결과값이 0이므로 뒤의 식의 값을 알아야 이 라인의 결과 값이 나옵니다.
그래서 b=b-1도 실행이 됩니다.
역시 그다음 식인
d=(a=a-3)&&(c=c+3);
식을
d=(a=a+3)&&(c=c-1);
으로 수정한다면 a=a+3결과 값이 참이 되므로 c=c+3식까지 계산되어야 겨로가 값이 나옵니다.
그리서 위의 예제로 결과를 보면
d=1 a=0 b=2
d=0 a=3 c=0
결과가 나옵니다.
그래서 님께서 궁금해 하신 예제는
약간은 신경을 써야 하고 프로그래머가 예상치 못한 결과가 나올수 있으므로
보통은 논리연산 전에 먼저 식을 계산하고 논리연산을 하는것이 좋습니다.
아마도 그 예제는 논리연산의 의미를 파악하게 하기 위한 예제인것 같습니다.
즉
d=(a=a-2)||(b=b-1);
식을
a=a-2;
b=b-1;
d=a||b;
으로 바꾸고
d=(a=a-3)&&(c=c+3);
식을
a=a-3;
c=c+3;
d=a&&c;
로 하면 모든 연산이 수행되고
그 값으로 논리연산을 수행하게 됩니다..
혹시나 더 궁금한점이 계시면 알고 있는데로 알려 드릴께요..
메일 주세요
|