64비트와 32비트의 구분방법

한번에 송수신 가능한 데이터 크기

데이터가 메모리에서 I/O BUS를 통해 CPU로 전송되는 크기가 각 시스템 크기에따라

64비트, 32비트 로 나눌수 있다.


데이터 처리능력

위와 마찬가지로 CPU에서 한번에 처리 가능한 데이터 크기로 나눌 수 있다.

데이터 이동과 처리가 동일한 크기로 이루어져야 완벽한 시스템을 이룰 수 있다.


64비트 시스템에서 일반적으로 64비트 명령어를 사용하지만 32비트로 디자인하면 한번에 32비트 데이터 2개를 처리 할 수도 있다.


프로그래머 입장에서의 64비트 컴퓨터


32비트 → 64비트

프로그램으로 표현 할 수 있는 범위의 증가

표현할 수 잇는 메모리의 전체 크기


일반적으로 32비트 시스템에서 포인터의 크기가 32비트이고

64비트 시스템에서는 포인터의 크기가 64비트이다.

32비트 시스템이라면 메모리를 어드레싱 할 때 주소값을 2^32 만큼을 갖는데 32비트 시스템에서 4G이상의 메모리를 사용 못 하는 이유가 바로 이것이다. 

시스템이 64비트라면 표현할 수 있는 메모리의 크기가 2^64로 훨씬더 크게 사용 할 수 있다.


만약 64비트 시스템을 사용하지만 메모리가  2G라면 의미없지않은가?

이것은 가상메모리를 사용한다.




활용 가능 메모리의 확장


 
int _tmain(void)

{

TCHAR str[100];


_tscanf(_T("%s"),str);

_tprintf(_T("%s"),str);

return 0;

int _tmain(void)

{

TCHAR ch;

do

{

_tscanf(_T("%c"),&ch);

_tprintf(_T("%c"),ch);

}while(ch!="\n");


return 0;

}




















MBCS와 WBCS의 동시 지원

 WBCS 기반의 개발이 여러가지로 장점이 많지만 기존 개발 된 프로그램과의  호환성,

사용자 시스템의 유니코드 지원여부에 때문에 프로그램 개발에 이써 MBCS와 WBCS을 동시에 지원하는 프로그램을 개발 하여야 한다.


#include<windows.h>

Windosws 정의 자료형

typedef char        CHAR;

typedef wchar_t   WCHAR;

#define CONST const


typedef CHAR*              LPSTR;

typedef CONST CHAR*   LPCSTR;


typedef WCHAR*            LPWSTR;

typedef CONST WCHAR* LPCWSTR;

 

windows.h 안에는 이런 식으로 자료형이 정의되있는데 실제 개발에 있어서 꼭 이런식의 자료형을 사용하지는 않으므로 이정도만 알아두자. 


MBCS와 WBCS 동시 지원 매크로 

#ifdef UNICODE

  typedef  WCHAR     TCHAR;

  typedef  LPWSTR    LPTSTR;

  typedef  LPCWSTR  LPCTSTR;

#else 

 typedef   CHAR        TCHAR;

 typedef   LPSTR       LPTSTR;

 typedef   LPCSTR     LPCTSTR;

#endif

windows.h 보면 위와같은 매크로가 선언되어 있다.


만약  매크로 UNICODE 가 정의됬을 경우 


TCHAR arr[10];    →    WCHAR arr[10];     →    wchar_t arr[10];


매크로 UNICODE 가 정의되지 않았을 경우

 

TCHAR arr[10];    →    CHAR arr[10] ;       →    char arr[10];


이런식으로 처리가 된다.

이 매크로를 통하여 손쉽게 MBCS와 WBCS를 동시에 지원하는 프로그램을 개발 할 수있다.


#ifdef _UNICODE

     #define __T(x)   L ## x

#else

     #define __T(x)   x


#define _T(x)       __T(x)

#define _TEXT(x) __T(x)


WBCS 기반의 문자열을 선언 할 때 L"ABC" 이런식으로 정의하는것을 위한 매크로가 위의 매크로 이다. 

  #define __T(x)   L ## x  이 부분의 ## 처리자는 L과 x를 붙이라는 의미이다. 

매크로 _UNICODE 가 정의됬을 경우


_T("ABC");   __T("ABC");   L"ABC";


매크로 _UNICODE 가 정의되지 않았을 경우


_T("ABC");   __T("ABC");   "ABC";


매크로가 정의 되어있을떄를 보면 문자열이 WBCS로 치환되고

매크로가 정의 되지않았을 때 MBCS 기반으로 해석된다. 


#define _T(x)       __T(x)

#define _TEXT(x) __T(x)

이 부분은 _T(x), __T(x), _TEXT(x) 어떤걸 쓰던 상관은 없지만 주로 _T(x)를 쓴다.



예제 2-6]

#define UNICODE

#define _UNICODE


int wmain(void){


TCHAR str[]=_T("1234567");

int size=sizeof(str);

printf("string length : %d \n",size);                         실행결과

return 0;                                                               string length : 16

}

간단한 예제를 통하여 매크로를 정의했을때  TCHAR str[]=_T("1234567");부분이 유니코드 처리가 되었다는 사실을 결과값을 통하여 알 수있다.

(문자 7개에 null값포함 각각 2byte씩 이므로 문자열의 길이가 16이다.)

※유니코드에서 null값도 2byte이다. 나만 모르던 사실 일 수 있다.



MBCS와 WBCS 동시 지원 함수

#ifdef _UNICODE 
  #define _tmain      wmain 
  #define _tcslen     wcslen 
  #define _tcscat     wcscat 
  #define _tcscpy    wcscpy 
  #define _tcsncpy  wcsncpy
  #define _tcscmp   wcscmp 
  #define _tcsncmp  wcsncmp
  #define _tprintf      wprintf 
  #define _tscanf     wscanf 
  #define _fgetts      fgetws 
  #define _fputts      fputws
#else 
  #define _tmain      main 
  #define _tcslen     strlen 
  #define _tcscat     strcat 
  #define _tcscpy    strcpy 
  #define _tcsncpy  strncpy
  #define _tcscmp   strcmp 
  #define _tcsncmp  strncmp
  #define _tprintf      printf 
  #define _tscanf     scanf 
  #define _fgetts      fgets 
  #define _fputts      fputs
#endif 


많이 쓰는 MBCS와 WBCS 동시 지원하는 함수이다.




 

 

문자셋의 종류와 특징

 

SBCS(Single Byte Character Set)

문자를 1byte를 사용하여 표현 대표적인 문자셋으로 아스키코드(ASCII code)가 있다.

 

MBCS(Multi Byte Character Set)

MBCS에서 Multi는 2byte 이상을 써서 문자를 표현해서가아닌 문자종류에 따라서 다른크기의 표현방식을 사용한다 해서의 Multi 라 한다. 

 

WBCS(Wide Byte Charater Set)

SBCS보다 2배 큰 2byte를 써서 문자를 표현. 유니코드

 

우리가 흔히 사용하는 컴퓨터 시스템은 SBCS이 아니라 영문과 한글을 같이쓰는 경우가 대부분이기 때문에 MBCS를 사용한다.

MBCS의 사용은 효율적일 수 있으나  하드웨어의 발전으로 안정성을 위해 WBCS를 사용하는 것이 안정적이다.

 

예제2-1]

#include <stdio.h>
#include <string.h>

int main(void)
{
 char str[]="ABC한글";
 int size=sizeof(str);
 int len=strlen(str);

 printf("배열의 크기 : %d \n", size);              실행결과
 printf("문자열 길이 : %d \n", len);                배열의 크기:8

 return 0;                                                    문자열 길이:7
}

 

예제의 결과값을 보면 배열의 크기가 8 ,문자열의 길이가 7이라 나온다.

문자열을 보면 ABC는 영어로 각각 1byte 씩이고 한글은 각각 2byte 씩해서

7byte에 맨뒤 null 문자를 합하여 8이라는 정확한 값을 출력한다.

문자열의 길이가 7이라 나온다. 하지만 이 문자열의 길이는 5이다.

strlen()함수가 한글을 2문자로 인식을 하기때문에 이러한 문제가 발생 한다.

 

 

 예제2-2]

#include <stdio.h>

int main(void)
{
 char str[]="한글입니다";
 int i;

 for(i=0; i<5; i++)
  fputc(str[i], stdout);

 fputs("\n", stdout);

 for(i=0; i<10; i++)
  fputc(str[i], stdout);                            실행결과

 fputs("\n", stdout);                             한글
 return 0;                                             한글입니다
}

 

이번 예제를 통하여 앞선예제에서의 문제를 다시한번 볼 수 있다.

for(i=0; i<5; i++) 를 통하여 5번 루프를 시켰을때 한글 이라는 결과를 출력하고

10번 루프 시켰을때 한글입니다 이라는 출력이 나온다.

 앞선 예제 2-1,2-2 를 보면 한글이 들어갔을 때 시스템이 지원해 줄 경우 MBCS을 이용하는것보다 WBCS 기반으로 프로그래밍 하는것이 안정적이다.

 

WBCS 기반의 프로그래밍

WBCS를 위한 두가지

첫째: char를 대신 wchar_t

둘째: "ABC"를 대신하는 L"ABC"

 

WBCS 기반 문자열 선언 예

wchar_t str[]=L"ABC";

 

 

wchar_t 가 익숙하지 않을수 있지만 기본적으로 제공하는 표준자료형이다.

char형은 1byte로 문자를 표현하고 wchar_t 2byte로 문자를 표현한다.

또한 문자열을 선언 할 때 문자열 앞에를 붙여주어야 한다.

 

 

 예제2-3]

#include <stdio.h>
#include <string.h>

int main(void)
{
 wchar_t str[]=L"ABC";
 int size=sizeof(str);
 int len=strlen(str);   

 printf("배열의 크기 : %d \n", size);
 printf("문자열 길이 : %d \n", len);

 return 0;
}

 

예제 2-3을 컴파일 하면 오류가 발생 한다.

int len=strlen(str);를 보면  strlen함수는 strlen(char*) 식으로 char형 포인터타입을 전달하게 선언되어있는데 예제를 보면 wchat_t을 사용하므로 strlen함수를 wcslen함수로 대체하여야 한다.

 

문자열 조작함수

 

SBCS 함수

WBCS 기반의 문자열 조작 함수

strlen

size_t wcslen(const wchar_t* string);

strcpy

wchat_t* wcscpy(wchar_t* dest, const wchar_t* src );

strncpy

wchar_t* wcsncpy(wchar_t* dest, const wchar_t* src, size_t cnt);

strcat

wchar_t* wcscat(wchar_t* dest,const wchar_t* src);

strncat

wchar_t* wcsncat(wchar_t* dest,const wchar_t* src, size_t cnt);

strcmp

int wcscmp(const wchar_t* s1,const wchar_t* s2);

strncmp

int wcsncmp(const wchar_t* , cinst wchar_t* s2, size_t cnt);

 

 

예제2-4]

#include <stdio.h>
#include <string.h>

int main(void)
{
 wchar_t str[]=L"ABC";
 int size=sizeof(str);
 int len=wcslen(str);

 printf("배열의 크기 : %d \n", size);              실행결과
 printf("문자열 길이 : %d \n", len);                배열의 크기:8

 return 0;                                                    문자열 길이:3
}

예제2-3를 위의 처럼 바꾸면 컴파일이 되고 실행결과도 올바르게 나온다.

하지만 printf()함수 부분을 보면 WBCS방식으로 처리하고있지않는다.

밑에 표를보고 WBCS 기반의 입출력을 해볼수 있다. 

 

 

문자열 입출력 함수

 

 

 SBCS 함수

WBCS 기반의 문자열 입출력 함수 

 printf

int wprintf(const wchar_t* format [, argument]...); 

scanf 

int wscanf(const wchar_t* format [,argument]...); 

 fgets

wchar_t* fgetws(wchar_t* string, int n, FILE* stream);

 fputs

int fputws(const wchar_t* string, FILE* stream); 

 

예제2-5]

#include <stdio.h>
#include <string.h>

int main(void)
{
 wchar_t str[]=L"ABC";
 int size=sizeof(str);
 int len=wcslen(str);

 wprintf(L"Array Size    : %d \n", size);
 wprintf(L"String Length : %d \n", len);

 return 0;
}

 

입출력 함수도 WBCS 기반의 함수로 바꾸었다. 하지만 매개변수 전달자의 유니코드화가 되지않았다. 

 

 

 

 

 

 

 

매개변수 전달이자들 모두 WCBS 기반으로 바꿔주기 위해서는

main함수 대신해서 wmain함수를 선언해 주면된다. 또한 전달하는 인자들도

wchar_t 타입으로 바꾸어 주어야 한다.

 

 

+ Recent posts