일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- c++
- 포인터
- Direct2D
- Win32
- Tips프로그래밍강좌
- CS
- c
- Visual Studio
- 지식나눔강좌
- Desktop
- c#
- 김성엽
- Tips강좌
- 연산자
- 프로그래밍
- 함수
- 티스토리
- VS ERROR
- doit코틀린프로그래밍
- 배열
- 리뷰
- 알고리즘
- Kotlin
- tipssoft
- Programming
- Javascript
- 이지스퍼블리싱
- Windows
- 문법
- 백준
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
C 스타일의 문자열 관리 방식 본문
이번 포스트에선 C에서 문자열을 어떻게 관리하고 저장하는지 알아봅니다.
하나의 변수, 하나의 값
프로그래밍을 하는 데 있어 중요한 것 중 하나가 변수입니다. 연산의 결과를 저장하기도, 또 저장된 값을 불러오기도 하는데 이용합니다. 이 변수의 특성 중에 중요한 한 가지가 있습니다. 바로 하나의 값만을 저장할 수 있다는 점입니다. 따라서 하나의 변수가 동시에 두 가지 값을 저장할 수는 없습니다. 저장할 땐 그렇다 치더라도 값을 빼내 올 때 무엇을 빼야 할지 결정지을 수 없기 때문입니다.
그렇지만 우리는 문자열을 변수에 저장해서 사용합니다. 어떻게 이런 일이 가능할까요?
생각의 전환
이런 문제를 C언어에서는 전체 문자열을 저장하지 않고 맨 처음 한 글자가 저장된 주소를 저장하는 것으로 해결했습니다. 이미지로 보면 아래와 같습니다.
B 타입의 문제점
A타입과 달리 B타입은 문제점이 하나 있습니다. 바로 문자열의 시작은 알지만 끝은 알 수 없다는 것입니다. C언어는 이러한 문제를 해결하기 위해 문자열의 끝에 ASCII 0번, NULL 문자를 집어넣었습니다.
string.h 헤더에 선언된 strlen() 함수는 문자열의 길이를 알아내기 위해 사용하는 함수입니다. 그러나 실질적으로는 현재 위치로부터 NULL 문자까지의 길이를 반환하는 것입니다. 비단 예시를 든 strlen() 함수뿐만 아니라 문자열을 다루는 대부분의 함수가 위와 같이 NULL 문자를 기준으로 제어를 합니다.
A 타입으로는 안 되나요?
가능합니다. 그러나 초기 C언어가 나온 시점의 컴퓨터 성능을 살펴봐야 합니다. C언어가 태동할 시점엔 지금과 같이 메모리(RAM)가 많지 않았습니다. 저 역시도 그 시대를 겪지 않았기 때문에 정확히는 모르지만 당시를 겪었던 분들의 말씀을 빌리면 1MB는커녕 500KB도 없을 시절이라고 합니다. 문자열은 문자 하나가 1Byte를 차지하기 때문에 가뜩이나 메모리가 부족한 당시 컴퓨터에 프로그램을 운영하기 위해서는 극악의 최적화(일명 갓적화)를 해야 했습니다. A 타입의 문제점은 가변 길이의 문자열을 담기 위해 새로운 타입의 자료형이 필요할 겁니다. 자료형이란 애초에 크기가 정해져 있기 때문에 크기를 알 수 없는 문자열을 다루기 위해서는 공간을 굉장히 크게 만들어야 합니다. 그런데 굉장히 큰 문자열을 저장하기 위해 크기를 무작정 키우게 되면 크기가 작은 문자열을 저장할 때 공간 낭비가 발생합니다.
처음 말한 것처럼 당시 1Byte의 메모리가 중요하던 시대엔 낭비란 있을 수 없습니다. 그래서 가장 효율적인 방법이라 판단된 B가 채택이 되었습니다.
Q. 현재는 메모리가 넘쳐나는데 그럼 이젠 A와 같이 바꾸면 안 되나요?
물론 가능합니다. 그렇지만 생각해보세요. 이렇게 구조를 변경하게 되면, 변경 전/후의 프로그램은 호환성을 완전히 잃게 됩니다. 호환성을 유지하기 위해 추가 연산이 들어가야 하니 더 느려질 수도 있구요. 만일 당신이라면 Windows 7에서 잘 돌아가던 게임과 서비스들이 Windows 10에서 돌아가지 않는다면, 당신은 Windows 10을 사용할까요? 경제적 관점에서 보더라도 호환성은 꼭 필요합니다. 그래서 처음에 구조를 잘 짜는것이 중요하죠. 한번 결정되고 나면, 고치는덴 더 많은 노력과 비용이 드니까요 :)
더 알아보기
문자열의 끝을 가리키는 널문자를 문자열에 적용하지 않았을 때 C언어의 문자열 관리 방식에서 어떤 문제가 일어나는지는 아래 포스트를 참고하세요.
# index
'DEV > C C++' 카테고리의 다른 글
scanf()의 문제점 (0) | 2019.06.25 |
---|---|
함수 인자로 단항연산자 사용하기 (0) | 2019.06.25 |
sizeof 연산자의 오용 (0) | 2019.06.17 |
sizeof 연산자 (0) | 2019.06.17 |
Snake with Windows API (0) | 2019.06.08 |