달력

112024  이전 다음

  • 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

stdlib.h ............................................................................

 

형변환 함수

 

#include <stdlib.h>

 

문자열을 숫자로 변환

int atoi(char *source_buffer)

long atol(char *source_buffer)

float atof(char *source_buffer)

 

숫자를 문자열로 변환

char *itoa(int value, char *string, int radix)

char *ltoa(long value, char *string, int radix)

char *ftoa(float value, char *string, int radix)

 

실수형 숫자를 문자열로 변환

char *ecvt(double value, int count, int *dec, int *sign)

 

부동소수점 숫자를 문자열로 변환

char *fcvt(double value, int count, int *dec, int *sign)

char *gcvt(double value, int digits, char *buffer)

 

sccanf

 

scanf처럼 키보드 입력을 받지 않고, 문자열에서 데이터를 추출 한다.

 

format :

int sscanf(const char* buffer, const char* format, [...address]);

 

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


char str[128];

int i,j,k;

 

  strcpy(str, "One = 1, Two = 2, Three = 3");
  sscanf(str,"One = %d, Two = %d, Three = %d", &i, &j, &k);
  printf("%d, %d, %d \n", i, j, k);

 

 

wcscpy  ............................................................................

 

copy a wide-character string

 

#include <wchar.h>

wchar_t *wcscpy(wchar_t *ws1, const wchar_t *ws2);

 


 

 

MFC ............................................................................

 

 

Preprocessor Directives for Generic-Text Mappings
# define Compiled version Example

_UNICODE

Unicode (wide-character)

_tcsrev maps to _wcsrev

_MBCS

Multibyte-character

_tcsrev maps to _mbsrev

None (the default: neither _UNICODE nor _MBCS defined)

SBCS (ASCII)

_tcsrev maps to strrev

 

 

Generic-Text Data Type Mappings
Generic-Text Data Type Name _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined

_TCHAR

char

char

wchar_t

_TINT

int

int

wint_t

_TSCHAR

signed char

signed char

wchar_t

_TUCHAR

unsigned char

unsigned char

wchar_t

_TXCHAR

char

unsigned char

wchar_t

_T or _TEXT

No effect (removed by preprocessor)

No effect (removed by preprocessor)

L (converts following character or string to its Unicode counterpart)

 

 

 

UNICODE를 정의해주느냐 아니냐에 따라 컴파일만 따로 해주면 되니까요.

 

                    ANSI           UNICODE         TCHAR

헤더파일       string.h         wchar.h          tchar.h

문자             'A'                L'A'               _T('A')

문자열          "ABC"            L"ABC"           _T("ABC")

문자열카피    strcpy            wcscpy          _tcscpy

문자열길이    strlen             wcslen           _tcslen

문자열출력    printf              wprintf            _tprinf

파일열기       fopen             wfopen           _tfopn

 

MultiByteToWideChar()  : ANSI -> UNICODE

WideCharToMultiByte()  : UNICODE -> ANSI

 

 

MBCS와 UTF-8 변환 예 :

 

char buffer[20];
WCHAR Unicode[20];
char UTF8code[20];


 

int nUnicodeSize = MultiByteToWideChar(CP_ACP, 0, lpID, strlen(lpID), Unicode,sizeof(Unicode));
int nUTF8codeSize = WideCharToMultiByte(CP_UTF8, 0, Unicode, nUnicodeSize, UTF8code, sizeof(UTF8code), NULL, NULL);
nUnicodeSize = MultiByteToWideChar(CP_UTF8, 0, UTF8code, nUTF8codeSize, Unicode,sizeof(Unicode));
memcpy(buffer, UTF8code, nUTF8codeSize);

 

..........................................................................

 

출처 : http://msdn.microsoft.com/en-us/library/tsbaswba%28VS.80%29.aspx

 

Generic-Text Routine Mappings

Generic-text
routine name
SBCS (_UNICODE &
MBCS not defined)
_MBCS
defined
_UNICODE defined

_cgetts

_cgets

_cgets

_cgetws

_cgetts_s

_cgets_s

_cgets_s

_cgetws_s

_cputts

_cputs

_cputs

_cputws

_fgettc

fgetc

fgetc

fgetwc

_fgettchar

_fgetchar

_fgetchar

_fgetwchar

_fgetts

fgets

fgets

fgetws

_fputtc

fputc

fputc

fputwc

_fputtchar

_fputchar

_fputchar

_fputwchar

_fputts

fputs

fputs

fputws

_ftprintf

fprintf

fprintf

fwprintf

_ftprintf_s

fprintf_s

fprintf_s

fwprintf_s

_ftscanf

fscanf

fscanf

fwscanf

_ftscanf_s

fscanf_s

fscanf_s

fwscanf_s

_gettc

getc

getc

getwc

_gettch

_getch

_getch

_getwch

_gettchar

getchar

getchar

getwchar

_gettche

_getche

_getche

_getwche

_getts

gets

gets

getws

_getts_s

gets_s

gets_s

getws_s

_istalnum

isalnum

_ismbcalnum

iswalnum

_istalpha

isalpha

_ismbcalpha

iswalpha

_istascii

isascii

isascii

iswascii

_istcntrl

iscntrl

iscntrl

iswcntrl

_istdigit

isdigit

_ismbcdigit

iswdigit

_istgraph

isgraph

_ismbcgraph

iswgraph

_istlead

Always returns false

_ismbblead

Always returns false

_istleadbyte

Always returns false

isleadbyte

Always returns false

_istlegal

Always returns true

_ismbclegal

Always returns true

_istlower

islower

_ismbclower

iswlower

_istprint

isprint

_ismbcprint

iswprint

_istpunct

ispunct

_ismbcpunct

iswpunct

_istspace

isspace

_ismbcspace

iswspace

_istupper

isupper

_ismbcupper

iswupper

_istxdigit

isxdigit

isxdigit

iswxdigit

_itot

_itoa

_itoa

_itow

_itot_s

_itoa_s

_itoa_s

_itow_s

_ltot

_ltoa

_ltoa

_ltow

_ltot_s

_ltoa_s

_ltoa_s

_ltow_s

_puttc

putc

putc

putwc

_puttch

_putch

_putch

_putwch

_puttchar

putchar

putchar

putwchar

_putts

puts

puts

_putws

_sctprintf

_scprintf

_scprintf

_scwprintf

_sntprintf

_snprintf

_snprintf

_snwprintf

_sntprintf_s

_snprintf_s

_snprintf_s

_snwprintf_s

_sntscanf

_snscanf

_snscanf

_snwscanf

_sntscanf_s

_snscanf_s

_snscanf_s

_snwscanf_s

_stprintf

sprintf

sprintf

swprintf

_stprintf_s

sprintf_s

sprintf_s

swprintf_s

_stscanf

sscanf

sscanf

swscanf

_stscanf_s

sscanf_s

sscanf_s

swscanf_s

_taccess

_access

_access

_waccess

_taccess_s

_access_s

_access_s

_waccess_s

_tasctime

asctime

asctime

_wasctime

_tasctime_s

asctime_s

asctime_s

_wasctime_s

_tccmp

Maps to macro or inline function

_mbsncmp

Maps to macro or inline function

_tccpy

Maps to macro or inline function

_mbccpy

Maps to macro or inline function

_tccpy_s

strcpy_s

_mbccpy_s

wcscpy_s

_tchdir

_chdir

_chdir

_wchdir

_tclen

Maps to macro or inline function

_mbclen

Maps to macro or inline function

_tchmod

_chmod

_chmod

_wchmod

_tcprintf

_cprintf

_cprintf

_cwprintf

_tcprintf_s

_cprintf_s

_cprintf_s

_cwprintf_s

_tcreat

_creat

_creat

_wcreat

_tcscanf

_cscanf

_cscanf

_cwscanf

_tcscanf_s

_cscanf_s

_cscanf_s

_cwscanf_s

_tcscat

strcat

_mbscat

wcscat

_tcscat_s

strcat_s

_mbscat_s

wcscat_s

_tcschr

strchr

_mbschr

wcschr

_tcsclen

strlen

_mbslen

wcslen

_tcsclen_s

strlen_s

_mbslen_s

wcslen_s

_tcscmp

strcmp

_mbscmp

wcscmp

_tcscoll

strcoll

_mbscoll

wcscoll

_tcscpy

strcpy

_mbscpy

wcscpy

_tcscpy_s

strcpy_s

_mbscpy_s

wcscpy_s

_tcscspn

strcspn

_mbscspn

wcscspn

_tcsdec

_strdec

_mbsdec

_wcsdec

_tcsdup

_strdup

_mbsdup

_wcsdup

_tcserror

strerror

strerror

_wcserror

_tcserror_s

strerror_s

strerror_s

_wcserror_s

_tcsftime

strftime

strftime

wcsftime

_tcsicmp

_stricmp

_mbsicmp

_wcsicmp

_tcsicoll

_stricoll

_mbsicoll

_wcsicoll

_tcsinc

_strinc

_mbsinc

_wcsinc

_tcslen

strlen

strlen

wcslen

_tcslen_s

strlen_s

strlen_s

wcslen_s

_tcslwr

_strlwr

_mbslwr

_wcslwr

_tcslwr_s

_strlwr_s

_mbslwr_s

_wcslwr_s

_tcsnbcnt

_strncnt

_mbsnbcnt

_wcsncnt

_tcsncat

strncat

_mbsnbcat

wcsncat

_tcsncat_s

strncat_s

_mbsnbcat_s

wcsncat_s

_tcsnccat

strncat

_mbsncat

wcsncat

_tcsnccmp

strncmp

_mbsncmp

wcsncmp

_tcsnccmp_s

strncmp_s

_mbsncmp_s

wcsncmp_s

_tcsnccoll

_strncoll

_mbsncoll

_wcsncoll

_tcsncmp

strncmp

_mbsnbcmp

wcsncmp

_tcsnccnt

_strncnt

_mbsnccnt

_wcsncnt

_tcsnccpy

strncpy

_mbsncpy

wcsncpy

_tcsnccpy_s

strncpy_s

_mbsncpy_s

wcsncpy_s

_tcsncicmp

_strnicmp

_mbsnicmp

_wcsnicmp

_tcsncicoll

_strnicoll

_mbsnicoll

_wcsnicoll

_tcsncpy

strncpy

_mbsnbcpy

wcsncpy

_tcsncpy_s

strncpy_s

_mbsnbcpy_s

wcsncpy_s

_tcsncset

_strnset

_mbsnset

_wcsnset

_tcsnextc

_strnextc

_mbsnextc

_wcsnextc

_tcsnicmp

_strnicmp

_mbsnbicmp

_wcsnicmp

_tcsnicoll

_strnicoll

_mbsnbicoll

_wcsnicoll

_tcsninc

_strninc

_mbsninc

_wcsninc

_tcsnccnt

_strncnt

_mbsnccnt

_wcsncnt

_tcsnset

_strnset

_mbsnbset

_wcsnset

_tcspbrk

strpbrk

_mbspbrk

wcspbrk

_tcsspnp

_strspnp

_mbsspnp

_wcsspnp

_tcsrchr

strrchr

_mbsrchr

wcsrchr

_tcsrev

_strrev

_mbsrev

_wcsrev

_tcsset

_strset

_mbsset

_wcsset

_tcsspn

strspn

_mbsspn

wcsspn

_tcsstr

strstr

_mbsstr

wcsstr

_tcstod

strtod

strtod

wcstod

_tcstoi64

_strtoi64

_strtoi64

_wcstoi64

_tcstok

strtok

_mbstok

wcstok

_tcstok_s

strtok_s

_mbstok_s

wcstok_s

_tcstol

strtol

strtol

wcstol

_tcstoui64

_strtoui64

_strtoui64

_wcstoui64

_tcstoul

strtoul

strtoul

wcstoul

_tcsupr

_strupr

_mbsupr

_wcsupr

_tcsupr_s

_strupr_s

_mbsupr_s

_wcsupr_s

_tcsxfrm

strxfrm

strxfrm

wcsxfrm

_tctime

ctime

ctime

_wctime

_tctime_s

ctime_s

ctime_s

_wctime_s

_tctime32

_ctime32

_ctime32

_wctime32

_tctime32_s

_ctime32_s

_ctime32_s

_wctime32_s

_tctime64

_ctime64

_ctime64

_wctime64

_tctime64_s

_ctime64_s

_ctime64_s

_wctime64_s

_texecl

_execl

_execl

_wexecl

_texecle

_execle

_execle

_wexecle

_texeclp

_execlp

_execlp

_wexeclp

_texeclpe

_execlpe

_execlpe

_wexeclpe

_texecv

_execv

_execv

_wexecv

_texecve

_execve

_execve

_wexecve

_texecvp

_execvp

_execvp

_wexecvp

_texecvpe

_execvpe

_execvpe

_wexecvpe

_tfdopen

_fdopen

_fdopen

_wfdopen

_tfindfirst

_findfirst

_findfirst

_wfindfirst

_tfindnext

_findnext

_findnext

_wfindnext

_tfindnext32

_findnext32

_findnext32

_wfindnext32

_tfindnext64

_findnext64

_findnext64

_wfindnext64

_tfindnexti64

_findnexti64

_findnexti64

_wfindnexti64

_tfindnexti6432

_findnexti6432

_findnexti6432

_wfindnexti6432

_tfindnext32i64

_findnext32i64

_findnext32i64

_wfindnext32i64

_tfopen

fopen

fopen

_wfopen

_tfopen_s

fopen_s

fopen_s

_wfopen_s

_tfreopen

freopen

freopen

_wfreopen

_tfreopen_s

freopen_s

freopen_s

_wfreopen_s

_tfsopen

_fsopen

_fsopen

_wfsopen

_tfullpath

_fullpath

_fullpath

_wfullpath

_tgetcwd

_getcwd

_getcwd

_wgetcwd

_tgetdcwd

_getdcwd

_getdcwd

_wgetdcwd

_tgetenv

getenv

getenv

_wgetenv

_tgetenv_s

getenv_s

getenv_s

_wgetenv_s

_tmain

main

main

wmain

_tmakepath

_makepath

_makepath

_wmakepath

_tmakepath_s

_makepath_s

_makepath_s

_wmakepath_s

_tmkdir

_mkdir

_mkdir

_wmkdir

_tmktemp

_mktemp

_mktemp

_wmktemp

_tmktemp_s

_mktemp_s

_mktemp_s

_wmktemp_s

_topen

_open

_open

_wopen

_topen_s

_open_s

_open_s

_wopen_s

_totlower

tolower

_mbctolower

towlower

_totupper

toupper

_mbctoupper

towupper

_tperror

perror

perror

_wperror

_tpopen

_popen

_popen

_wpopen

_tprintf

printf

printf

wprintf

_tprintf_s

printf_s

printf_s

wprintf_s

_tputenv

_putenv

_putenv

_wputenv

_tputenv_s

_putenv_s

_putenv_s

_wputenv_s

_tremove

remove

remove

_wremove

_trename

rename

rename

_wrename

_trmdir

_rmdir

_rmdir

_wrmdir

_tsearchenv

_searchenv

_searchenv

_wsearchenv

_tsearchenv_s

_searchenv_s

_searchenv_s

_wsearchenv_s

_tscanf

scanf

scanf

wscanf

_tscanf_s

scanf_s

scanf_s

wscanf_s

_tsetlocale

setlocale

setlocale

_wsetlocale

_tsopen

_sopen

_sopen

_wsopen

_tsopen_s

_sopen_s

_sopen_s

_wsopen_s

_tspawnl

_spawnl

_spawnl

_wspawnl

_tspawnle

_spawnle

_spawnle

_wspawnle

_tspawnlp

_spawnlp

_spawnlp

_wspawnlp

_tspawnlpe

_spawnlpe

_spawnlpe

_wspawnlpe

_tspawnv

_spawnv

_spawnv

_wspawnv

_tspawnve

_spawnve

_spawnve

_wspawnve

_tspawnvp

_spawnvp

_spawnvp

_wspawnvp

_tspawnvpe

_spawnvpe

_spawnvpe

_wspawnvpe

_tsplitpath

_splitpath

_splitpath

_wsplitpath

_tstat

_stat

_stat

_wstat

_tstat32

_stat32

_stat32

_wstat32

_tstati32

_stati32

_stati32

_wstati32

_tstat64

_stat64

_stat64

_wstat64

_tstati64

_stati64

_stati64

_wstati64

_tstof

atof

atof

_wtof

_tstoi

atoi

atoi

_wtoi

_tstoi64

_atoi64

_atoi64

_wtoi64

_tstol

atol

atol

_wtol

_tstrdate

_strdate

_strdate

_wstrdate

_tstrdate_s

_strdate_s

_strdate_s

_wstrdate_s

_tstrtime

_strtime

_strtime

_wstrtime

_tstrtime_s

_strtime_s

_strtime_s

_wstrtime_s

_tsystem

system

system

_wsystem

_ttempnam

_tempnam

_tempnam

_wtempnam

_ttmpnam

tmpnam

tmpnam

_wtmpnam

_ttmpnam_s

tmpnam_s

tmpnam_s

_wtmpnam_s

_ttoi

atoi

atoi

_wtoi

_ttoi64

_atoi64

_atoi64

_wtoi64

_ttol

atol

atol

_wtol

_tunlink

_unlink

_unlink

_wunlink

_tutime

_utime

_utime

_wutime

_tutime32

_utime32

_utime32

_wutime32

_tutime64

_utime64

_utime64

_wutime64

_tWinMain

WinMain

WinMain

wWinMain

_ui64tot

_ui64toa

_ui64toa

_ui64tow

_ui64tot_s

_ui64toa_s

_ui64toa_s

_ui64tow_s

_ultot

_ultoa

_ultoa

_ultow

_ultot_s

_ultoa_s

_ultoa_s

_ultow_s

_ungettc

ungetc

ungetc

ungetwc

_ungettch

_ungetch

_ungetch

_ungetwch

_vftprintf

vfprintf

vfprintf

vfwprintf

_vftprintf_s

vfprintf_s

vfprintf_s

vfwprintf_S

_vsctprintf

_vscprintf

_vscprintf

_vscwprintf

_vsctprintf_s

_vscprintf_s

_vscprintf_s

_vscwprintf_S

_vsntprintf

_vsnprintf

_vsnprintf

_vsnwprintf

_vsntprintf_s

_vsnprintf_s

_vsnprintf_s

_vsnwprintf_s

_vstprintf

vsprintf

vsprintf

vswprintf

_vstprintf_s

vsprintf_s

vsprintf_s

vswprintf_s

_vtprintf

vprintf

vprintf

vwprintf

_vtprintf_s

vprintf_s

vprintf_s

vwprintf_s

 

Generic-Text Data Type Mappings
Generic-text data type name SBCS (_UNICODE, _MBCS not defined) _MBCS defined _UNICODE defined

_TCHAR

char

char

wchar_t

_tfinddata_t

_finddata_t

_finddata_t

_wfinddata_t

_tfinddata64_t

__finddata64_t

__finddata64_t

__wfinddata64_t

_tfinddatai64_t

_finddatai64_t

_finddatai64_t

_wfinddatai64_t

_TINT

int

int

wint_t

_TSCHAR

signed char

signed char

wchar_t

_TUCHAR

unsigned char

unsigned char

wchar_t

_TXCHAR

char

unsigned char

wchar_t

_T or _TEXT

No effect (removed by preprocessor)

No effect (removed by preprocessor)

L (converts following character or string to its Unicode counterpart)

 

 

Locale-Dependent Routines
Routine Use setlocale category setting dependence

atof, _wtof_l, _wtof, _atof_l

Convert character to floating-point value

LC_NUMERIC

atoi, _wtoi_l, _wtoi, _atoi_l

Convert character to integer value

LC_NUMERIC

_atoi64, _wtoi64_l, _wtoi64, _atoi64_l

Convert character to 64-bit integer value

LC_NUMERIC

atol, _wtol_l, _wtol, _atol_l

Convert character to long value

LC_NUMERIC

_atodbl, _atoflt_l, _atoflt, _atoldbl_l, _atoldbl, _atodbl_l

Convert character to double-long value

LC_NUMERIC

Routines is

Test given integer for particular condition.

LC_CTYPE

isleadbyte, _isleadbyte_l

Test for lead byte

LC_CTYPE

localeconv

Read appropriate values for formatting numeric quantities

LC_MONETARY, LC_NUMERIC

MB_CUR_MAX

Maximum length in bytes of any multibyte character in current locale (macro defined in STDLIB.H)

LC_CTYPE

_mbccpy_s, _mbccpy_l, _mbccpy, _mbccpy_s_l

Copy one multibyte character

LC_CTYPE

_mbclen, _mblen_l,  mblen

Validate and return number of bytes in multibyte character

LC_CTYPE

strlen, _mbstrlen_l, _mbstrlen, _mbslen_l, _mbslen, wcslen_l, wcslen, strlen_l

For multibyte-character strings: validate each character in string; return string length

LC_CTYPE

mbstowcs_s, _mbstowcs_l,mbstowcs,_mbstowcs_s_l

Convert sequence of multibyte characters to corresponding sequence of wide characters

LC_CTYPE

mbtowc, _mbtowc_l

Convert multibyte character to corresponding wide character

LC_CTYPE

printf functions

Write formatted output

LC_NUMERIC (determines radix character output)

scanf functions

Read formatted input

LC_NUMERIC (determines radix character recognition)

setlocale, _wsetlocale

Select locale for program

Not applicable

_mbscoll_l _wcscoll_l, _strcoll_l, _mbscoll, wcscoll,strcoll

Compare characters of two strings

LC_COLLATE

_mbsicmp_l,_wcsicmp_l, _stricmp_l, _mbsicmp, _wcsicmp, _stricmp,

Compare two strings without regard to case

LC_CTYPE

_mbsicoll_l,_wcsicoll_l, _stricoll_l, _mbsicoll, _wcsicoll,_stricoll,

Compare characters of two strings (case insensitive)

LC_COLLATE

_mbsncoll_l,_wcsncoll_l, _strncoll_l, _mbsncoll, _wcsncoll, _strncoll,

Compare first n characters of two strings

LC_COLLATE

_mbsnicmp_l,_wcsnicmp_l, _strnicmp_l, _mbsnicmp, _wcsnicmp, _strnicmp,

Compare characters of two strings without regard to case.

LC_CTYPE

_mbsnicoll_l,_wcsnicoll_l, _strnicoll_l, _mbsnicoll, _wcsnicoll, _strnicoll,

Compare first n characters of two strings (case insensitive)

LC_COLLATE

_wcsftime_l,_strftime_l, wcsftime, strftime,

Format date and time value according to supplied format argument

LC_TIME

_mbslwr_l,_wcslwr_l, _strlwr_l, _mbslwr, _wcslwr, _strlwr, _wcslwr_s_l,_wcslwr_s, _mbslwr_s_l, _mbslwr_s, _strlwr_s_l, _strlwr_s,

Convert, in place, each uppercase letter in given string to lowercase

LC_CTYPE

_wcstod_l, wcstod, _strtod_l,strtod,

Convert character string to double value

LC_NUMERIC (determines radix character recognition)

_wcstol_l,_strtol_l, wcstol,strtol,

Convert character string to long value

LC_NUMERIC (determines radix character recognition)

_wcstoul_l,wcstoul, _strtoul_l, strtoul,

Convert character string to unsigned long value

LC_NUMERIC (determines radix character recognition)

_wcsupr, _wcsupr_l, _mbsupr_l, _mbsupr, _strupr_l, _strupr, _wcsupr_s_l, _wcsupr_s, _mbsupr_s_l, _mbsupr_s, _strupr_s_l, _strupr_s,

Convert, in place, each lowercase letter in string to uppercase

LC_CTYPE

_wcsxfrm_l, _strxfrm_l, wcsxfrm, strxfrm,

Transform string into collated form according to locale

LC_COLLATE

_towlower_l, _tolower_l, towlower, _tolower,tolower,_mbctoupper_l, _mbctoupper, _mbctolower_l,_mbctolower,

Convert given character to corresponding lowercase character

LC_CTYPE

_towupper_l, _toupper_l, towupper, _toupper,toupper, _mbctoupper_l, _mbctoupper, _mbctolower_l,_mbctolower,

Convert given character to corresponding uppercase letter

LC_CTYPE

_wcstombs_l,wcstombs,_wcstombs_s_l,wcstombs_s,

Convert sequence of wide characters to corresponding sequence of multibyte characters

LC_CTYPE

_wctomb_l,wctomb,_wctomb_s_l,wctomb_s,

Convert wide character to corresponding multibyte character

LC_CTYPE


출처 : http://blog.naver.com/dolicom/10074808231
Posted by 위너즈
|

C++에서 복사생성자의 전달인자 선언시 const를 붙여주지 않아도 상관없다. 그러나 & 선언은 반드시 해줘야 한다.

& 선언이 없다면 무한루프에 빠져 버리기 때문이다. 다행히 대부분의 컴파일러는 & 선언을 해주지 않으면 컴파일

오류를 발생시켜 준다. 참으로 고마운 일이 아닐 수 없다. 그렇다면 왜 무한루프에 빠지게 되는 것일까?

다음 코드를 보기 바란다.

위 소스에서 네모친 부분이 복사생성자를 호출하는 부분이다.

여기서 &를 넣지 않는다면, 이는 Call by Reference 가 아닌, Call by Value가 된다.

즉, 값을 복사하여 그 값을 참조한다는 뜻이다. 하지만 문제는 지금부터 시작이다.

AAA객체를 복사하기 위해서는 객체생성 순서에 따라서 메모리를 할당하고 값을 복사하여야 한다.

다시 말해서 생성자를 호출하여야 한다는 의미다.

복사생성자 호출 -> 인자로 넘어가는 객체의 복사 -> 생성자, 복사생성자 호출 -> 그 복사생성자 안에서 또다시 객체 복사 -> 복사생성자 호출 -> ... 무한반복 ...

이렇게 복사생성자의 형식인자를 생성해야 하기 때문에 무한루프에 빠지게 된다. 역시 원인은 &를 빼면 Call by Value 라는 점에 있고, 레퍼런스를 쓰는 이유 중 하나이기도 하다.

 

※ 참고로 레퍼런스(&)를 사용한 Call by Reference로 인자를 넘겨주는 이유는 다음과 같이 크게 2가지이다.

1. &를 사용하지 않고 포인터를 사용하면 포인터 연산이 가능하기 때문에 잘못된 메모리 접근을 할 가능성이 높아진다.

    아래의 코드는 에러를 나타낼 것이다.

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

 void swap(int *a, int *b)

 {

        int temp = *a;

        a++;    // 잘못 들어간 코드

        *a = *b;

        *b = temp;

}

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

경우에 따라서는 포인터 연산이 가능하다는 것이 단점으로 작용한다.

 

2. 약간의 성능향상이 가능하다. 

   Call by Value로 크기가 큰 구조체같은 데이터를 함수 인자로 넘겨주면 함수의 호출이 부담스러울 수 밖에 없다.

   Call by Value의 기본 방식이 복사이기 때문이다.

   이러한 부담을 레퍼런스가 해결해 줄 수 있다. 레퍼런스의 형태로 받게 되면, 변수 주소만 복사해 가는 것이지, 데이터 자체가 복사되는 것이 아니기 때문이다.

→ 그렇다면, 레퍼런스(&)를 사용하여 Call by Reference로 함수 인자를 넘기는 것이 무조건 좋은 것인가??

   꼭 그렇지는 않다. 다음의 코드를 보자

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

void swap(int &a, int &b)

{

        int temp = a;

        a = b;

        b = temp;

}

int main(void)

{

        ...

        swap(val1, val2); 

        ...

}

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

   대충 눈치를 채셨겠지만, 이것만 봐서는 도대체 이 swap 함수가 Call by Value인지 Call by Reference인지 감을 잡지 못한다.
   프로그램의 길이가 엄청 긴 경우에는 더욱 헷갈릴 것이다.

   Call by Reference의 적절한 사용은 프로그래머의 선택이다. ^^

출처 : http://blog.naver.com/damby0?Redirect=Log&logNo=50023611792

'Programming > C++' 카테고리의 다른 글

C/C++언어 함수들  (0) 2011.08.22
교차 포함 시 대량의 오류가 발생하는 경우  (0) 2011.04.26
Posted by 위너즈
|
error C2146: 구문 오류 : ';'이(가) ... 식별자 앞에 없습니다.
error C4430: 형식 지정자가 없습니다. int로 가정합니다. 참고: C++에서는 기본 int를 지원하지 않습니다.
error C4430: 형식 지정자가 없습니다. int로 가정합니다. 참고: C++에서는 기본 int를 지원하지 않습니다.

...

위와 같은 에러가 나는 이유는 클래스를 찾을 수 없는 경우에 발생합니다. 분명히 클래스가 있는데도 불구하고 이런 에러메시지가 발생하는 경우는.. 보통 교차포함을 한 경우에 이런 에러가 자주 발생합니다.
이게 무슨 얘기냐.. 다음을 보시죠..

b.h
#pragma once
#include "a.h"
class B
{
public:
 A a;
};

a.h
#pragma once
#include "b.h"
class A
{
public:
 B b;
};

양쪽의 클래스들은 서로를 필요로 하기 때문에 서로 #include을 해주었습니다.
언뜻 보기에는 문제가 없어보이죠. 실제로 자바에서는 에러가 나질 않습니다. 하지만 c++에서는 에러를 유발합니다. 무수히 많은 에러를 유발하죠.... 아주 많이....
 
하나하나 따라가보면 그 이유를 알 수 있습니다.
일단 b.cpp파일을 컴파일한다고 합시다. 그럼 b.cpp에는 최상단에 b.h가 include되어있을 겁니다. 그래서 컴파일러는 b.h를 포함시키죠. b.h를 가보니 상단에 a.h가 include되어있습니다. 그럼 그 헤더파일을 포함시키려 하겠죠. 그래서 a.h에 가보니.. 상단에 b.h가 include되어있습니다. 좀전에 b.cpp에서 b.h를 include했는데도 불구 한번더 include하려하지요.(아직 class B가 전부 읽혀진건 아닙니다.) 하지만 #pragma once구문 보이시죠? 이 구문때문에 헤더파일은 단 한번만 불려와지게 됩니다. 결국 a.h에 있는 #include "b.h"구문은 있으나 마나한 셈이 되죠. 그래서 class A의 B b부분에서 클래스 B는 이세상에 없는 클래스로 인식하고 형식이 없다는 에러메시지를 발생시키는 겁니다. 만약 class A에 포함된 에러 헤더파일 중 B를 필요로 하는 헤더파일이 있다면.. 에러메시지는 더욱더 많이 발생할 겁니다. 마찬가지로 a.cpp를 컴파일 하는경우 똑같은 에러가 나겠네요.

또한 서로 포함하지 않았는데도 불구, 이 에러메시지가 발생하는 경우가 있습니다.
그 경우는 서로는 포함하지 않았지만, 각 파일에 포함된 헤더파일들에 포함되어 간접적으로 서로를 포함한 경우가 해당됩니다.
b.h
#pragma once
#include "a.h"
class B
{
public:
 A a;
};

a.h
#pragma once
#include "c.h"
class A
{
public:
 B b;
};

c.h
#pragma once
#include "b.h"
class C
{
};


정말 간단하게 생각하면 #pragma once가 문제라고 생각하실 수 있습니다.
하지만 이걸 없애버리면 더 큰 문제가 발생합니다. class B가 두번 로드되는 경우죠. 심벌은 단 한개만 유효합니다. class B가 여러개 있을수는 없겠죠. 그렇다면, 단 한번만 불려와지고.. a.h에서도 인식할 수 있는 방법이 있느냐..? 물론 존재합니다. 여러가지 기법들이 존재하죠.



해결책

1. 가장 간단한 방법
헤더파일에서는 컴파일러에 단지 "암시"만 주고 포함시키지 않는 방법입니다.
b.h
#pragma once
class A; // class A가 존재한다고만 알려줍니다.
class B
{
public:
 A* a; // 포인터로 바꾸었습니다.
};

a.h
#pragma once
class B; // class B가 존재한다고만 알려줍니다.
class A
{
public:
 B* b;
};

※ 주의) 각각의 소스파일엔 포함시켜줘야합니다. 이렇게 하면 서로 include를 하지 않기 때문에 위와 같은 에러가 발생하지 않습니다. class A; 라고 하기만 하고 끝낸 부분이 눈에 띄는데, 이 부분은 실제로 클래스를 정의하진 않고 단지 앞으로 정의될 것이다, 나중에 링크과정때 찾아보라고 하는 일종의 암시입니다. 당장은 컴파일을 위해 때우는(?) 수단이라고 보시면 되겠죠. 그리고 A a에서 A* a로 포인터로 바뀐 부분을 알 수가 있는데, 일반 변수의 경우 크기를 알아야 하기 때문이죠. 따라서 일반 변수로 했다면 B를 컴파일 하는 도중 A의 크기를 구하려고 할 것이고, 에러를 유발하곤 합니다. 반면에 포인터 변수는 어떤 타입에도 상관없이 4바이트를 고수합니다.

한가지 주의하실 점은, 저렇게 하고 b.h에서 A의 멤버변수(함수)에 접근하는 인라인 함수같은 코드는 넣으시면 안됩니다. 컴파일 되는 당시로썬 A의 상세코드는 알길이 없기 때문이죠. 단 다음과 같은 경우는 가능합니다. 그 이유는 당장엔 A의 내용을 알필요가 없기 때문입니다. 소스파일에 넣으시기 바랍니다.
b.h
#pragma once
class A; // class A가 존재한다고만 알려줍니다.
class B
{
public:
 A* a; // 포인터로 바꾸었습니다.
 B() : a(NULL) {}
 ~B(){ if( a != NULL)delete a; } // 이 구문은 절대 안됩니다. 현재로썬 a의 크기를 알수 없기 때문입니다.
 A* GetAPtr() { return a; }
};




2. 좀더 나은 방법
b.h
#pragma once
#include "ABase.h"
#include "BBase.h"
class B : public BBase
{
public:
 B();
 virtual ~B();
 ABase* a;
};

a.h
#pragma once
#include "ABase.h"
#include "BBase.h"
class A : public ABase
{
public:
 A();
 virtual ~A();
 BBase* b;
};

b.cpp
#include "b.h"
#include "a.h"

B::B()
{
  a = new A();
}
B::~B()
{
  if( a!=NULL ) delete a;
}

BBase.h
class BBase
{
public:
  virtual ~BBase(){}
};

클래스를 상속으로 계층관계로 만들어버린 후, 부모클래스를 포함시키는 방법입니다. 정의는 부모클래스지만 당연히 할당은 자식클래스로 하게 되겠죠?^^; 이 방법은 실제로 자주 사용되고 있습니다. 유명한 패턴중 상태패턴에서도 이런 구조로 사용되죠. 그리고 컨테이너들도 저런 방식과 유사하게 설계되었을거라 생각합니다. 하지만, 무리하게 이 방식으로 할 필욘 없다고 생각합니다. 몇몇의 경우는 제외하고는 이 방식보단 처음방식이 더 나을수도 있겠습니다..^^



맺음말
실제로 이런 디자인은 말라고 합니다만.. 현재 라이브러리에서는 이런 디자인이 비일비재합니다. 가장 간단한 예로 MFC에서 부모와 차일드 윈도우 관계죠. 또는 게임 오브젝트 관리자와 게임 오브젝트들과 서로 포함시켜서 프로그래밍을 단순화 시키기도 합니다. 때로는 이런 디자인이 간편하고 가독성에도 일조한단 얘기죠.
저작자 표시 비영리 변경 금지
출처 : http://ekessy.tistory.com/trackback/20 
 

'Programming > C++' 카테고리의 다른 글

C/C++언어 함수들  (0) 2011.08.22
[C++] 레퍼런스(&) 미사용시 복사생성자의 무한루프  (0) 2011.05.18
Posted by 위너즈
|