00411CE5 mov eax,dword ptr [b] -> 첫번째 ++b를 연산하기 위해서 b변수를 eax레지스터에 저장
00411CE8 add eax,1 -> eax과 1을 더해서 eax레지스터에 저장
00411CEB mov dword ptr [b],eax -> eax를 b변수에 다시 저장.. 여기서 b변수의 값은 4
00411CEE mov ecx,dword ptr [b] -> 두번째 ++b를 연산하기 위해서 다시 b변수값을 ecx레지스터에 저장
00411CF1 add ecx,1 -> ecx과 1을 더해서 ecx레지스터에 저장
00411CF4 mov dword ptr [b],ecx -> ecx를 b변수에 다시 저장.. 여기서 b변수의 값은 5
00411CF7 mov edx,dword ptr [b] -> + 연산을 위해서 b변수의 값을 edx레지스터에 저장
00411CFA add edx,dword ptr [b] -> edx 레지스터의 값과 b변수의 값을 합해서 edx레지스터에 저장
00411CFD mov dword ptr [a],edx -> edx레지스터의 값을 a변수에 저장
공부하시는거라면 모르겠지만 실제로 돌아가는 프로그램에서 저렇게 머리아프게 코드 짜시면 안됩니다. ;)
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
연산자 결합방향으로 이항연산자인 +가 평가될려면 우선 양 항이 먼저 평가 되어야합니다.
그렇기 때문에 첫번째 +가 평가되기 위해서는 양쪽 ++b가 평가되어서 5+5가 됩니다.
그리고 이 결과가 다시 두번째 +와 결합하여 평가되어야하기 때문에 양 항이 평가되어서
왼쪽항인 10은 상수이므로 아무런 일이 일어나지 않지만 오른쪽항인 ++b는 6으로 평가되어서 최종적으로
10+6이 됩니다.
여기까지 위의 결과를 내는 컴파일러 입장에서 분석을 한 것이지.. 다른 컴파일러에서는 실제로 이렇게 일어나지 않을수도 있습니다.
10*10 + 11*11 + 12*12가
(10*10) + (11*11) + (12*12)와 같이 평가 되어야하는 것 처럼
++연산자도 +연산자보다 우선순위가 높으므로
(++b) + (++b) + (++b)가 맞습니다만..
평가되는 변수 자체의 값이 변하는 경우에는 논리적으로 연산자 우선순위에 따라서 평가를 하더라도
중간에 값이 변해버리기 때문에 어떻게 평가될지는 모릅니다.
그러므로 저런 코드는 절~~대 만들지 마시고 정확히 써주셔야합니다.:)
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
어렵게 떠들자면 두 시퀸스 포인트 사이에서 동일한 객체가 두번이상 수정되는 행위는 정의되지 않은 행동 어쩌고 저쩌고가 되겠고, 걍 간단하게 말하자면 저런거 쓰지 마세요.
9가 나오던 10이 나오던 8이 나오던 컴파일러 맘입니다.
위와 같은 수식에서
1) 언제 b의 값을 읽어오는가
2) 언제 b의 값을 증가시키는가
이 두가지 행동을 어떤 순서대로 할지에 대해서, C언어는 특별히 제한을 두고 있지 않기 때문에 각자 컴파일러 하기 나름입니다. 보장된 것은 오로지 수식 마지막의 ;이전에 그 작업들이 모두 끝난다는 것 뿐. b의 증가를 단일 명령어로 하는가 레지스터로 읽어오고 증가시킨뒤 다시 쓰고 하는가에 따라서는 ;이후의 b의 값이 5가 아니라 4가 될 수도 있는 일입니다.
연산자 우선순위에
연산자 우선순위에 의해서 아래와 같이 계산되는듯 합니다.
1.첫번째 ++b -> 4
2.두번째 ++b -> 5
3.1과2의 합을 위해 +연산 -> b(5) + b(5) -> 10
어셈코드를 보니 아래와 같이 되는군요
공부하시는거라면 모르겠지만 실제로 돌아가는 프로그램에서 저렇게 머리아프게 코드 짜시면 안됩니다. ;)
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
이 경우는 어떻게 생각하세요? ++b + ++b + ++b
b가 3일때, 아래와 같이 계산하면 몇이 나올까요?
++b + ++b + ++b
이전 답글에 의하면, 6+6+6 = 18 이 나올꺼라 예상되지만, 실제 결과 값은 16이 나옵니다.
왜 이런것일 까요?
ㅠㅜ
나는 본인이 맞음을 증명하노라 ㅋ
이것도 대략
이것도 대략 이런식입니다..
((++b) + (++b)) + (++b))
b가 3이었으므로
(++b) + (++b)) -> 10.. b는 5
(10 + ++b) -> 16
이해 가시는지요?
5 + 5 + 6 -> 16
연산자 결합방향으로 이항연산자인 +가 평가될려면 우선 양 항이 먼저 평가 되어야합니다.
그렇기 때문에 첫번째 +가 평가되기 위해서는 양쪽 ++b가 평가되어서 5+5가 됩니다.
그리고 이 결과가 다시 두번째 +와 결합하여 평가되어야하기 때문에 양 항이 평가되어서
왼쪽항인 10은 상수이므로 아무런 일이 일어나지 않지만 오른쪽항인 ++b는 6으로 평가되어서 최종적으로
10+6이 됩니다.
여기까지 위의 결과를 내는 컴파일러 입장에서 분석을 한 것이지.. 다른 컴파일러에서는 실제로 이렇게 일어나지 않을수도 있습니다.
10*10 + 11*11 + 12*12가
(10*10) + (11*11) + (12*12)와 같이 평가 되어야하는 것 처럼
++연산자도 +연산자보다 우선순위가 높으므로
(++b) + (++b) + (++b)가 맞습니다만..
평가되는 변수 자체의 값이 변하는 경우에는 논리적으로 연산자 우선순위에 따라서 평가를 하더라도
중간에 값이 변해버리기 때문에 어떻게 평가될지는 모릅니다.
그러므로 저런 코드는 절~~대 만들지 마시고 정확히 써주셔야합니다.:)
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.
어렵게 떠들자면 두
어렵게 떠들자면 두 시퀸스 포인트 사이에서 동일한 객체가 두번이상 수정되는 행위는 정의되지 않은 행동 어쩌고 저쩌고가 되겠고, 걍 간단하게 말하자면 저런거 쓰지 마세요.
9가 나오던 10이 나오던 8이 나오던 컴파일러 맘입니다.
위와 같은 수식에서
1) 언제 b의 값을 읽어오는가
2) 언제 b의 값을 증가시키는가
이 두가지 행동을 어떤 순서대로 할지에 대해서, C언어는 특별히 제한을 두고 있지 않기 때문에 각자 컴파일러 하기 나름입니다. 보장된 것은 오로지 수식 마지막의 ;이전에 그 작업들이 모두 끝난다는 것 뿐. b의 증가를 단일 명령어로 하는가 레지스터로 읽어오고 증가시킨뒤 다시 쓰고 하는가에 따라서는 ;이후의 b의 값이 5가 아니라 4가 될 수도 있는 일입니다.
덧붙이자면, 위의
덧붙이자면, 위의 수식은 이식성이 없는 코드일 뿐만 아니라 근본적으로 틀린 코드입니다.
답변감사합니다.
대충 무슨 말씀을 하시는지 감이 오네요
답변 감사합니다.
나는 본인이 맞음을 증명하노라 ㅋ
나는 본인이 맞음을 증명하노라 ㅋ
댓글 달기