본문 바로가기
C++/기초

C++ 기초 : 문자열 (1)

글: 시플마 2024. 4. 2.

1Byte로 표현할 수 있는 양수는 0 포함, 255까지이기 때문에

1Byte로 충분합니다. 그래서 문자를 표현하는 자료형 char는 1Byte이죠.

 

 

그러나 이는 영어만 사용할 때 기준이고,

당장 한글만 표현하려고 해도 '가', '달', '꿼' 등 경우의 수가 엄청 많습니다.

 

이를 위해 다른 체계가 필요했고 그때 사용하는 자료형이

2Byte 정수로, 문자를 표현하는 자료형 'wchar_t'입니다.

 

2Byte면 16Bit이고, 이는 2의 16제곱이므로 0 ~ 65,535의 수를 

표현할 수 있습니다. 한글을 표현하는데 충분하겠죠.

 

 

아래 코드를 보시면

 

wchar_t를 사용한 모습을 볼 수 있습니다.

 

대입할 문자 앞에 대문자 L을 붙여, 해당 문자를

2Byte 공간에 넣을 것을 알려주어야 합니다.

 

로컬 창에서 값을 확인해 보면

char형 변수 c에 '가'를 대입하니 이상한 값이 나오고

wchar_t형 변수 wc에 L을 붙여 '가'를 대입하면 

정상적으로 값이 대입된 것을 확인할 수 있습니다.

 

 


 

 

 

문자열을 대입하려면 배열로 선언해야 할 것입니다.

 

char형 배열 c와 wchar_t형 배열 wc를 각각 10개의

공간을 할당하여 "abcdef"를 넣었습니다.

 

char형 배열 c는 각 공간이 1Byte일 것이고

wchar_t형 배열 wc는 각 공간이 2Byte로 구성되어 있겠죠?

 

 

여기서 주의할 점은

 

위 코드와 같이

대입할 문자가 6개라고 해서 6개의 공간만 할당하면 안됩니다.

이유는 문자열의 끝을 알리기 위해 문자열 뒤에는 NULL Character가

들어가기 때문에 들어가는 문자의 개수보다 공간이 한 개 더 필요합니다.

위와 같은 경우 최소 7개의 공간이 필요한 것이죠.

 

 


 

 

 

문자 자료형이 아니라면 문자로 초기화를 진행할 수 없습니다.

 

예를 들어 위 그림처럼

정수 자료형인 short형 변수 s에 문자열을 바로 대입하려고 하니 오류가 발생하죠. 

 

 

아래 ASCII 표를 기반으로

 

 

위 코드를 봤을 때

short형 변수 s와 wchar_t형 변수 wc의 메모리에 들어간 값은 같겠죠.

또한 변수 s도 나머지 공간이 0으로 채워져 있을 것입니다.

 

다만 변수 wc는 문자 자료형이기 때문에 문자로 표현해 줄 수 있는 것이죠.

 

 

 


 

 

 

아래 코드에서

 

26번째 줄을 보죠.

wchar_t형 포인터 변수 pChar가 선언되었습니다.

그런데 특이한 점은 문자열의 주솟값을 저장하고 있습니다.

오류도 발생하지 않고요.

 

포인터 변수는 주솟값을 받아야 하기 때문에 rvalue, 

즉 특정 변수의 주소를 넣어줘야 할 것 같은데 단순한 문자열을 대입하고 있죠.

 

 

어떻게 동작하고 있는 것일까요?

 

wchar_t형 변수 wc 같은 경우, 초기화를 하면서 "abcdef"를 '복사'하여

자신이 할당하고 있는 배열 공간에 값을 넣는 것입니다.

 

 

반면 const wchar_t형 포인터 변수 pChar는

 

"abcdef" 문자열의 시작 주소를 저장하고 있는 것이죠.

 

코드로 문자열을 작성하면 어떤 메모리 공간에 문자열이 저장됩니다.

배열의 문자열을 넣을 때는 이를 복사하여 사용하는 것이고,

포인터 변수로 문자열의 주솟값을 저장하면 바로 이를 가리키는 것이죠.

 

이러한 문자열이 있는 공간이 바로 'ROM(Read-Only Memory)'입니다.

우리가 작성하는 코드가 바로 이 공간에 들어가 있습니다.

 

 

그럼 아래 코드를 보면

 

28번째 줄은 오류가 발생하지 않습니다. 실행하면

배열 wc 두 번째 칸에 저장된 b가 z로 바뀌겠죠.

 

그럼 29번째 줄은 왜 오류가 발생할까요?

포인터 변수 pChar는 ROM에 있는 문자열의 주소를

저장하고 있어 이를 직접 가리키고 있는 형태이기 때문에 

오직 읽기만 가능한 메모리에 있는 값을 바꾸려고 하니 오류가 발생하는 것입니다.

 

ROM에는 우리가 작성하고 실행할 코드가 쓰여있기 때문에

이를 프로그램이 진행되는 와중에 바꾸려고 하면 당연히 오류가 발생하는 것이죠.

 

그래서 문자 자료형 포인터 변수를 선언하고

문자 또는 문자열로 바로 초기화하고 싶다면

const를 붙여야 문법 오류가 발생하지 않습니다.

 

const를 붙이지 않고 선언된  문자 자료형 포인터 변수로

ROM에 있는 문자열에 접근하여 값을 바꾸는 것을 방지한 것이죠.

 

 


 

 

 

애초에 L"abcdef"라는 구문 자체의 반환 형식이 const wchar_t 형식입니다.

 

예전에는 const가 붙지 않고 일반 문자 자료형으로 반환되었다고 하네요.

그래서 해당 문자 또는 문자열의 주소를 저장할 때 사용하는 포인터 변수에도 

const를 붙일 필요가 없었고,이에 따라 직접 접근하여 값을 수정하는 코드를 작성해도

문법 오류가 발생하지 않아 오류가 발생할 여지가 있었다고 합니다.

 

다행히 이러한 점이 개선되어 이제는 문법 오류로 바로 잡아주죠.

 

 

물론 강제로 const wchar_t형 문자열을

 

wchar_t형 문자열로 변환하여

wchar_t형 포인터 변수에 주솟값을 저장하고 값을 수정할 수 있습니다.

 

이러면 컴파일과 링크 과정에서도 오류를 잡아주지 못합니다.

 

이후 빌드하고 프로그램까지 나왔는데,

막상 실행하니 실행 중 발생하는 런타임 오류가 발생할 수 있겠죠.

 

 

이러한 상황을 만들지 않으려면

문자열과 포인터 관련 내용을 잘 숙지해야겠습니다.

 

 

 

 

강의 출처 : https://www.youtube.com/watch?v=PFc4g8mxOiI&list=PL4SIC1d_ab-aOxWPucn31NHkQvNPHK1D1&pp=iAQB

 

 


 

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

C++ 기초 : 문자열 (3)  (0) 2024.04.03
C++ 기초 : 문자열 (2)  (0) 2024.04.03
C++ 기초 : 문자  (0) 2024.04.01
C++ 기초 : void  (0) 2024.03.31
C++ 기초 : const 포인터 예시  (0) 2024.03.31