상수 형태의 문자열을 가리키는 포인터

프로그래밍/C 2019.04.17 댓글 Plorence

배열에서도 문자열을 다룰 수 있듯이, 포인터에서도 가능합니다.

포인터에서 동적 할당을 사용하여 읽기/쓰기 전용으로도 가능하지만, '읽기' 전용이 필요한 경우에 동적 할당을 쓰지 않고 "상수 형태의 문자열"을 사용해도 됩니다.

 

문자열 시점에서 배열과 포인터가 다른 점

char str[] = "my string";
char * str2 = "Your string";

첫 번째 줄인 배열은 배열을 기반으로하는 '변수 형태의 문자열'입니다. 포인터를 기반으로 문자열을 선언하는 것도 가능합니다.
두 번째 줄인 포인터는 메모리공간을 수동으로 만들어주지 않았기 때문에 "Your string"이라는 문자열은 자동으로 할당되고
문자열의 첫문자 Y의 주소값이 반환이 되어 str2에 대입됩니다.

Y의 메모리주소가 반환이 되어 str2에 대입이 되니 이것은 str(배열)과 str2(포인터)의 특징은 같습니다.
다만 배열의이름은 상수라서 계속해서 문자 M를 지시하는 상태여야 하지만
포인터 변수 str2은 다른위치를 지시할 수 있습니다.

#include <stdio.h>
int main (void){
    char str1[] = "My string";
    char * str = "Your String";
    printf("%s %s",str1,str);
    
    str = "string";
    printf("%s",str);
    
    return 0;
}

이렇게 포인터는 대상을 바꿀 수는 있지만 배열의 이름은 상수 형태의 포인터이기 때문에 대상을 변경할 수 없습니다.
이때 상수 형태의 문자열과 상수 형태의 포인터를 혼동하시면 안 됩니다.

배열을 통해 문자열을 선언한 건 '변수 형태의 문자열' 이라고 하고
포인터를 통해 문자열을 선언한 건 '상수 형태의 문자열'이라고 합니다.

배열과 포인터로 선언된 문자열의 차이점은, 배열은 문자문자마다 변경이 가능하지만
포인터는 불가능합니다. 각각의 요소에 접근할 방법이 없기 때문입니다.

즉 자동할당된 문자열은 읽기 전용 영역에 할당된 셈입니다.

 

#include <stdio.h>
int main (void){
    char str1[] = "My string";
    char * str2 = "Your String";
    printf("%s %s",str1,str);
    
    str1[0] = 'x'; //가능
    str2[0] = 'x'; //불가능
    
    printf("%s %s",str1,str);
    
    return 0;
}

위 예제는 str2가 지시하는 문자열은 그 내용의 변경이 불가능합니다.
str1는 한문자씩 저장되어있기 때문에 가능합니다.
C에서는 상수형태의 문자열이 char [N]이지만 C++에서는 const char [N] 타입으로 반환하기 때문에 런타임 에러 방지가 가능합니다.(컴파일 타임에서 체크하기 때문)

 

상수 형태의 문자열의 처리순서

char * str = "my string";

먼저 "my string"이라는 문자열이 메모리 공간에 저장이 됩니다.

그리고 그 메모리 주소 값이 반환이 됩니다.

char * str = 0x1234;

이때 메모리 주소 값은 문자열의 첫 문자 m의 메모리 주소 값입니다.

함수의 호출도 마찬가지입니다.
큰따옴표로 묶어서 표현되는 문자열은 메모리 공간에 저장된 후 주소 값이 반환됩니다.

printf("hello world!"); --> printf(0x1234)

이것도 마찬가지로 메모리 주소 값은 문자열의 첫 문자인 h의 주소 값입니다.

실제로 전달되는 값은 문자 h의 주소 값입니다.

댓글