블로그 이미지
fiadot_old

칼퇴근을 위한 게임 서버 개발 방법론에 대한 심도있는 고찰 및 성찰을 위한 블로그!

Rss feed Tistory
Technical Article/펌 2002. 12. 15. 09:05

[공지] WarGame메뉴에 대한...

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 12. 13. 17:38

해커스쿨 2차대회

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 11. 12. 01:48

패킷스니핑 개념이해...

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 10. 14. 07:21

[C++] reinterpret_cast' static_cast 에 대해서..

제    목  [답변]reinterpret_cast' static_cast 에 대해서..  
작 성 자  이원구(iwongu)   첨 부
파 일  
작성시간  2000-08-10 오전 11:54:16
조 회 수  351

안녕하세요. 이원구입니다.

기존의 C에 있던 cast 연산에는 몇가지 문제가 있었습니다.
예를 들어 다음과 같은 문장을 보면

Data* data = (Data*)pSomething;

여기서 쓰인 cast가 무엇인지 알수 있는 방법이 없습니다. 코드를 보는 사람뿐 아니
라 컴파일러도 알수 없겠죠. 따라서 컴파일러는 무조건 casting을 하게 됩니다. 또
한 후에 아주 긴 코드상에서 cast한 부분만을 보고자 할때도 검색어로 괄호를 넣을수
도 없고 난감하지요.

이러한 몇가지 점을 보완하고 개발자들에게 여러가지 편리함을 주고자 C++에서는 네
가지 cast operator가 정의되었습니다. static_cast, dynamic_cast,
const_cast, reinterpret_cast가 그것입니다.

간단히 설명을 하자면 다음과 같습니다.

static_cast - 기본적으로 기존 C에서 casting하던 것과 같은 역할을 합니다. 따
라서 기존의 C의 casting으로 안되던 것들은 이것으로도 되지 않습니다. 또한
const형을 non-const형으로 cast하는 것 역시 이 연산자로 할수 없습니다.

const_cast - const형 데이터를 non-const형으로 바꾸거나 volatile형을 non-
volatile형으로 cast해 줍니다. 다른 용도로는 사용할 수 없습니다.

dynamic_cast - class들의 inheritance hierachy들 사이를 올바르게 cast하는
데 사용됩니다. 다른 용도로는 사용할수 없습니다. 이 기능은 RTTI(Run-time
Type Information)기능을 참고하시면 도움이 되실 겁니다. 참고로 이 연산자는 올
바로 cast되지 않는 경우에는 null을 return하기 때문에 매우 유용하게 사용됩니
다.

reinterpret_cast - 이 cast는 보통 구현에 따라 다르게 작업을 수행한다고 되어
있습니다. 따라서 이 연산자는 다른 컴파일러에 porting이 어렵다고 되어 있습니
다. 보통 위의 세가지 cast로 불가능한 casting을 할때 사용되며 서로 다른 프로토
타입을 가진 함수 포인터를 casting하는데 주로 사용이 됩니다.

다시 위의 예로 돌아가면

Data* data = const_cast< Data*>(pSomething);
Data* data = dynamic_cast< Data*>(pSomething);
Data* data = static_cast< Data*>(pSomething);

와 같은 문장이 있다면 왜 casting이 필요했는지를 쉽게 이 부분의 코드만 봐도 확인
이 되겠지요. 물론 컴파일러도 좀더 효율적이고 정확하게 컴파일이 가능할테고요.

마지막으로 C++에 관련된 책중에 여러가지 item으로 구성되어 있어서 재밌고 유용하
게 읽을수 있는 책으로

Effective C++, by Scott Meyers, Addison Wesley
More Effective C++, by Scott Meyers, Addison Wesley

가 있습니다. 꼭 한번 읽어 보세요. 그냥 C++책이나 object-oriented 관련 서적
을 읽는 것과는 다른 맛(?)이 있습니다.

그럼 이만...

도움이 되셨나요.

:) iwongu /R /C /S /L
mailto:iwongu@rcsl.inha.ac.kr
http://rcsl.inha.ac.kr/~iwongu
,
Technical Article/펌 2002. 9. 3. 20:21

Integer Pack & UnPack...

기능??
32비트 컴파일러에서는 int형이 4바이트를 차지한다.
실제로 정수를 사용할때 이만큼 많은 수가 필요한 경우는 많지않으므로..
압축해서 사용해보자~~

이 소스에서는 16비트 컴파일러를 기준으로 int가 2바이트일때...
low, high가 256이하일때만 비트연산을 통해서 둘을 압축해서 리턴한다!

int        IntergerPack(int *nPack, int nHighByte, int nLowByte)
{
        int nTmpHigh, nTmpLow;
        
        *nPack = 0;

        if ( nHighByte > 255 || nLowByte > 255 )
                return FALSE;

        nTmpHigh = 0xFF00 & (nHighByte << 8);
        nTmpLow = 0x00FF & nLowByte;
        
        *nPack = nTmpHigh | nTmpLow;
        

        return TRUE;
}

int        IntergerUnpack(int nPack, int *nHighByte, int *nLowByte)
{
        *nHighByte = (nPack & 0xFF00 ) >> 8;
        *nLowByte = (nPack & 0x00FF);

        return TRUE;
}
,
Technical Article/펌 2002. 8. 20. 02:40

m = (++i) + (++i) 에 대한 고찰....

───────────────────────────────────────
#26     Pooh    (석원홍  )
[아시는 분]간단한 계산                                       08/19 19:16     6

#include <stdio.h>

int main()
{
int i = 0;
int m = 0;
m = (++i)+(++i);

printf("%d",m);
}

과연 결과는 한 번 쯤 생각해 보구요..^^;.







결과는 4가 나오네요..ㅠㅠ..3을 예상했는데요.(리눅스에서)

그런데 다른 분이 솔라리스에서 같은 버젼에 gcc에서

컴파일하니..3이 나왔다고 하네요..


어떤 게시판에서 본 건데...저런 식으로 사용은 거의(?)
되지 않지만, 저런 질문이 흥미롭긴 한데..

어떻게 알야내야 할지...^^;.

오늘도 좋은 하루..











#27     lovydayz(이근호  )
미테 문제  풀이잡설...                                       08/20 20:02     6
일단 결론부터 말씀드리면...

컴파일러의 지능(?)차이라고...

일단 3이 나온놈이 한갑자 높은놈이라 생각하심이...

왜인지는 밑에를 쭈욱 봐주세요 ^^


연산자 우선순위로 봤을때...

()먼저... ++ ... 그담이 + 가 되겠슴다....

즉... ++i == 1.... 두번째 ++i 에서 2...

즉 1+2 = 3이 되어야 코드를 짠사람의 의도라고 할수 있겠는데...

(내 맘대로 추측한건가 ㅡㅡ;;;)



일반적인 컴파일러 결과는 조금 다르져...

(여기서 일반적이라 함은 원홍이 행님이 한것과 내가 VC6++에서 테스트한것)

몇가지 실험을 해보면...

(++i) + (--i) == 0
(++i) + (  i) == 2
(++i) + (++i) == 4
(  i) + (++i) == 2
(--i) + (++i) == 0

5가지 경우를 비교했을때...알수있는건...

괄호의 유무와 연산자의 결합우선순위와 상관없이...

같은 라인에 있는 같은변수를 ++ -- 하는 연산은...

서로 각각 처리가 됨을 알수 있습니다.



왜 이렇게 되는지 이해하려면 디스어셈블한 코드를

살짜기 보면 쉽게 알수있는데

(어셈을 제대로 공부한게 아니고 후루꾸로 해서

  제대로는 못합니다 ㅡㅡ;; 감안해줘요)


8:        m = (++i) + (++i);
00401036   mov         eax,dword ptr [ebp-8]
00401039   add         eax,1
0040103C   mov         dword ptr [ebp-8],eax
eax레지스테어 i의 주소를 넣고.. 1을 더해주죠...
그담에 다시 i에다가 값을 넘깁니다.

0040103F   mov         ecx,dword ptr [ebp-8]
00401042   add         ecx,1
00401045   mov         dword ptr [ebp-8],ecx
ecx에 i의 주소를 넘기고 1증가시키고...다시 i에 넣고
위에랑 똑같은데 레지스터만 ecx써  

00401048   mov         edx,dword ptr [ebp-8]
edx에 i의 주소를 넘기구요...

0040104B   add         edx,dword ptr [ebp-8]
요기가 압권!!!
즉 i + i 에서 뿌라스 기호 부분인데...
현재i는 2인데...이놈을 edx에 다시 더해서..
즉 4 ㅡㅡ;;; 여기서 바로 4가 나오는 이유가 밝혀진것임다...으흐흐흐

0040104E   mov         dword ptr [ebp-4],edx
이게 마지막의 m = 이 구문..


즉.... 한라인에서 대입문에 들어가는 연산문에서 (말이 좀 어렵네 ㅡㅡ;;)

i의 주소를 바탕으로 각각의 증가(++) 감소(--)연산자는 제대로 연산이 되지만

마지막에 인자의 합을 더하는 부분에서...

주소를 통해 합이 도출되기   문에...

4가 나온다는 말씀이 되겠슴다.


그럼 3이 나온놈은 무엇이냐 ... 대강은 짐작하셨겠지만...

(아직 3이 나온놈을 디스어셈블 못해봐서 뭐라 말하기는 그렇지만...)

컴파일러에서 바이너리코드를 생성할때...

새로운 레지스터를 등록해서 eax, ecx를 더해서...

그걸 edx에 넘겨주는걸로 사료됩니다.

그렇게 하면 3이 나오겠죠 ^^



역시 심오한 C ^^

이샹 =3=3=3=3=3
,
Technical Article/펌 2002. 7. 31. 19:31

[펌] array[i] 와 *(array+i)의 차이

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 7. 31. 12:31

[펌] 서버 접속인원의 한계

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 7. 24. 13:55

[펌] 문자열을 원하는데로 자르자.. - Split함수 구현

보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력해주세요.

Technical Article/펌 2002. 6. 24. 10:17

[펌] dbgprintf 예~

이제 F9, F5 키는 잊어 먹으세요..

제가 MSDN에서 파다가 나온 황금같은 소스를 걍 올릴께엽..

void dbgprint(const PCHAR lpszFmt,...)
{
    CHAR szBuf[512];
    va_list vargs;

    va_start(vargs,lpszFmt);
    vsprintf(szBuf, lpszFmt, vargs);
    va_end(vargs);
    OutputDebugString(szBuf);
    return;
}

아웃풋창에 걍 뜹니다.

실시간 디버깅시에 무척 유용하겠죠...

다만 실행시간이 좀 느려진다는 단점도 있으니깐

ifdef을 잘 이용하세요....
,
TOTAL TODAY