프로그래밍 언어/C

[C언어] 문자열 포인터와 문자열 배열 차이 정리

happy_life 2022. 8. 13. 11:57

C언어에는 문자열을 다루기 위해 문자열 포인터를 사용하거나 문자열 배열을 사용합니다. 이 둘은 비슷한 것같지만 다르므로 명확히 구분해 이해해야합니다. 문자열 포인터은 특정 포인터에 문자열의 주소를 저장한 것이고, 문자열 배열은 문자를 배열의 형식으로 저장한 것입니다.

 

 

문자열 포인터와 문자열 배열의 개념

char name[5] = "1234"; // 문자열 배열
const char* str = "yahoo"; // 배열 포인터

문자열 배열은 말그대로 문자를 배열의 형식으로 저장한 것을 말한다. 특히 문자열 배열은 포인터 상수와 동일하다. 포인터 상수이기 때문에 메모리의 위치를 바꿀 수 없는데 이는 특징에서 자세히 설명한다.

 

문자열 포인터는 특정 포인터에 문자열의 주소를 저장한 것이다.

 

 

문자열 포인터와 문자열 배열의 특징

문자열 배열 도식화

 

 

① 문자열 배열

1. 선언과 초기화를 따로하는 경우 직접 값을 대입하는 것이 불가능하다.

 

할당 시 에러

 

위의 코드는 expression must be a modifiable lvalue 에러가 난다. 이는 올바른 문자열 사용을 위해 반드시 이해해야 하는데, 왜 나는지는 아래에 설명한다.

먼저 앞서, 문자열 배열은 포인터 상수라고 하였다. 그렇기 때문에 값을 저장하는 주소를 변경할 수 없다. 위의 코드는 "1234"라는 문자열 리터럴 상수를 생성하고, 그 주소를 name이라는 포인터 상수에 넣으려고 하는 것이다. "1234"라는 문자열 리터럴 상수의 새로운 주소변하지 않는 포인터 상수에 넣으려고 하니 에러가 발생하는 것이다. 이를 해결하기 위해서는 strcpy()를 사용해야 한다.

 

*strcpy()의 동작

strcpy()는 그럼 어떻게 동작하길래 이 문제를 해결할 수 있는지 알아보자. "1234"라는 메모리 주소를 순서대로 역참조하면서 포인터 상수의 주소에 하나씩 값을 매핑해주는 것이다.

 

● strcpy() 코드

char* strcpy(char* dest, const char* src)
{
	char* tmp = dest;

	/*
	 * src 가 null byte 일때까지 dest에 한자씩 복사한 후 리턴합니다.
	 */
	while ((*dest++ = *src++) != '\0')
		/* nothing */;
	return tmp;
}

 

문자열 배열에 할당 하는 코드예제

char name2[5];
strcpy(name2, "1234");
printf("name2: %s\n", name2);

 

 

 

② 배열 포인터

배열 포인터 도식화

 

 

특정 포인터에 문자열 리터럴 상수의 주소를 저장한 것이다. 문자열 리터럴 상수란 메모리의 주소가 따로 지정되어 변하지 않는 문자열을 의미한다.

 

1. 선언과 초기화를 따로하는 경우 직접 값을 대입하는 것이 가능하다.

앞서 문자열 배열에서는 불가능하였지만, 배열 포인터에서는 가능하다. 왜그럴까?

에러X

 

 

"1234"라는 새로운 문자열 리터럴 상수의 주소를 str에 대입하는 것이다. 도식화한 그림으로 이해하는 것이 더 빠르다. 아래의 그림을 보자.

주소 대입

 

str은 포인터이기 때문에 다른 문자열 리터럴의 주소를 가리킬 수 있다. 따라서 값을 대입할 수 있는 것이다.

 

 

2. 포인터 연산이 가능하다.

++ 같은 연산을 할 수있다. 아래의 코드를 보자.

 

코드 예제

 

int main(void) {
	
	const char* str = "yahoo"; // 문자열 리터럴 상수를 참조하는 str 포인터
	printf("str: %s\n", str);
	str++;
	printf("str : %s\n", str);

	return 0;
}

 

결과값

 

이를 사진으로 이해하면 아래와 같다. 기존에 y위치를 처음으로하여 쭉 문자열 리터럴 상수를 읽었다면, str++연산으로 인해 그 다음 주소인 a부터 쭉 문자열 리터럴 상수를 읽게되는 것이다.

연산 후 문자열 포인터