Shine's dev log

[C] char[] 과 char *의 차이에 관하여 본문

프로그래밍, 알고리즘

[C] char[] 과 char *의 차이에 관하여

dong1 2020. 3. 25. 01:18

신입생 시절, 나를 괴롭혔던 문자열에 대하여 제대로 정리해보자.

 

아까도 말했듯이 C에는 문자열을 직접 다루는 자료형이 없다. 그래서 char의 배열을 사용하여 문자열을 '간접적으로' 나타낸다.

 

하지만, 리스트와는 다르게 배열은 크기가 고정적이다. 그래서 처음 char배열의 변수를 만들 때, 넉넉하게 크기를 설정해줘야 하는데, 그러다 보면 메모리의 낭비가 발생할 수 있다.

 

예를들어 char s1[100] 으로 설정된 s1라는 변수에 "hello"라는 문자열로 초기화 시킨다면,

 

h, e, l, l, o, \0 이 6개를 제외한 94개의 칸은 낭비되는 것이다.

 

그렇다고 무턱대고 배열의 크기를 줄이자니 데이터가 잘릴 위험이 있기 때문에 조심스럽다.

 

이러한 문제점을 해결할 수 있는 것이 바로 char*이다.

 

예를들어 char *s2 = "hello" 이렇게 초기화를 했다면, s2에는 hello라는 문자열이 저장된 메모리의 첫 주소값이 저장된다.

 

#include <stdio.h>

int main() 
{
	char *s2 = "hello";
	print("%d\n", s2);
}

 

이렇게 s2를 int형으로 출력시키면 

 

다음과 같은 결과값이 나온다.

 

즉, hello라는 문자열이 저장된 메모리의 주소값이 4210688이라는 것이다.

 

 

#include <stdio.h>

int main() 
{
	char *s2 = "hello";
	print("%s\n", s2);
}

 

그렇다면 s2, 즉 hello라는 문자열이 저장된 메모리의 주소값을 %s로 출력시키면 어떻게 될까?

 

문자열인 hello가 출력된다.

 

 

이를 그림으로 간단히 표현해보면,

 

이렇게 표현할 수 있다.

 

그렇다면, printf("%s", s2+1); 이렇게 입력한다면 결과값은 어떻게 될까?

 

s2 + 1은 "hello" 중 "e"의 주소값이므로 "ello" 가 출력이 된다.

 

참고로, 이렇게 문자열의 리터럴 주소가 할당된 포인터는 쓰기가 불가능하다.

 

그래서 scanf 같은 함수로 문자열을 받아오는 것도 불가능하다.

 

이럴때는 malloc을 사용하여 미리 메모리를 할당해주면, 쓰기도 가능해지므로 참고하길 바란다.

 

 

 

오늘의 내용을 정리를 해보면,

 

  1. 여러가지 문제들(특히 메모리 문제) 때문에 문자열을 다룰때는 char * 를 많이 쓴다.

 

  2. 문자열의 주소의 시작값을 %s로 출력시키면 문자열이 출력된다.

 

위 내용은 공부하며 정리한 것으로, 오류가 있을 수 있습니다