_countof를 이용하면 정적으로 할당된 배열의 개수를 구 할 수 있다.


예제1>

int n[2];

int rt = _countof(n);

rt에는 2 가 입력된다.


하지만 이것을 포인터로 변환해 버리면 개수를 구 할 수 없다.


예제2>

int* p = n;

int rt2 = _countof(p);


컴파일 오류가 난다.


프로그래밍에 유용하게 쓰기는 힘들꺼 같다.


링크

#pragma once


class CCriticalSection2   

{   

private:   

CRITICAL_SECTION  m_cs;   

public:   

CCriticalSection2()   

{   

InitializeCriticalSection(&m_cs);   

}   

~CCriticalSection2()   

{   

DeleteCriticalSection(&m_cs);   

}   


inline void Enter() { EnterCriticalSection(&m_cs); }   

inline void Leave() { LeaveCriticalSection(&m_cs); }   

};   


template<class T>   

class CMultiThreadSync   

{   

friend class CThreadSync;   

private:   

static CCriticalSection2 m_Sync;   

public:   

class CThreadSync   

{   

public:   

CThreadSync()   

{   

T::m_Sync.Enter();   

}   

~CThreadSync()   

{   

T::m_Sync.Leave();     

}   

};   

};   


template<class T>   

CCriticalSection2 CMultiThreadSync<T>::m_Sync;


///////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////

// 실제사용

// 

// class CMyThred : public CMultiThreadSync<CMyThred>   

// {   

// }   

// //구현부분   

// 

// void CMyThread()   

// {   

// CThreadSync sync;   

// //작업 수행   

// }  

// 


링크


#if !defined (__AutoDetectMemoryLeak_h__)

#define __AutoDetectMemoryLeak_h__


#if defined(_MSC_VER) && defined (_DEBUG)

#define _CRTDBG_MAP_ALLOC // 메모리 누수를 탐지하기 위해 선언 해주어야 한다.

#include <crtdbg.h>

#if !defined (_CONSOLE)

#include <cstdlib> // for Consol Application

#endif


class __AutoDetectMemoryLeak

{

public:

    __AutoDetectMemoryLeak ()

    {

        _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | 

            _CRTDBG_LEAK_CHECK_DF);


        // Consol Application인 경우

#if defined (_CONSOLE)

        // Send all reports to STDOUT

        _CrtSetReportMode( _CRT_WARN,               _CRTDBG_MODE_FILE   );

        _CrtSetReportFile( _CRT_WARN,               _CRTDBG_FILE_STDOUT );

        _CrtSetReportMode( _CRT_ERROR,              _CRTDBG_MODE_FILE   );

        _CrtSetReportFile( _CRT_ERROR,              _CRTDBG_FILE_STDOUT );

        _CrtSetReportMode( _CRT_ASSERT,             _CRTDBG_MODE_FILE   );

        _CrtSetReportFile( _CRT_ASSERT,             _CRTDBG_FILE_STDOUT );



        /* new로 할당된 메모리에 누수가 있을 경우 소스상의 

        정확한 위치를 덤프해준다.

        *  ※ _AFXDLL을 사용할때는 자동으로 되지만 CONSOLE 

        모드에서 아래처럼

        * 재정의를 해주어야만 합니다.

        *    date: 2000-12-05

        */

#define DEBUG_NORMALBLOCK   new ( _NORMAL_BLOCK, __FILE__, __LINE__ )

#ifdef new

#undef new

#endif

#define new DEBUG_NORMALBLOCK


#else


        // Send all reports to DEBUG window

        _CrtSetReportMode( _CRT_WARN,   

            _CRTDBG_MODE_DEBUG  );

        _CrtSetReportMode( _CRT_ERROR,  

            _CRTDBG_MODE_DEBUG  );

        _CrtSetReportMode( _CRT_ASSERT, 

            _CRTDBG_MODE_DEBUG  );


#endif


#ifdef malloc

#undef malloc

#endif

        /*

        * malloc으로 할당된 메모리에 누수가 있을 경우 위치

        를 덤프

        * CONSOLE 모드일 경우 crtdbg.h에 malloc이 정의되어 

        있지만,

        * _AXFDLL 모드일 경우에는 약간 다른방식으로 덤프 하

        게된다.

        * date: 2001-01-30

        */

#define malloc(s) (_malloc_dbg( s, _NORMAL_BLOCK, __FILE__, __LINE__ ))

    }

};


// 몇 가지 초기화를 생성자를 통해 자동으로 해주기 위해 전역으로 선언한다.

static __AutoDetectMemoryLeak __autoDetectMemoryLeak;


#endif // if defined(_MSC_VER) && defined (_DEBUG)


#endif // __AutoDetectMemoryLeak_h__

메모리 누수


#if !defined (__AutoDetectMemoryLeak_h__)
#define __AutoDetectMemoryLeak_h__

#if defined(_MSC_VER) && defined (_DEBUG)
#define _CRTDBG_MAP_ALLOC // 메모리 누수를 탐지하기 위해 선언 해주어야 한다.
#include <crtdbg.h>
#if !defined (_CONSOLE)
#include <cstdlib> // for Consol Application
#endif

class __AutoDetectMemoryLeak
{
public:
    __AutoDetectMemoryLeak ()
    {
        _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | 
            _CRTDBG_LEAK_CHECK_DF);

        // Consol Application인 경우
#if defined (_CONSOLE)
        // Send all reports to STDOUT
        _CrtSetReportMode( _CRT_WARN,   
            _CRTDBG_MODE_FILE   );
        _CrtSetReportFile( _CRT_WARN,   
            _CRTDBG_FILE_STDOUT );
        _CrtSetReportMode( _CRT_ERROR,  
            _CRTDBG_MODE_FILE   );
        _CrtSetReportFile( _CRT_ERROR,  
            _CRTDBG_FILE_STDOUT );
        _CrtSetReportMode( _CRT_ASSERT, 
            _CRTDBG_MODE_FILE   );
        _CrtSetReportFile( _CRT_ASSERT, 
            _CRTDBG_FILE_STDOUT );


        /* new로 할당된 메모리에 누수가 있을 경우 소스상의 
        정확한 위치를 덤프해준다.
        *  ※ _AFXDLL을 사용할때는 자동으로 되지만 CONSOLE 
        모드에서 아래처럼
        * 재정의를 해주어야만 합니다.
        *    date: 2000-12-05
        */

#define DEBUG_NORMALBLOCK   new ( _NORMAL_BLOCK, __FILE__, __LINE__ )
#ifdef new
#undef new
#endif
#define new DEBUG_NORMALBLOCK

#else

        // Send all reports to DEBUG window
        _CrtSetReportMode( _CRT_WARN,   
            _CRTDBG_MODE_DEBUG  );
        _CrtSetReportMode( _CRT_ERROR,  
            _CRTDBG_MODE_DEBUG  );
        _CrtSetReportMode( _CRT_ASSERT, 
            _CRTDBG_MODE_DEBUG  );

#endif

#ifdef malloc
#undef malloc
#endif
        /*
        * malloc으로 할당된 메모리에 누수가 있을 경우 위치
        를 덤프
        * CONSOLE 모드일 경우 crtdbg.h에 malloc이 정의되어 
        있지만,
        * _AXFDLL 모드일 경우에는 약간 다른방식으로 덤프 하
        게된다.
        * date: 2001-01-30
        */

#define malloc(s) (_malloc_dbg( s, _NORMAL_BLOCK, __FILE__, __LINE__ ))
    }
};

// 몇 가지 초기화를 생성자를 통해 자동으로 해주기 위해 전역으로 선언한다.
static __AutoDetectMemoryLeak __autoDetectMemoryLeak;

#endif // if defined(_MSC_VER) && defined (_DEBUG)

#endif // __AutoDetectMemoryLeak_h__


링크

///////////////////////////////////////////////////////////////////////////// 


/*Log.h*/ 


#define MAX_BUFFER_LENGTH 1024


class CLog

public: 

// 생략기호(ellipsis)인...는 컴파일러에게 이후의 인수에 대해서는 개수와 타입을 점검하지 않도록 한다. 이 기호에 의해 가변인수를 사용할 수 있다. 

static BOOL WriteLog(LPTSTR data, ...) 

SYSTEMTIME    SystemTime; 

TCHAR        CurrentDate[32] = {0, }; 

TCHAR        CurrentFileName[MAX_PATH] = {0, }; 

FILE*        FilePtr = NULL; 

TCHAR        DebugLog[MAX_BUFFER_LENGTH] = {0, }; 

TCHAR        Log[MAX_BUFFER_LENGTH] = {0, }; 


// va_list = char*형, 가변인수를 읽기 위해 포인터변수를 선언했다고 생각하면 된다. 

va_list        ap; 


// va_start(가변인수, 마지막 고정변수) 

// 가변인수 ap를 고정변수data 다음의 메모리에 올리고 초기화한다. 

// va_arg(ap, 인자타입) 인자타입을 받아 ap부터 반복적으로 다음 인자를 리턴한다. 

va_start(ap, data); 


// 로그에 데이터를 입력한다. 

_vstprintf_s(Log, _countof(Log), data, ap); 

// va_end(ap) 가변인수를 다 읽은 후 뒷정리한다. 

va_end(ap); 


// 시스템시간 가져오기 

GetLocalTime(&SystemTime); 


// 현재 데이터변수에 현재 시간을 저장한다. 

_sntprintf_s(CurrentDate, _countof(CurrentDate), 32, _T("%02d-%02d-%02d %02d:%02d:%02d"), 

SystemTime.wYear, 

SystemTime.wMonth, 

SystemTime.wDay, 

SystemTime.wHour, 

SystemTime.wMinute, 

SystemTime.wSecond); 


// 현재 파일이름을 저장한다. 

_sntprintf_s(CurrentFileName, _countof(CurrentFileName), MAX_PATH, _T("LOG_%04d-%02d-%02d %02d.txt"), 

SystemTime.wYear, 

SystemTime.wMonth, 

SystemTime.wDay, 

SystemTime.wHour); 


// 파일이 없으면 파일을 생성하고 파일이 있으면 존재하는 파일내용 다음에 쓴다. 

_tfopen_s(&FilePtr, CurrentFileName, _T("a")); 


// 생성이 되지 않으면 

if(!FilePtr) 

return FALSE; 


// 파일에 현재 날짜와 로그를 입력한다. 

_ftprintf(FilePtr, _T("[%s] %s\n"), CurrentDate, Log); 


// 디버그 로그에 현재 날짜와 로그를 입력한다. 

_sntprintf_s(DebugLog, _countof(DebugLog), MAX_BUFFER_LENGTH, _T("[%s] %s\n"), CurrentDate, Log); 


// 버퍼를 해제한다. 

fflush(FilePtr); 


// 파일을 닫는다. 

fclose(FilePtr); 


// 디버그 로그를 출력한다. 

OutputDebugString(DebugLog); 

_tprintf(_T("%s\n"), DebugLog); 


return TRUE; 

}; 

//////////////////////////////////////////////////////////////////////////////////// 


에이스타 알고리즘 클래스로 정리




MyPathConsol.zip




원본 소스 : 링크

vs2008로 작업 되어 있고, 마우스로 클릭하면 지형을 생성합니다.

길찾기 4방향

PathFind.zip


길찾기 8방향


PathFind8way.zip





#include <queue>

#include <deque>


//

// 배열 내용 값 순서

// 0 1 2

// 3 4 5

// 6 7 8

// 

// 찾는 순서

// 0: 왼쪽, 1:위쪽, 2:오른쪽, 3:아래쪽


class Puz

{

public:

enum { MAX_PUZ = 9 };

enum PUZ_DIRECTION { PUZ_LEFT = 0, PUZ_UP, PUZ_RIGHT, PUZ_DOWN, PUZ_DIRECTION_MAX };

Puz()

:m_pParant(NULL), m_nDeep(0)

{

  for(int i = 0; i < MAX_PUZ; ++i)

  m_nPuz[i] = 0;


for(int i = 0; i < 4; ++i)

m_nNotMove[i] = true;

}


Puz* m_pParant;

int m_nPuz[MAX_PUZ];

int m_nDeep;

bool m_nNotMove[PUZ_DIRECTION_MAX];


void SwapPuz( int _nIndex1, int _nIndex2 )

{

int nTemp = m_nPuz[_nIndex1];

m_nPuz[_nIndex1] = m_nPuz[_nIndex2];

m_nPuz[_nIndex2] = nTemp;

}


bool EqualPuz( Puz* _p )

{

for(int i = 0; i < MAX_PUZ; ++i)

{

if( this->m_nPuz[i] == _p->m_nPuz[i] )

{

}

else

{

return false;

}

}


return true;

}


int SearchZero()

{

for( int i = 0; i < MAX_PUZ; ++i )

{

if( 0 == m_nPuz[i] )

return i;

}


CCLog( "SearchZero() Error!" );

return -1;

}


bool CanMove( int _eVal )

{

switch( _eVal )

{

case PUZ_LEFT:

{

int nZero = SearchZero();

if( 0 == nZero || 3 == nZero || 6 == nZero )

return false;

}

break;

case PUZ_UP:

{

int nZero = SearchZero();

if( 0 == nZero || 1 == nZero || 2 == nZero )

return false;

}

break;

case PUZ_RIGHT:

{

int nZero = SearchZero();

if( 2 == nZero || 5 == nZero || 8 == nZero )

return false;

}

break;

case PUZ_DOWN:

{

int nZero = SearchZero();

if( 6 == nZero || 7 == nZero || 8 == nZero )

return false;

}

break;

}


return m_nNotMove[_eVal];

}


Puz* NodeExpention( int _eVal )

{

Puz* pRt = new Puz;


pRt->m_nDeep = this->m_nDeep + 1;

pRt->m_pParant = this;


for(int i = 0; i < 9; ++i)

pRt->m_nPuz[i] = this->m_nPuz[i];


int nReversal;

switch( _eVal )

{

case PUZ_LEFT:

{

nReversal = PUZ_RIGHT;

break;

}

case PUZ_UP:

{

nReversal = PUZ_DOWN;

break;

}

case PUZ_RIGHT:

{

nReversal = PUZ_LEFT;

break;

}

case PUZ_DOWN:

{

nReversal = PUZ_UP;

break;

}

default:

CCLog("NodeExpention( int _eVal ) Error!");

break;

}


pRt->m_nNotMove[nReversal] = false;


int nZero = SearchZero();


switch( _eVal )

{

case PUZ_LEFT:

{

pRt->SwapPuz(nZero, nZero - 1);

break;

}

case PUZ_UP:

{

pRt->SwapPuz(nZero, nZero - 3);

break;

}

case PUZ_RIGHT:

{

pRt->SwapPuz(nZero, nZero + 1);

break;

}

case PUZ_DOWN:

{

pRt->SwapPuz(nZero, nZero + 3);

break;

}

}


return pRt;

}


};




void main()
{
deque<Puz*> OpenNode;
queue<Puz*> CloseNode;

Puz* InitState = new Puz;
InitState->m_nPuz[0] = 2;
InitState->m_nPuz[1] = 8;
InitState->m_nPuz[2] = 3;
InitState->m_nPuz[3] = 1;
InitState->m_nPuz[4] = 6;
InitState->m_nPuz[5] = 4;
InitState->m_nPuz[6] = 7;
InitState->m_nPuz[7] = 0;
InitState->m_nPuz[8] = 5;

Puz* TargetState = new Puz;
TargetState->m_nPuz[0] = 1;
TargetState->m_nPuz[1] = 2;
TargetState->m_nPuz[2] = 3;
TargetState->m_nPuz[3] = 8;
TargetState->m_nPuz[4] = 0;
TargetState->m_nPuz[5] = 4;
TargetState->m_nPuz[6] = 7;
TargetState->m_nPuz[7] = 6;
TargetState->m_nPuz[8] = 5;

OpenNode.push_front(InitState);

for(;;)
{
if( 0 == OpenNode.size() )
break;

Puz* pNodeN = OpenNode.front();
OpenNode.pop_front();

CloseNode.push( pNodeN );
  
if( 5 > pNodeN->m_nDeep )
{
for(int i = Puz::PUZ_DOWN; i > -1; --i)
{
if( pNodeN->CanMove( i ) )
{
Puz* pDirectionPuz = pNodeN->NodeExpention(i);
if( TargetState->EqualPuz(pDirectionPuz) )
_asm nop // 찾음!
else
OpenNode.push_front(pDirectionPuz); // push_front 대신 push_back 하면 넓이 우선
}
}


} // if( 5 > pNodeN->m_nDeep )
} // for(;;)
}

#include <stdio.h>
#include <time.h>


void main(void) {
  time_t timer;
  struct tm *t;

  timer = time(NULL); // 현재 시각을 초 단위로 얻기

  t = localtime(&timer); // 초 단위의 시간을 분리하여 구조체에 넣기


  printf("유닉스 타임 (Unix Time): %d 초\n\n", timer); // 1970년 1월 1일 0시 0분 0초부터 시작하여 현재까지의 초

  printf("현재 년: %d\n",   t->tm_year + 1900);
  printf("현재 월: %d\n",   t->tm_mon + 1);
  printf("현재 일: %d\n\n", t->tm_mday);

  printf("현재 시: %d\n",   t->tm_hour);
  printf("현재 분: %d\n",   t->tm_min);
  printf("현재 초: %d\n\n", t->tm_sec);

  printf("현재 요일: %d\n", t->tm_wday); // 일요일=0, 월요일=1, 화요일=2, 수요일=3, 목요일=4, 금요일=5, 토요일=6
  printf("올해 몇 번째 날: %d\n", t->tm_yday); // 1월 1일은 0, 1월 2일은 1
  printf("서머타임 적용 여부: %d\n", t->tm_isdst); // 0 이면 서머타임 없음

}


다음과 같은 .reg파일을 만들어 레지스트리에 등록하면 .svn폴더를 지워주는 메뉴가 우클릭 팝업에 추가됨.


Windows Registry Editor Version 5.00 


[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]

@="Delete SVN Folders" 


[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]

@="cmd.exe /c \"TITLE Removing SVN Folders in %1 && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""


+ Recent posts