1
2
3
4
5
6
7
8
9
10
11
12
13
14
// BOM 추출하기
 
System.IO.FileStream fs = System.IO.File.OpenRead(xmlFilePath);
byte[] byteOrderMark = new byte[3];
fs.Read(byteOrderMark, 03);
 
if (byteOrderMark[0== 0xEF && byteOrderMark[1== 0xBB && byteOrderMark[2== 0xBF)
{
    // utf-8
}
else if (byteOrderMark[0== 0xFF && byteOrderMark[0== 0xFE)
{
    // utf-16
}
cs


'Languages > C#' 카테고리의 다른 글

[C#] Internal Property 접근하기  (0) 2016.03.23
[C#] InputBox 만들기  (0) 2014.01.21



1
2
3
4
5
6
7
8
9
10
11
12
catch (System.Xml.XmlException e)
{
    // Exception을 처리하려는데 Internal Property 로 접근이 필요한 상황이 되었다.
    // Internal Property : ResString
 
    // Reflection 옵션을 이용하여 Internal Property 의 접근을 요청한다.
    var t = e.GetType().GetProperty("ResString"System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
 
    // 저장된 값을 요청한다.
    string resString = (string)t.GetValue(e, null); 
}
 
cs


'Languages > C#' 카테고리의 다른 글

[C#] BOM 확인 (FileStream)  (0) 2016.03.23
[C#] InputBox 만들기  (0) 2014.01.21

기본적으로 괄호 () 는 IF문 또는 FOR문을 사용할 때 C 언어에서의 중괄호 {} 와 동일한 형태로 사용한다.

하지만 괄호 () 를 C언어 사용하듯이 사용하면 에러를 만나게 된다.


1
2
3
4
5
6
7
8
9
10
11
 
:: 정상 코드
IF "%ERRORLEVEL%" == 0  ( 
    echo 0이면 true라는 소리이다.
)
 
::잘못된 코드
IF "%ERRORLEVEL%" == 0  ( 
    echo 0이면 ( true )라는 소리이다.
)
 


잘못된 코드에서 괄호를 사용했는데 ) 괄호를 만나면 IF문이 닫힙니다로 해석되어 에러를 뿜어낸다.

[ 에러은(는) 예상되지 않았습니다. ]


echo는 C언어에서 std::cout, std::printf와 유사한데 여기에서 어떤 문장을 집어 넣어도 "" 큰 따옴표가 방어 역할을 수행한다. 하지만 echo는 그렇지 못하므로 주의하여 사용해야 한다.

'Languages > DOS SHELL' 카테고리의 다른 글

[DOS SHELL] for 문  (0) 2015.09.21
[DOS SHELL] IF 문  (0) 2015.09.21
[DOS SHELL] goto 와 call의 차이점  (0) 2015.09.21
[DOS SHELL] Variable 선언 및 사용  (0) 2015.09.21


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
:: 문장을 파싱할 때 사용하는 방법
:: tokens는 몇번째 내용을 가져올 것인가를 지정하는 숫자이다. (1부터 시작)
:: delims는 어떤 기준으로 문장을 분리할 것인지에 대한 기준이다.
 
set sentence= aaa-bbb-ccc-ddd
FOR /F "tokens=2 delims=-" %%i in ("%sentence%") do echo token = %%i
 
 
 
:: 파일을 파싱할 때 사용하는 방법
:: usebackq는 FileName을 ( ' )작은 따옴표로 감싸면 문장으로 인식하고
:: ( " )큰 따옴표로 감싸면 파일로 인식하기 위한 옵션이다.
 
FOR /F "usebackq tokens=2 delims=-" %%i in ('%SentenceName%') do echo token = %%i
 
FOR /F "usebackq tokens=2 delims=-" %%i in ("%FileName%") do echo token = %%i
 
 
 
:: tokens를 여러 개 만들고자 할 때
:: delims로 나열된 파싱 단어들의 숫자를 지정해주면 i, j, k, l에 순서대로 전달된다.
 
set sentence= aaa-bbb-ccc-ddd
FOR /F "tokens=1,2,3,4 delims=-" %%i in ("%sentence%") do echo token = %%i, %%j, %%k, %%l
cs


for문을 사용할 때는 문장과 파일을 명확히 구분할 필요가 있다.
자세한 사용법은 CMD 실행하고 for /?로 살펴보기.


'Languages > DOS SHELL' 카테고리의 다른 글

[DOS SHELL] 괄호() 사용시 주의 사항  (0) 2015.10.21
[DOS SHELL] IF 문  (0) 2015.09.21
[DOS SHELL] goto 와 call의 차이점  (0) 2015.09.21
[DOS SHELL] Variable 선언 및 사용  (0) 2015.09.21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
IF "%ERRORLEVEL%" == 0  ( 
    echo 0이면 true라는 소리이다.
)
IF "%ERRORLEVEL%" NEQ 0  ( 
    echo 0이 아니면 true라는 소리이다.
)
 
set name=FoxLime
IF "%name%" == "Foxlime" (
    echo 대소문자 구분하여 문자열을 비교한다.
)
IF  /i "%name%" == "Foxlime" (
    echo 대소문자 구분 없이 문자열을 비교한다.
)
 
IF "%rootPath%" == "C:\" (
    echo C:\ true.
) ELSE IF "%rootPath%" == "D:\" (
    echo D:\ true.
)
 
 
IF %UserLevel% == 1 IF %Character% > 2 (
    echo IF문에서 &&(and)를 표현하는 식이다.  
)
 
SET IsBool=false
IF %UserLevel% == 1 SET IsBool=true
IF %Character% > 2 SET IsBool=true
IF /i "IsBool" == "true" (
    echo IF문을 ||(or)를 표현하는 식이다.
)
 
cs


'Languages > DOS SHELL' 카테고리의 다른 글

[DOS SHELL] 괄호() 사용시 주의 사항  (0) 2015.10.21
[DOS SHELL] for 문  (0) 2015.09.21
[DOS SHELL] goto 와 call의 차이점  (0) 2015.09.21
[DOS SHELL] Variable 선언 및 사용  (0) 2015.09.21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@echo off
 
:: call과 goto는 실행하는 동작이 다르다.
:: call은 :Test를 현재 위치로 불러와 처리하고 다음 라인 처리를 진행한다.
:: goto는 :Test 위치로 이동하여 처리한다.
 
call :Test
goto :Test
 
exit /b 0
 
:Test
echo you called Test
exit /b 0
cs



'Languages > DOS SHELL' 카테고리의 다른 글

[DOS SHELL] 괄호() 사용시 주의 사항  (0) 2015.10.21
[DOS SHELL] for 문  (0) 2015.09.21
[DOS SHELL] IF 문  (0) 2015.09.21
[DOS SHELL] Variable 선언 및 사용  (0) 2015.09.21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SET CurrentPath=%CD%
 
:: 0의 위치부터 시작하여 3글자를 잘라 저장한다.
SET RootPath=%CD:0,3%
 
:: parameter
SET param0=%~0
SET param1=%~1
 
:: save file about paths
(
echo CurrentPath=%CurrentPath%
echo RootPath=%RootPath%
)>"path.dat"
 
 
cs


변수는 SET으로 선언되며 Value를 사용하려면 %로 감싸야 한다.


'Languages > DOS SHELL' 카테고리의 다른 글

[DOS SHELL] 괄호() 사용시 주의 사항  (0) 2015.10.21
[DOS SHELL] for 문  (0) 2015.09.21
[DOS SHELL] IF 문  (0) 2015.09.21
[DOS SHELL] goto 와 call의 차이점  (0) 2015.09.21

게임 아이템이 붙은 옵션 또는 속성 값을 bool로 사용하면 된다가 보통의 생각이다.

bool을 sizeof로 측정하면 1Byte = 8bit 값이 나오는데 필요한건 1bit를 표현하기 위해 사용하고 있는 값은 1Byte인것이다. 7bit는 낭비로 보이게 마련이다. 이와 같은 경우 선배님들의 해결법은 바로 비트 연산을 이용하는 것이다.


예를 들어 "NPC에게 판매불가, 버리기 불가, 거래 불가" 등등의 속성들 설정할 때 사용한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
typedef unsigned int UINT;
 
// 시프트 연산을 이용하여 해당하는 자리에 비트를 넣어준다.
enum ITEM_ATTRIBUTE
{
    SELL_SHOP    = 1 << 0, // 상점 판매 유무
    THROW_OUT    = 1 << 1, // 버리기 유무
    ITEM_ATTRIBUTE_MAX    = 1 << 32,
};
 
int main()
{
    UINT itemAttr = SELL_SHOP;
    std::cout << static_cast<UINT>(itemAttr & SELL_SHOP) << std::endl;
    std::cout << static_cast<UINT>(itemAttr & THROW_OUT) << std::endl;
 
    UINT itemAttr = SELL_SHOP | THROW_OUT;
    std::cout << static_cast<UINT>(itemAttr & SELL_SHOP) << std::endl;
    std::cout << static_cast<UINT>(itemAttr & THROW_OUT) << std::endl;
    return 0;
}
cs

(itemAttr & SELL_SHOP)으로 확인하면 해당 비트가 1의 상태면 0보다 큰 숫자를 반환하고 

비트가 0의 상태면 0을 반환한다.

원문 링크 : http://msdn.microsoft.com/ko-kr/library/yakksftt.aspx


문자열을 정수로 변환합니다. 이러한 기능의 더 안전한 버전을 사용할 수 있습니다. _itoa_s, _i64toa_s, _ui64toa_s, _itow_s, _i64tow_s, _ui64tow_s를 참조하십시오.

char *_itoa(
   int value,
   char *str,
   int radix 
);
char *_i64toa(
   __int64 value,
   char *str,
   int radix 
);
char * _ui64toa(
   unsigned _int64 value,
   char *str,
   int radix 
);
wchar_t * _itow(
   int value,
   wchar_t *str,
   int radix 
);
wchar_t * _i64tow(
   __int64 value,
   wchar_t *str,
   int radix 
);
wchar_t * _ui64tow(
   unsigned __int64 value,
   wchar_t *str,
   int radix 
);
template <size_t size>
char *_itoa(
   int value,
   char (&str)[size],
   int radix 
); // C++ only
template <size_t size>
char *_i64toa(
   __int64 value,
   char (&str)[size],
   int radix 
); // C++ only
template <size_t size>
char * _ui64toa(
   unsigned _int64 value,
   char (&str)[size],
   int radix 
); // C++ only
template <size_t size>
wchar_t * _itow(
   int value,
   wchar_t (&str)[size],
   int radix 
); // C++ only
template <size_t size>
wchar_t * _i64tow(
   __int64 value,
   wchar_t (&str)[size],
   int radix 
); // C++ only
template <size_t size>
wchar_t * _ui64tow(
   unsigned __int64 value,
   wchar_t (&str)[size],
   int radix 
); // C++ only

value

변환될 수 있는 숫자

str

문자열 결과

radix

다음 value의 기본은; 범위 2–36에 있어야 합니다.

각 함수들은 str에 포인터를 반환합니다. 반환되는 오류가 없습니다.

다음 _itoa_i64toa, 및 _ui64toa 함수는 주어진 value 인수의 자리를 는 null로 끝나는 문자열로 변경하고, str에서 결과( _itoa 에 대한 최대 33, _i64toa 에 대한 65 및 _ui64toa)를 저장합니다. 만일 radix이 10 및 value 가 음수이면 저장된 문자열의 첫 문자는 빼기 기호 ( – )입니다. 다음 _itow_i64tow, 및 _ui64tow 는 각각 _itoa_i64toa, 및 _ui64toa의 와이드 문자 버전입니다.

보안 정보 보안 정보

버퍼 오버런을 방지 하기 위해 , str 버퍼가 변환된 숫자와 후행 null 문자 및 기호 문자를 저장 하기에 충분 한지 확인해야 합니다.

C++에서 이러한 함수는 보다 최신의 보안 대응 함수를 호출하는 템플릿 오버로드를 갖고 있습니다. 자세한 내용은 안전한 템플릿 오버로드을 참조하십시오.

제네릭 텍스트 라우팅 매핑

TCHAR.H 루틴

_UNICODE 및 _MBCS 정의되지 않음

_MBCS 정의됨

_UNICODE 정의됨

_itot

_itoa

_itoa

_itow

_i64tot

_i64toa

_i64toa

_i64tow

_ui64tot

_ui64toa

_ui64toa

_ui64tow

루틴

필수 헤더

_itoa

<stdlib.h>

_i64toa

<stdlib.h>

_ui64toa

<stdlib.h>

_itow

<stdlib.h>

_i64tow

<stdlib.h>

_ui64tow

<stdlib.h>

호환성에 대한 자세한 내용은 소개 단원의 호환성 부분을 참조하십시오.

// crt_itoa.c
// compile with: /W3
// This program makes use of the _itoa functions
// in various examples.

#include <string.h>
#include <stdlib.h>

int main( void )
{
   char buffer[65];
   int r;
   for( r=10; r>=2; --r )
   {
     _itoa( -1, buffer, r ); // C4996
     // Note: _itoa is deprecated; consider using _itoa_s instead
     printf( "base %d: %s (%d chars)\n", r, buffer, strnlen(buffer, _countof(buffer)) );
   }
   printf( "\n" );
   for( r=10; r>=2; --r )
   {
     _i64toa( -1L, buffer, r ); // C4996
     // Note: _i64toa is deprecated; consider using _i64toa_s
     printf( "base %d: %s (%d chars)\n", r, buffer, strnlen(buffer, _countof(buffer)) );
   }
   printf( "\n" );
   for( r=10; r>=2; --r )
   {
     _ui64toa( 0xffffffffffffffffL, buffer, r ); // C4996
     // Note: _ui64toa is deprecated; consider using _ui64toa_s
     printf( "base %d: %s (%d chars)\n", r, buffer, strnlen(buffer, _countof(buffer)) );
   }
}
기본 10:-1 (2 자)
기본 9:12068657453 (11 자)
기본 8:37777777777 (11 자)
기본 7:211301422353 (12 자)
기본 6:1550104015503 (13 자)
기본 5:32244002423140 (14 자)
기본 4:3333333333333333 (16 자)
기본 3:102002022201221111210 (21 자)
기본 2:11111111111111111111111111111111 (32 자)

기본 10:-1 (2 자)
기본 9:145808576354216723756 (21 자)
기본 8:1777777777777777777777 (22 자)
기본 7:45012021522523134134601 (23 자)
기본 6:3520522010102100444244423 (25 자)
기본 5:2214220303114400424121122430 (28 자)
기본 4:33333333333333333333333333333333 (32 자)
기본 3:11112220022122120101211020120210210211220 (41 자)
기본 2:1111111111111111111111111111111111111111111111111111111111111111 (64 자)

기본 10:18446744073709551615 (20 자)
기본 9:145808576354216723756 (21 자)
기본 8:1777777777777777777777 (22 자)
기본 7:45012021522523134134601 (23 자)
기본 6:3520522010102100444244423 (25 자)
기본 5:2214220303114400424121122430 (28 자)
기본 4:33333333333333333333333333333333 (32 자)
기본 3:11112220022122120101211020120210210211220 (41 자)
기본 2:1111111111111111111111111111111111111111111111111111111111111111 (64 자)


클래스 뷰 --> 해당 Dlg (CxxxxxxxDlg) 선택  

--> 속성 창 --> 재정의 클릭 --> PreTranslateMessage 생성


--> 처리 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
BOOL CGDStressToolDlg::PreTranslateMessage(MSG* pMsg)
{
    if(pMsg->message == WM_KEYDOWN)
    {
        switch(pMsg->wParam)
        {
        case VK_ESCAPE:
            if(AfxMessageBox(_T("툴을 종료하시겠습니까?"),MB_YESNO) == IDNO)
                return TRUE;
            break;
        case VK_RETURN:
            return TRUE;
        }
        
    }
    // TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
 
    return CDialogEx::PreTranslateMessage(pMsg);
}





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
        // InputBox 함수 구현.
        public DialogResult InputBox(string title, string promptText, ref string value)
        {
            Form form = new Form();
            Label label = new Label();
            TextBox textBox = new TextBox();
            Button buttonOk = new Button();
            Button buttonCancel = new Button();
            form.Text = title;
            label.Text = promptText;
            textBox.Text = value;
            buttonOk.Text = "OK";
            buttonCancel.Text = "Cancel";
            buttonOk.DialogResult = DialogResult.OK;
            buttonCancel.DialogResult = DialogResult.Cancel;
            label.SetBounds(9, 20, 372, 13);
            textBox.SetBounds(12, 36, 372, 20);
            buttonOk.SetBounds(228, 72, 75, 23);
            buttonCancel.SetBounds(309, 72, 75, 23);
            label.AutoSize = true;
            textBox.Anchor = textBox.Anchor | AnchorStyles.Right;
            buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
            buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
            form.ClientSize = new Size(396, 107);
            form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel });
            form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height);
            form.FormBorderStyle = FormBorderStyle.FixedDialog;
            form.StartPosition = FormStartPosition.CenterScreen;
            form.MinimizeBox = false;
            form.MaximizeBox = false;
            form.AcceptButton = buttonOk;
            form.CancelButton = buttonCancel;
            DialogResult dialogResult = form.ShowDialog();
            value = textBox.Text;
            return dialogResult;
        }
 
        private void ListView1DoubleClick(object sender, EventArgs e)
        {
            // InputBox 호출부 구현.
            string value = "0";
            if (this.InputBox("Enter values""Value :"ref value) == DialogResult.OK)
            {
                MessageBox.Show(value);
            }
        }


'Languages > C#' 카테고리의 다른 글

[C#] BOM 확인 (FileStream)  (0) 2016.03.23
[C#] Internal Property 접근하기  (0) 2016.03.23

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream> 
#include <map> 
#include <vector> 
 
using namespace std; 
 
int main() 
    map<intint>    mapTest; 
    mapTest.insert( pair< int,int >( 1,0 ) ); 
    mapTest.insert( pair< int,int >( 2,0 ) ); 
    mapTest.insert( pair< int,int >( 3,0 ) ); 
    mapTest.insert( pair< int,int >( 4,0 ) ); 
    mapTest.insert( pair< int,int >( 5,0 ) ); 
 
    vector<map<intint>> vmVectorTest; 
    vmVectorTest.push_back(mapTest); 
 
    vector<map<intint>>::iterator vitr; 
    vitr = vmVectorTest.begin(); 
 
    map<intint>::iterator mapitr; 
    mapitr = vitr->begin(); 
 
    do 
    { 
        cout << mapitr->first << " , " << mapitr->second << endl; 
 
        ++mapitr; 
    }while(mapitr != vitr->end()); 
 
    return 0; 
}

vector에 map을 담을 생각을 한 이유는 자유롭게 변형되는 맵 배열을 생각하게 되었다.

현재로써는 사용량이 빈번하지 않을 것으로 예상되지만 유용하게 사용할 일이 있을거란 생각에 테스트 코드를 작성하게 되었다.

 

위의 코드를 보면 vector에 map을 담았지만 다른 각도로 보면 다양한 STL 컨네이너들이 각자 상황에 맞게 포함 될 수 있음을

의미한다. 이 의미는 자유롭게 사용하여 필요할 때 꺼내 사용하면 된다.

 

퍼포먼스를 먼저 생각하는 분이라면 하나의 연산이라도 하지 않아야 한다는 가정이 붙겠지만 일단 요즘 시대의 컴퓨터는

이 정도의 내용을 허용하므로 자유롭게 사용하는게 더 이익일 수있다는 사실을 생각하면 좋다.

 

고정형의 배열을 사용하거나 매번 new를 이용한 배열 생성의 형태라면 vector가 더 효과적이므로 한번 정도 생각을 해볼 수 있는

문장이다.


프로퍼티스 (성질, 특징) 창을 열어 아래 경로의 항목을 True로 변경 시켜준다.

Properties  ->  Appearance  ->  Abolute Align  -> True

 

 변경이 완료되면 Properties 창 하단에 아래와 같이 pos설정할 수 있는 항목이 생긴다.

 

Center -> False 상태에서는 X, Y Position을 설정할 수 있다. True 상태라면 중앙에 위치하게 된다.

0, 0 좌표는 화면 왼쪽 상단의 기본 좌표이다. 좌표를 설정하고 싶다면 픽셀단위 값을 확인 후 입력하면 된다.

 

 

▷ 포인터의 개념 정리

  - 주소를 가르킨다.

  - 메모리는 주소를 가지고 있고 주소를 통해 메모리 접근이 가능하다. 이 주소를 저장하고 있는게 바로 포인터이다.

  - 거대한 데이터(struct와 같은)를 전달 인자(매개 변수)로 전달하는 것은 메모리 낭비이므로 포인터를 전달하면

     거대한 데이터의 위치(주소)만 전달하면 되므로 효과적으로 사용할 수 있다.

 

 ▷ 흔히 책에 있는 예제

    int  nCount = 100;

    int *pCnt;

    pCnt = &nCount;

 

▷ 경험에 의한 예제

   struct stUserBaseInfo{

        int  nUserIdx;

        char[50] nCharName;

        int nCharIdx;

  }; 

   // 위의 이런 구조체가 있다는 가정이라면 거대한 데이터가 된다.

   stUserBaseInfo  meInfo;

   stUserBaseInfo  *pMeInfo;

   pMeInfo = (* stUserBaseInfo) meInfo;

                 ------------------

                     └> "데이터형 변환자"라 부른다.

  // 즉 구조체를 가지는 거대한 데이터나 클래스를 통째로 넘겨 처리가 필요하다면 포인터로 주소만 넘기는

      방법이 보다 효과적이라는 사실이다.

 

▷ 또 다른 예제

   int*  p_info;

  char*  p_chInfo;

  //다른 데이터형일 경우 주소를 가르키려면?

 

  p_chInfo = (char *) p_info;

                 -------

                    └> "데이터형 변환자"를 이용하여 다른 데이터형일 경우 주소를 가르킨다.

 

  p_info가 가르키는 주소  :  p_info

  p_chInfo가 가르키는 주소 : (int *) p_chInfo

 

 

 

▷ 포인터와 const 

  int  gorp = 16;

  int  chips = 12;

 

                      ┌> 다른 변수를 지시할 수 있다. ( p_snack = chips; )

                 ----------

  const  int  *  p_snack = &gorp;

  --------

      └> 지시하는 값은 변경할 수 없다. ( *p_snack = 20; )

 

 

                      ┌> 지시하는 변수는 변경 불가능!!

              -------------

    int  *  const  p_snack = &gorp;

   -----

      └> 값 변경 가능.

 

▷ 더블 포인터

   - 다차원 배열을 접근하는데 사용된다.

   - 책에 나와 있는대로 포인터는 더블 포인터로 받는다라는 부분도 맞겠지만 엄밀히 말하자면 더블 포인터는

     다차원 배열을 접근하는데 유용하게 사용된다는 점이다.

  char*  double_arr[] = {"abc", "def"};

  char** ptr_arr = double_arr;

 

  cout << ptr_arr[0] << endl;

 

출력 결과

abc

 

▷ 다차원 배열을 사용하지 않는 경우

   char*  double_arr[] = {"abc", "def"};

   char*  ptr_arr  =  double_arr[0];

 

   cout << "ptr_arr  :  "  << ptr_arr << endl;

   // 다차원 배열 접근이 아니라면 이렇게 접근이 가능하다.

 

 

'Languages > cplusplus' 카테고리의 다른 글

[STL] Vector + Map 연습 코드  (0) 2013.07.19
[MFC] Dialog Box 위치 변경  (0) 2012.11.26
지수표기 / enum / new 메모리 할당  (0) 2012.10.12
데이터 형변환  (0) 2012.09.26
32bit 자료형 / 64bit 자료형의 크기 정리  (0) 2012.09.26

 

 지수 표기

  +5.37E+16

 

0.000E+N 형식은 소수점을 오른쪽으로 N자리만큼 이동하는 것이고

0.000E-N은 소수점을 왼쪽으로 N자리만큼 이동하는 것이다.

 

 

 → enum

                 ┌>     열거형의 변수 선언할 때 사용됨.  

  enum  spectrum  { red, orange, yellow, green, blue };

                             ------------------------------

                                                  └> 열거자들

 

Ex)  spectrum  band;

       └> spectrum형 열거형 변수는 이미 선언된 값만 대입 가능하다.

             선언 후 값을 대입하지 않으면 Error를 발생한다.

       band = yellow;    // true

       band = 100;        // false   (열거자가 아니므로 실패)

 

→ 열거자가 아닌 값을 대입하고 싶다면?

       band = spectrum(100);

 

 

 → new 메모리 할당

 [typename] * [pointer_name] = new [typename];

 

Ex)  int  *pn = new  int;

                    --------

                         └> int형 데이터를 저장할 새로운 메모리가 필요하다고 프로그램에 알린다.(heap memory)

 

* 컴퓨터의 메모리가 부족하여 new의 메모리 할당 요청을 허용할 수 없는 경우 new는 0값을 리턴한다.

                                                                                                          ----------

                                                                                                        NULL pointer

 

        delete pn;    //메모리 해제 (해제하지 않으면 메모리 누수 발생)

 

* new를 사용하여 메모리를 할당 후 메모리 해제가 필요한 경우 delete를 사용한다.

  메모리 해제가 필요한 경우는 사용할 데이터가 필요가 없는 경우일 뿐이다.

 

 

  정적 바인딩 (static binding)

     사용이 되든 안되는 항상 메모리를 차지하는 방식 (Ex : 배열)

 

 → 동적 바인딩 (dynamic binding)

     new를 사용하면 배열을 실행 시간에 생성할 수 있고 필요 없으면 생성하지 않을 수 있다.

     또는 프로그래미을 실행하는 동안에 배열의 크기를 결정할 수 있다.

 

 int  *psome = new  int[10];        // new를 사용한 동적 배열 생성 예제

 delete[] psome;  //동적 배열 해제.

 

 

char * itoa (int value, char * str, int base);

숫자를 문자열로 형변환이 필요한 경우 사용되는 함수이다.

 

첫번째 전달인자 : 변환할 변수

두번째 전달인자 : 저장할 곳

세번째 전달인자 : 변활할 진수 (2진수, 8진수, 10진수 등등)

 

char buf[10];

int a = 11111;

itoa( a, buf, 10);

=====================================================================

숫자를 문자열로 변환

int a = 10;

CString str;

str.format ("%02d", a);



Date(날짜)를 문자열로 바꾸어 전송이 필요할 때 (숫자를 문자열로 변환하는 것도 동일하다)

void CRDB::TMDATE(CString *s, time_t tmv)
{
     tm *ptm;
     ptm=localtime(&tmv);
     s->Format("%d-%02d-%02d",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday);
}

void CRDB::TMTIME(CString *s, time_t tmv)

     tm *ptm;
     ptm=localtime(&tmv);
     s->Format("%02d:%02d:%02d",ptm->tm_hour,ptm->tm_min,ptm->tm_sec);
}

 

문제가 되는 코드들에 대해 예제로 정리된 사이트

http://wiki.kldp.org/wiki.php/32bitCodeTo64bit

 

개발할 때 이해를 돕는 사이트

http://blog.naver.com/PostView.nhn?blogId=kkpa1002&logNo=20106022381

http://rusy.tistory.com/entry/32%EB%B9%84%ED%8A%B8-vs-64%EB%B9%84%ED%8A%B8-WIN32-vs-WIN64

 

자료형 

32 bit OS

64bit OS 

 int

 32 bit (4 Byte)

 32 bit

 short

 16 bit

 16 bit

 long

 32 bit

 64 bit

 longlong

 64 bit

 64 bit

 pointer (*)

 32 bit

 64 bit

 long double

 12 bytes

 16 bytes (128 bit)

 size_t , ssize_t

 32 bit

 64 bit

 typedef

 

 

 

#include <stdio.h>
#include <stdlib.h> #include <limits.h>

int main(void)
{

        printf("### 1 Byte = 8 bit ###\n");
        printf("int : %d byte\n",sizeof(int));
        printf("unsigned int : %d byte\n",sizeof(unsigned int));
        printf("long int : %d byte\n",sizeof(long int));
        printf("unsigned long int : %d byte\n",sizeof(unsigned long int));
        printf("long long int : %d byte\n",sizeof(long long int));
        printf("float : %d byte\n",sizeof(float));
        printf("double : %d byte\n",sizeof(double));
        printf("long double : %d byte\n",sizeof(long double));
        printf("(void *) : %d byte\n",sizeof(void *));
        printf("\n");
        printf("INT_MAX = %d\n", INT_MAX);
        printf("UINT_MAX = %ud\n", UINT_MAX);
        printf("LONG_MAX = %ld\n", LONG_MAX);
        printf("ULONG_MAX = %lud\n", ULONG_MAX);

        return 0;

}

아래는 64bit에서의 결과의 예제이다.

### 1 Byte = 8 bit ###
int : 4 byte
unsigned int : 4 byte
long int : 8 byte
unsigned long int : 8 byte
long long int : 8 byte
float : 4 byte
double : 8 byte
long double : 16 byte
(void *) : 8 byte

INT_MAX = 2147483647
UINT_MAX = 4294967295d
LONG_MAX = 9223372036854775807
ULONG_MAX = 18446744073709551615d

몇 가지 유의사항

  • 64bit에서는 포인터의 크기와 int의 크기가 다르다. sizeof(void *) != sizeof(int).
  • 포인터의 크기가 64bit이기 때문에 그 메모리 주소 연산은 32bit의 환경과 다르게 된다.
  • 64bit에서 long 형태의 값을 int 형태로 cast할 때 주의해야 한다. 64bit에서는 sizeof(long)

!= sizeof(int). 그러나 32bit 환경에서는 sizeof(int) == sizeof(long) = 32bit = 4byte.

  • 64bit에서 long 형태의 값을 double으로 cast할 때는 정확도의 손실이 생길 수 있다. significant

figure의 갯수가 long 형태와 double 형태가 다르다는 것을 숙지해야 한다.

  • Fortran에서 integer와 real의 기본 크기는 64bit에서도 여전히 32bit = 4byte이므로, 64bit

integer를 쓰기 위해서는, kind를 이용하거나 아니면 INTEGER*8를 명시해야 한다.

 

  1 #include <iostream>
  2 #include <vector>
  3 #include <time.h>
  4 using namespace std;
  5 
  6 
  7 int main()
  8 {
  9 	// 랜덤 돌릴 범위의 모든 숫자를 저장한다.
 10 	vector<int> LottoNum;
 11 	for (int i = 0; i < 50; ++i)
 12 		LottoNum.push_back((i+1));
 13 
 14 	vector<int> ResultLottoNum;  // 램덤 후 결과값 담을 벡터
 15 	int NumRand = 0;
 16 
 17 	srand((unsigned)time(0));
 18 
 19 	for (int i = 0; i < 25; ++i)
 20 	{
 21 		vector<int>::iterator vcItr;
 22 
 23 		int SelectRandNum = 0;
 24 		SelectRandNum = rand()%LottoNum.size();  //랜덤
 25 
 26 		vcItr = LottoNum.begin() + SelectRandNum; // iterator에 램덤 위치 값 가르키도록 지정.
 27 
 28 		NumRand = *vcItr;   //값을 저장.
 29 		cout << NumRand << " / ";
 30 
 31 		if ((i+1)%5 == 0)
 32 			cout << endl;
 33 		ResultLottoNum.push_back(NumRand);  //최종 결과값 저장 벡터에 데이터 넣기.
 34 
 35 		LottoNum.erase(vcItr);     // 중복되지 않도록 삭제 처리.
 36 	}
 37 	return 0;
 38 }
 39 
 40 


 

==========================================================

OnInitDialog() 함수 자동 추가 방법

==========================================================

Dialog Box 클래스 추가 후 헤더 파일을 열고 Properties 창에 보면

 

여기에 OnInitDialog 부분이 있는데 추가해주면 자동으로 추가 된다.

 

※ 메뉴에서 View -> Class View를 이용하는 방법도 있으므로 참고.

 

 

==========================================================

모든게 귀찮아 수동 추가 하고 싶다면 아래의 내용을 참고

==========================================================

Dialog Box를 추가 후 클래스를 생성하게 된다. 그 생성된 헤더파일(.h)에 OnInitDialog() 함수를 생성해준다.

OnInitDialog()함수는 기본적으로 CDialog 클래스에 virtual로 존재한다.

 

1. 헤더파일(.h) 추가 내용

protected:

virtual BOOL OnInitDialog();        //생성한 클래스 헤더파일에 추가한다.

 

2. 씨피피(.cpp) 추가 내용

BOOL    classCreateName::OnDialog()

{

CDialog::OnInitDialog();

 

//TODO : Add extra initialization here

return TRUE;

}

 

모두 완료 되었으므로 초기화 해주고 싶은 내용을  [ //TODO : Add extra initialization here ] 문장 아래에 추가 한다.

대화 상자는 두 가지로 나뉜다.

  -  모달(Modal) 대화 상자

  -  모덜리스(Modeless) 대화상자

 

모달 대화 상자는 메인 흐름을 정지하고 동작하는 대화 상자이며, 모덜리스  대화 상자는 흐름을 방해하지 않고 별개로 작동하는 형태입니다.

 

1. Resource View에서 Insert Dialog를 클릭하면 Dialog Box를 생성할 수 있다.

2. 생성한 Dialog Box에서 오른쪽 버튼으로 Add Class하여 클래스를 추가해 준다.

 

3. 대화 상자를 사용하고 싶다면  클래스 이름으로 생성된 [헤더파일]을 메인 대화상자 .cpp 파일에 코드를 추가 한다.

#include "ModalDlg.h"

 

=============================================================================================

// 모달 대화 상자로 호출 하는 방법 

CModalDlg Dlg;
 INT_PTR nResult = Dlg.DoModal();

 if (nResult == IDOK) 
 {
  AfxMessageBox(_T("Clicked Button OK!"));
 }

=============================================================================================

// 모달리스 대화 상자로 호출 하는 방법

 static CModalDlg Dlg;
 if (Dlg.GetSafeHwnd() == NULL)
 {
  Dlg.Create(IDD_SUBDIG1);
 }

 Dlg.ShowWindow(SW_SHOW);

 

 

 

1. Toolbox - List Control 을 생성한다.

2. Properties - View 를 이용하여 필요한 보기 방식을 지정한다. (보통 : List 방식 사용)

3. 생성된 리스트 컨트롤에서 오른쪽 버튼을 클릭하여 [Add Variable...]을 클릭하여 변수를 만든다.

 

 

4. 데이터를 초기화 및 설정하고 싶다면 OnInitDialog() 함수에 코드를 삽입한다.

m_ctrItemList.InsertItem(0, _T("1 th Test item"));

m_ctrItemList.InsertItem(1, _T("2 th Test item"));

 

5. 컬럼 헤더를 만들어 데이터를 추가하고 싶은 경우 아래와 같이 OnInitDialog() 함수에 코드를 삽입한다.

m_ctrItemList.InsertColumn(0, _T("Count"), LVCFMT_LEFT, 150);

m_ctrItemList.InsertColumn(1, _T("Count"), LVCFMT_LEFT, 150);

m_ctrItemList.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);        //스타일을 지정하지 않으면 출력되지 않는다.

 

 m_ctrItemList.InsertItem(0, _T("1 th Test item"));            //첫번째 컬럼헤더에 값 셋팅
 m_ctrItemList.SetItemText(0, 1, _T("1 th complate"));      //두번째 컬럼헤더에 값 셋팅

  // 컬럼 헤더에 값 추가는 첫번째 컬럼이냐 두번째 컬럼이냐에 따라 다르다... 물론 두번째 컬럼헤더 값 셋팅처럼 첫번째 값 셋팅을 해주어도 무관하다.

 

 

▷ 행 전체 컬럼 선택 할 수 있도록 설정하기

    - BOOL CDialog::OnInitDialog()에 다음과 같이 내용을 추가한다.

     m_ctrCashItem.SetExtendedStyle(LVS_EX_FULLROWSELECT);

이렇게 쉬운걸 한참동안 찾아 헤매었다 ㅡㅡ;;

 

 

visual studio 2005 기준으로 테스트 되었습니다.

 

1.  Dialog Editor에서 Combo Box를 드래그 하여 생성한다.

2.  아래 그림과 같이 화살표 버튼을 누르면 리스트 표시 영역 사이즈를 조정할 수 있다.

     리스트 개수에 맞게 마우스 드래그를 이용하여 늘려 준다.

 

3. 콤보 박스 리스트 추가 및 표현(출력) 방법

    3.1  콤보 박스에 마우스를 올려 놓고 오른쪽 버튼 클릭 [Add VariAble...] 선택!

    3.2  아래와 같은 화면이 나오면 control을 생성한다.

    

 

    3.3 OnInitDialog() 함수에 초기화 하는 내용을 추가한다.

          m_comboServerList.AddString(_T("1 channel"));                   //텍스트 추가
          m_comboServerList.AddString(_T("2 channel"));

          m_comboServerList.SetCurSel(0);                                //텍스트 선택

    3.4 현재 선택된 곳이 어디인지 알고 싶다면 아래와 같이 함수 사용

         index  =  m_comboServerList.GetCurSel();        //현재 선택된 텍스트 값을 int형으로 반환

 

4.  콤보 박스 변경 시 동작 하고 싶을 때...

   - Properties 창에 보면 Control Events 를 클릭하고  동작하고 싶은 내용을 추가한다.

    - 필요한 동작 코드를 안쪽에 삽입하면 내가 원하는 동작을 취한다.

 

5. 콤보 박스 Type 설정

   - Properties 창에 보면 Type이 있다.

 

Dropdown은 Edit가 가능한 상태이다.

Drop List는 선택만 가능한 상태이다.

 

6. 콤보박스 텍스트 가져오기

  CString temp;

   this->m_comboBox.GetLBText(this->m_comboBox.GetCurSel(), temp);

   //GetCurSel()을 호출하면 현재 몇번째 지정하고 있는지에 대한 정보만 넘어온다. 주의가 필요하다.

 

  

=======================================================================================

                              콤보 박스  클래스 함수들 리스트 (펌)

=======================================================================================

▷ CComboBox::AddString - 스트링을 더함.
▷ CComboBox::CComboBox - ComboBox 오브젝트를 생성(구성).
▷ CComboBox::Clear -현재 선택을 지움.
▷ CComboBox::CompareItem - 새로운 리스트 항목의 상태적 위치를 결정.
▷ CComboBox::Copy - 현재 선택을 Copy.
▷ CComboBox::Create - CComboBox를 생성.
▷ CComboBox::Cut - 제거된 텍스트를 복사.
▷ CComboBox::DeleteItem- 항목이 Combo 박스에서 제거.
▷ CComboBox::DeleteString - 스트링을 제거.
▷ CComboBox::Dir - 리스트를 더함.
▷ CComboBox::DrawItem - 양상이 변할 때 불려짐.
▷ CComboBox::FindString - 첫 번째 스트링을 찾음.
▷ CComboBox::FindStringExact - 첫 번째 리스트 박스 스트링을 찾음.
▷ CComboBox::GetCount - 항목의 수를 회복.
▷ CComboBox::GetCurSel - 현재 선택된 항목의 색인을 찾음
▷ CComboBox::GetDroppedControlRect - 스크린 좌표를 되찾음.
▷ CComboBox::GetDroppedState - 리스트 박스가 보일지를 결정.
▷ CComboBox::GetEditSel - 시작과 끝나는 문자의 위치를 얻음.
▷ CComboBox::GetExtendedUI - 디폴트, 확장 사용자 인터페이스의 결정.
▷ CComboBox::GetItemData - 항목과 관련된 비트값을 회복.
▷ CComboBox::GetItemDataPtr - 포인터로서 관련된 비트 값을 회복.
▷ CComboBox::GetItemHeight - 리스트 항목의 높이를 회복.
▷ CComboBox::GetLBText - 리스트 박스로 부터 스트링을 얻음.
▷ CComboBox::GetLBTextLen - 스트링의 길이를 지정.
▷ CComboBox::InsertString - 스트링의 삽입.
▷ CComboBox::LimitText - 텍스트의 길이를 제한.
▷ CComboBox::MeasureItem - Combo 박스 치수를 결정하기 위해 불려짐.
▷ CComboBox::Paste - 현재 커서 위치에서 편집 제어로 삽입.
▷ CComboBox::ResetContent - 모든 항목의 제거.
▷ CComboBox::SelectString - 스트링을 선택, 복사.
▷ CComboBox::SetCurSel - 스트링을 선택.
▷ CComboBox::SetEditSel - 편집 제어에서 문자들을 선택.
▷ CComboBox::SetExtendedUI - 디폴트, 확장 사용자 인터페이스의 선택.
▷ CComboBox::SetItemData - 항목과 관련된 값을 정함.
▷ CComboBox::SetItemDataPtr - 포인터에 대한 관련된 값을 정함.
▷ CComboBox::SetItemHeight - 높이를 지정.
▷ CComboBox::ShowDropDown - 리스트 박스를 보여주거나 숨김.

 

리눅스에 설치된 MySQL 쿼리문을 이용하여 날짜, 시간을 입력하여 정수형으로 변환해주는 함수가 존재한다.

 

select  unix_timestamp('2011-05-30 12:00');

 

이 함수를 이용하면 정수 값  :  1306724400  출력된다.

 

unix_timestamp 값을 날짜, 시간으로 출력하려면 다음과 같이 진행한다.

 

  1 time_t g_itemTime = 1306724400;
  2 struct tm * localtt;
  3
  4 localtt = localtime(&g_itemTime);
  5
  6 cout << localtt->tm_year + 1900 << endl;
  7 cout << localtt->tm_mon + 1 << endl;

 

결과 값을 출력해 봤더니 제대로 나온다... ^^*

 

 

====================================================================================================

▷ 시간 변환시 주의 사항

  struct tm* stTime = localtime(&server.m_time);

  : 포인터로 서버의 시간을 바로 넘기는건 주의가 필요하다.

     왜냐하면 시간의 대한 조작을 하는 경우 시간이 꼬여 잘못된 서버 동작을 일으킬 수 있기 때문이다.

 

비트 연산자는 주로 메모리를 효율적으로 관리하거나 서버와 클라이언트 간의 전송하는 패킷을 효율적으로 주고 받아야 하는 경우 고민해볼 수 있다...

 

C/C++에서 가장 기초인 자료형에 대해 배우게 되는데... 1byte 부터 8byte까지 다양하게 사용이 가능하다...

cout << sizeof(bool); 명령으로 살펴보면 bool 역시 1byte임을 알 수 있다. 게임의 경우 장비에 대한 착용 유무를 확인 한다고 하면 대략 기존 8개 정도(머리, 상의, 하의, 신발, 장갑, 귀걸이 2개 , 목걸이 등등)로 나뉜다...

그렇다면 이 8개를 1byte씩 계산하면 대략 8byte를 사용하지만 4byte int형으로 표현도 가능하다.

우리가 비트의 대한 개념을 배웠다면 숫자 표현이 4byte는 32bit 표현 가능하다.

int형 4byte = 32 bit이므로 비트 표현은 32개 표현 가능..

 

// Bit 단위로 대입
unsigned int  EquipItem = 0;
EquipItem |= 1;
EquipItem |= 4;

// 아이템 존재 유무 확인
for (int i=0; i<32; ++i)
{
	if (EquipItem & (1 << i))
		cout << i << endl;
}


===============================================================================================

만약 bool 자료형을 배열로 만들어 사용한다면이라는 생각을 해보게 되었다..

bool EquipItem[8] = {false, };

cout << sizeof(EquipItem) << endl;

사이즈가 궁금해서 일단 출력해 봤더니 8byte가 나온다...

 

약간의 계산적인 부분이 비트 연산할 때 복잡할거라 생각했지만 이해하고 나니 훨씬 간편하다...

 

어떤 상황이냐에 따라 코드가 달라질 것이다... 기초는 역시 중요한 것 같다...

기초를 튼튼히 하면 할수록 많은 것들이 보인다...

경력 3년이 될 때까지는 계속 머리속에 기초는 외워야겠다는 생각을 해본다...

 

 


visual studio 2005를 사용하던 도중 source safe로 여러명이 작업하는 경우 축적된 변경 코드들이 내 컴퓨터로
유입되면서 선언과 정의 찾아가기가 틀리는 경우가 발생되었다...

visual studio 2005를 종료 후
해당 프로젝트 폴더에 존재하는 0000.ncb 파일을 삭제 후 다시 실행하면 정상적으로 돌아온다...


원리는 다음과 같다... 모든 파일 정보들을 다시 로드하므로 현상 해결이 가능하다...



나라 이름 숫자 alpha-3 alpha-2
가나 288 GHA GH
가봉 266 GAB GA
가이아나 328 GUY GY
감비아 270 GMB GM
과들루프 312 GLP GP
과테말라 320 GTM GT
316 GUM GU
그레나다 308 GRD GD
그루지야 268 GEO GE
그리스 300 GRC GR
그린란드 304 GRL GL
기니 324 GIN GN
기니비사우 624 GNB GW
나미비아 516 NAM NA
나우루 520 NRU NR
나이지리아 566 NGA NG
남극 010 ATA AQ
남아프리카 공화국 710 ZAF ZA
네덜란드 528 NLD NL
네덜란드령 안틸레스 530 ANT AN
네팔 524 NPL NP
노르웨이 578 NOR NO
노퍽 섬 574 NFK NF
누벨칼레도니 540 NCL NC
뉴질랜드 554 NZL NZ
니우에 570 NIU NU
니제르 562 NER NE
니카라과 558 NIC NI
대한민국 410 KOR KR
덴마크 208 DNK DK
도미니카 212 DMA DM
도미니카 공화국 214 DOM DO
독일 276 DEU DE
동티모르 626 TLS TL
라오스 418 LAO LA
라이베리아 430 LBR LR
라트비아 428 LVA LV
러시아 643 RUS RU
레바논 422 LBN LB
레소토 426 LSO LS
레위니옹 638 REU RE
루마니아 642 ROU RO
룩셈부르크 442 LUX LU
르완다 646 RWA RW
리비아 434 LBY LY
리투아니아 440 LTU LT
리히텐슈타인 438 LIE LI
마다가스카르 450 MDG MG
마르티니크 474 MTQ MQ
마셜 제도 584 MHL MH
마요트 175 MYT YT
마카오 446 MAC MO
마케도니아 공화국 807 MKD MK
말라위 454 MWI MW
말레이시아 458 MYS MY
말리 466 MLI ML
멕시코 484 MEX MX
모나코 492 MCO MC
모로코 504 MAR MA
모리셔스 480 MUS MU
모리타니 478 MRT MR
모잠비크 508 MOZ MZ
몬트세랫 500 MSR MS
몰도바 498 MDA MD
몰디브 462 MDV MV
몰타 470 MLT MT
몽골 496 MNG MN
미국 840 USA US
미국령 군소 제도 581 UMI UM
미국령 버진아일랜드 850 VIR VI
미얀마 104 MMR MM
미크로네시아 연방 583 FSM FM
바누아투 548 VUT VU
바레인 048 BHR BH
바베이도스 052 BRB BB
바티칸 시국 336 VAT VA
바하마 044 BHS BS
방글라데시 050 BGD BD
버뮤다 060 BMU BM
베냉 204 BEN BJ
베네수엘라 862 VEN VE
베트남 704 VNM VN
벨기에 056 BEL BE
벨라루스 112 BLR BY
벨리즈 084 BLZ BZ
보스니아 헤르체고비나 070 BIH BA
보우벳 섬 074 BVT BV
보츠와나 072 BWA BW
볼리비아 068 BOL BO
부룬디 108 BDI BI
부르키나파소 854 BFA BF
부탄 064 BTN BT
북마리아나 제도 580 MNP MP
불가리아 100 BGR BG
브라질 076 BRA BR
브루나이 096 BRN BN
사모아 882 WSM WS
사우디아라비아 682 SAU SA
사우스조지아 사우스샌드위치 제도 239 SGS GS
산마리노 674 SMR SM
상투메 프린시페 678 STP ST
생피에르 미클롱 666 SPM PM
서사하라 732 ESH EH
세네갈 686 SEN SN
세르비아 몬테네그로 891 SCG CS
세이셸 690 SYC SC
세인트루시아 662 LCA LC
세인트빈센트 그레나딘 670 VCT VC
세인트키츠 네비스 659 KNA KN
세인트헬레나 섬 654 SHN SH
소말리아 706 SOM SO
솔로몬 제도 090 SLB SB
수단 736 SDN SD
수리남 740 SUR SR
스리랑카 144 LKA LK
스발바르 얀마옌 744 SJM SJ
스와질란드 748 SWZ SZ
스웨덴 752 SWE SE
스위스 756 CHE CH
슬로바키아 703 SVK SK
슬로베니아 705 SVN SI
시리아 760 SYR SY
시에라리온 694 SLE SL
싱가포르 702 SGP SG
아랍에미리트 784 ARE AE
아루바 533 ABW AW
아르메니아 051 ARM AM
아르헨티나 032 ARG AR
아메리칸사모아 016 ASM AS
아이슬란드 352 ISL IS
아이티 332 HTI HT
아일랜드 372 IRL IE
아제르바이잔 031 AZE AZ
아프가니스탄 004 AFG AF
안도라 020 AND AD
알바니아 008 ALB AL
알제리 012 DZA DZ
앙골라 024 AGO AO
앤티가 바부다 028 ATG AG
앵귈라 660 AIA AI
에리트레아 232 ERI ER
에스토니아 233 EST EE
에스파냐 724 ESP ES
에콰도르 218 ECU EC
에티오피아 231 ETH ET
엘살바도르 222 SLV SV
영국 826 GBR GB
영국령 버진아일랜드 092 VGB VG
영국령 인도양 식민지 086 IOT IO
예멘 887 YEM YE
오만 512 OMN OM
오스트레일리아 036 AUS AU
오스트리아 040 AUT AT
온두라스 340 HND HN
올란드 제도 248 ALA AX
요르단 400 JOR JO
우간다 800 UGA UG
우루과이 858 URY UY
우즈베키스탄 860 UZB UZ
우크라이나 804 UKR UA
월리스 푸투나 876 WLF WF
이라크 368 IRQ IQ
이란 364 IRN IR
이스라엘 376 ISR IL
이집트 818 EGY EG
이탈리아 380 ITA IT
인도네시아 360 IDN ID
인도 356 IND IN
일본 392 JPN JP
자메이카 388 JAM JM
잠비아 894 ZMB ZM
적도 기니 226 GNQ GQ
조선민주주의인민공화국 408 PRK KP
중앙아프리카 공화국 140 CAF CF
중화민국 158 TWN TW
중화인민공화국 156 CHN CN
지부티 262 DJI DJ
지브롤터 292 GIB GI
짐바브웨 716 ZWE ZW
차드 148 TCD TD
체코 203 CZE CZ
칠레 152 CHL CL
카메룬 120 CMR CM
카보베르데 132 CPV CV
카자흐스탄 398 KAZ KZ
카타르 634 QAT QA
캄보디아 116 KHM KH
캐나다 124 CAN CA
케냐 404 KEN KE
케이맨 제도 136 CYM KY
코모로 174 COM KM
코스타리카 188 CRI CR
코코스 제도 166 CCK CC
코트디부아르 384 CIV CI
콜롬비아 170 COL CO
콩고 공화국 178 COG CG
콩고 민주 공화국 180 COD CD
쿠바 192 CUB CU
쿠웨이트 414 KWT KW
쿡 제도 184 COK CK
크로아티아 191 HRV HR
크리스마스 섬 162 CXR CX
키르기스스탄 417 KGZ KG
키리바시 296 KIR KI
키프로스 196 CYP CY
타이 764 THA TH
타지키스탄 762 TJK TJ
탄자니아 834 TZA TZ
터크스 케이커스 제도 796 TCA TC
터키 792 TUR TR
토고 768 TGO TG
토켈라우 제도 772 TKL TK
통가 776 TON TO
투르크메니스탄 795 TKM TM
투발루 798 TUV TV
튀니지 788 TUN TN
트리니다드 토바고 780 TTO TT
파나마 591 PAN PA
파라과이 600 PRY PY
파키스탄 586 PAK PK
파푸아 뉴기니 598 PNG PG
팔라우 585 PLW PW
팔레스타인 275 PSE PS
페로스 제도 234 FRO FO
페루 604 PER PE
포르투갈 620 PRT PT
포클랜드 제도 238 FLK FK
폴란드 616 POL PL
푸에르토리코 630 PRI PR
프랑스 250 FRA FR
프랑스령 기아나 254 GUF GF
프랑스령 남부 지역 260 ATF TF
프랑스령 폴리네시아 258 PYF PF
피지 242 FJI FJ
핀란드 246 FIN FI
필리핀 608 PHL PH
핏케언 섬 612 PCN PN
허드 맥도날드 제도 334 HMD HM
헝가리 348 HUN HU
홍콩 344 HKG      



#ifndef    TEST_H_
#define   TEST_H_

-   내용 생략  -

#endif

> macro wrapper방식을 이용하여 중복 include를 제거하는데 사용되는 예제 코드이다.
   이 코드는 TEST_H_ 가 define 되어 있다면 더 이상 읽지 않는다.

====================================================================================

#pragma once

  - 내용 생략 -

> 컴파일러에게 이 파일을 한번만 읽으면 되는것을 알려주는 코드이다.

====================================================================================


두 코드의 차이점은 ifndef은 비교를 지속적으로 하므로 컴파일러 속도가 늦어진다... 하지만 한번 읽으면
더 이상 읽지 않아도 된다는 pragma는 속도가 좀 빠르게 된다... 하지만 두 개의 코드는 동일한 기능을
하고 있다... 컴파일 속도가 조금 더 빠른 방법이 좋지 않을까라는 생각을 해본다...

참고 : #pragma는 표준에서 정의도니 전처리기 지시어가 맞다고 한다.

< #define을 사용하는 경우 >

1. 국가별 코드가 다르게 들어가야 하는 경우.

2. 버전에 따라 코드가 다르게 들어가야 하는 경우.

3. 솔루션(구성 관리자)에 따라 각각 다르게 빌드 되어야 하는 경우. (Ex. Debug, Release, Etc...) 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#define A_SYSTEM       //기존 코드
#define B_SYSTEM       //신규 추가 코드
 
 
#ifdef A_SYSTEM
      #ifdef B_SYSTEM
              // 신규 추가 코드
      #else
              // 기존 코드
      #endif
#endif
 
==================================================================================
 
#if defined (A_SYSTEM) || defined (B_SYSTEM)
     // 코드 또는 디파인
#endif
 
#if defined (A_SYSTEM) && defined (B_SYSTEM)
     // 코드 또는 디파인
#endif
 
==================================================================================
 
#if defined (A_SYSTEM)
     // 코드 또는 디파인
#elif defined (B_SYSTEM)
     // 코드 또는 디파인
#else
     // 코드 또는 디파인
#endif
 
cs



#define의 장점은 구분이 명확하지만 많이 포함되면 엄청난 난독형 코드가 될 가능성이 높다.

SVN을 이용하여 Revision으로 #define을 대체하는 경우도 존재 한다.


SVN은 Revision 관리가 소홀히 되는 경우 오동작 버그 발생하는 경우를 종종 봐 왔는데 오히려 관리가 소홀하다면 #define이 더 좋을 수 있다는 생각도 든다.


SVN의 시스템 구현별 Revision 관리만 잘 된다면 난독 코드가 될 가능성이 낮기 때문에 개인적으로 선호한다.





1. 자동 형변환이 다르다
   - windows에서 개발 툴로 visual studio를 사용하고 컴파일하면 에러나지 않는 코드는 아래와 같다.

      int a = a * 0.5;

   -  위의 코드를 Linux에서 컴파일하면 오류이다. 자동 형변환이 안된다....-_-;;;

      int a = (int)(a * 0.5);


2. 제공되는 함수가 다르다
   - 윈도우에서 제공하는 함수가 있고 리눅스에서 제공하는 함수가 있으므로 공통으로 사용되는 함수를 사용해야 한다.
   - 윈도우 독자 제공 유요한 함수를 사용하면 리눅스에서는 컴파일 되지 않으므로 멀티 플랫폼으로 개발할 때
     주의가 필요하다.


윈도우 환경에서 개발하고 리눅스 환경에서 구동하는 경우 신입인 나에겐 색다른 경험이기도 하지만 많은 것들을 배울 수 있어 좋다.... 부스트라는 것도 사용해보는데 컴파일할 때는 느리지만 동작에는 최적의 상태를 나타냈기에 사용할거라 예상된다... ^^* 아직 부스트에 대한 부분은 많이 몰라 찾아보고 있다... ^^

http://msdn.microsoft.com/ko-kr/library/dd409393.aspx

visual studio 2010 버전에서 지원하는 내용을 서술했는데... 이해하기 쉽게 접근한 그림이 마음에 든다...

이전에 관심을 갖고 여러 사이트들을 참고하고 봤더니 이해가 쉬워 링크를 걸어 놓았다....
UML을 이용하니 구조 파악하기도 용이하고 내가 무엇을 만들어야 할지도 머리속에 그려지니
용이하게 사용되는것 같다....

+ Recent posts