-
[C Language] 38. 문자열과 포인터 - C 언어CSE/C Language 2015. 8. 4. 15:47
1. 문자열이란?
"In C, strings are arrays of characters."
C에서의 문자열에 대한 정의를 보면, 문자열 형이 없고 단지 문자들의 집합인 배열로 처리한다는 것을 알 수 있다. 또한, 포인터적인 관점에서 본다면 시스템은 문자열 전체에 전혀 관심이 없다. 시스템은 오로지 문자열 중에서도 가장 첫 번째 문자가 저장된 곳의 위치에만 관심이 있을 뿐이다. 문자열의 끝은 널 문자로 판별하기 때문에 널 문자가 없는 문자열은 C에서 상당히 위험한 존재로 여겨지고 메모리 에러의 대부분을 차지한다.
2. 문자열 포인터 변수
int 형 포인터 변수가 int 형 변수를 가리킬 수 있는 것과 마찬가지로 문자열 포인터 변수도 문자열을 가리킬 수 있다. 좀 더 정확히 말하면 문자열 중에서도 가장 첫 번째 문자가 저장된 곳을 주소를 기억한다.
문자열을 만나는 순간 시스템은 문자열을 메모리 어딘가에 저장하고 그 주소를 리턴한다. 이때의 주소는 문자들 중에서 가장 첫 번째 문자가 저장된 곳의 주소이다.
아래 예제로 문자열 단위 출력을 해보도록 하자.
12345678910111213141516171819202122232425/** str.c** Created on: 2015. 8. 4.* Author: Yeonsu*/#include <stdio.h>int main(void) {char *char_p = "I am a good boy";for (; *char_p; char_p++) {if (*char_p != ' ')putchar(*char_p);if (*char_p == ' ')putchar('\n');}puts("");return 0;}cs 3. 포인터 배열
여기서는 문자열을 저장할 때 배열을 사용했을 때와 포인터를 사용했을 때의 차이점을 명확히 설명함으로써 포인터가 얼마나 메모리 공간을 효율적으로 사용하는 지 검증해 보기로 한다.
배열을 사용하여 문자열을 저장한 경우
12345678910char name[6][20];strcpy(name[0], "Kim Dong Guk");strcpy(name[1], "Lee Dong Guk");strcpy(name[2], "Park Dong Guk");strcpy(name[3], "Jung Dong Guk");strcpy(name[4], "Han Dong Guk");strcpy(name[5], "Moon Dong Guk");cs 여섯 명의 이름을 저장하기 위해 모두 120바이트를 할당하였다. 한 사람의 이름을 저장하기 위한 공간이 들쑥날쑥하기 때문에 넉넉하게 20바이트를 준비하였다. 그 덕분에 남는 공백은 모두 낭비되고 있다. 배열을 사용하여 이름을 저장하는 방식은 한눈에 보아도 메모리 낭비가 심하다는 것을 알 수 있다.
포인터 배열을 사용하여 문자열을 저장한 경우
123456789char *name[6];name[0] = "Kim Dong Guk";name[1] = "Lee Dong Guk";name[2] = "Park Dong Guk";name[3] = "Jung Dong Guk";name[4] = "Han Dong Guk";name[5] = "Moon Dong Guk";cs name[0]이라는 포인터 변수는 'Kim Dong Guk'이라는 문자열에서 K가 저장된 주소를 기록한다. name[1]은 'L'의 주소를 기록하고 각각 맨 앞의 문자열의 주소를 저장하는데 이와 같이 처리하면 배열을 사용할 때와는 달리 메모리 낭비가 전혀 없음을 알 수 있다.
4. a, 'a', "a"
a와 'a' 그리고 "a"는 C에서 전혀 다른 특성을 가지고 있다.
1234567char a; // 1 byteshort b; // 2 bytesint c; // 4 bytes'a' // 1 byte"a" // 2 bytes, a \0cs 마지막 "a"는 문자열 상수로 C에서의 모든 문자열은 널 문자로 끝나기 때문에 눈에 보이지 않는 널 문자가 자동적으로 추가된다.
5. 포인터 변수와 배열명의 차이
- 할당받는 메모리의 크기가 다르다.
배열명: 배열며 자체로는 메모리를 차지하지 않고 배열첨자와 형(type)에 따라서 크기가 결정된다.
포인터 변수: 포인터를 저장하는 변수이기 때문에 무조건 4 바이트를 할당받는다.
- 문자열을 저장하는 형식이 다르다(복사와 할당의 차이가 발생)
배열명: 문자열 상수가 메모리에 저장되는 것이 아니라 문자 하나 하나가 배열에 복사된다.
포인터 변수: 문자열 상수가 메모리에 저장되고 이 위치가 포인터 변수에 할당된다.
- 증감연산자으 사용 여부가 다르다.
배열명: 증감 연산자를 사용할 수 없다.
포인터 변수: 증감 연산자를 사용할 수 있다.
'CSE > C Language' 카테고리의 다른 글
[C Language] 41. 포인터의 개념을 깨는 '0' (0) 2015.08.05 [C Language] 40. 문자열 함수 - C 언어 (0) 2015.08.05 [C Language] 39. 포인터의 포인터 - C 언어 (0) 2015.08.05 [C Language] 37. 2차원 배열과 포인터 - C 언어 (0) 2015.08.04 [C Language] 36. 1차원 배열과 포인터 - C 언어 (0) 2015.07.20 [C Language] 35. 포인터 기초 - C 언어 (0) 2015.07.20