본문 바로가기
Language&Framework&Etc/C

포인터와 배열! 함께 이해하기(13-3) 상수 형태의 문자열을 가리키는 포인터

by 머리올리자 2020. 12. 8.

두 가지 형태의 문자열 표현

1. 배열을 기반으로 하는 '변수 형태의 문자열' 선언 

char str1[] = "Hello"; → 배열 길이 자동 계산

 

2. 포인터 기반으로 문자열 선언

char* str2 = "No thanks";

  • 2와 같이 선언하면 메모리 공간에 문자열 "No thanks"이 저장
  • 문자열의 첫 번째 문자 N의 주소값이 반환.
  • 그 반환 값이 포인터 변수 str2에 저장.
  • str2를 char형 포인터로 선언.

그렇다면 위의 두 문자열 선언의 차이점?

 

[str1] 은 그 자체로 문자열 전체를 저장하는 배열,

[str2] 는 메모리상에 자동으로 저장된 문자열 "Your String"의 첫 번째 문자를 단순히 가리키고만 있는 포인터 변수

 

다만 배열 이름 str1이 의미하는 것도 실제로는 문자 M의 주소 값이기 때문에 str1도 str2도 문자열의 시작 주소 값을 담고 있다는 측면에서는 동일.

 

다음의 차이가 있음

"배열이름 str1은 계속해서 문자 M이 저장된 위치를 가리키는 상태이어야 하지만

 배열이름 str2는 다른 위치를 가리킬 수 있다"

 

왜냐? → str2가 변수 형태의 포인터이기 때문에(배열이름 str1은 상수 형태의 포인터)

#include <stdio.h>

int main(void)
{
	char* str = "My team";
	str = "You know you can\'t fuxx with my team";

	printf("%s\n", str);

	
}

 

2020-12-08 확인결과 변수형태의 문자열도 가리키는 상태를 바꿀 수 있다.

#include <stdio.h>

int main(void)
{
	/* 변수 형태의 문자열 */
	char bp[] = "boring pointer";
	char* pbp = bp;

	printf("%p\n", pbp);

	char fp[] = "fuxxin pointer";
	/* 포인터 변수 변경 */
	pbp = fp;
	
	/*변경된 값 출력*/
	printf("%c\n", pbp[0]);



	/*상수 형태의 문자열*/
	char* pstr1 = "Who the fuxx are you";
	printf("%c\n", pstr1[0]);

	/* 포인터 변수 변경 */
	pstr1 = "Go fuxx yourself";

	/*변경된 값 출력*/
	printf("%c\n", pstr1[0]);
}

 

1. 변수 형태의 문자열(값의 변경이 가능함)

char str1[] = "Boaring pointer";

 

2. 상수 형태의 문자열(값의 변경 불가)

char* str2 = "fuxxin pointer"

 

예제

#include <stdio.h>

int main(void)
{
	char str1[] = "Bro";  // 변수 형태의 문자열
	char* str2 = "Man";   // 상수 형태의 문자열
	printf("%s %s \n", str1, str2);

	str2 = "ther"; // 가리키는 대상 변경
	printf("%s %s \n", str1, str2);

	str1[0] = 'X';  // 문자열 변경 성공
	str2[0] = 'X';  // 문자열 변경 실패
	printf("%s %s \n", str1, str2);

	return 0;
}

  • 컴파일은 됨
  • 하지만 실행시 문제가 발생
  • 선언된 문자가 상수 형태의 문자열이기 때문에
  • 일부 컴파일러는 상수 형태의 문자열의 연산을 허용함
  • 그러나 모든 컴파일러에서 동작하는 코드가 아니기 때문에 주의해야 함
  • 상수 형태의 문자열은 그 값을 변경시키지 않아야 한다.

어디서든 선언할 수 있는 상수 형태의 문자열

char* str = "Const String";

1. 이렇게 상수 형태의 문자열을 정의

2. 문자열이 메모리 공간에 저장

3. 그 메모리의 주소 값이 반환됨

4. 문자열이 0x1234번지에 저장되었다고 가정하면

5. 다음의 형태로 됨

char* str = 0x1234;

6. 포인터 변수 str에는 문자열 주소 값 0x1234가 저장되는 것임.

 

그렇다면 printf 출력 과정에서 선언되는 문자열 처리는?

printf("boaring pointer")

이 경우도 마찬가지

printf("0x1234")

이렇듯 printf 함수는 문자열을 통째로 전달받는 함수가 아닌, 문자열의 주소 값을 전달받는 함수

 

함수 호출문은?

fuxxyou("man") // fuxxyou라는 이름의 함수호출

이는 매개변수 선언이 아래와 같음을 짐작할 수 있음

void fuxxyou(char* str) // 반환형 void라고 가정

참고 : [윤성우 열혈 C 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.

 

 

2020-12-11 내용 추가

#include <stdio.h>

int main()
{
    char c1 = 'a';         // 변수에 문자 'a' 저장
    char *s1 = "Hello";    // 포인터에 문자열 "Hello"의 주소 저장

    printf("%c\n", c1);    // a: %c로 문자 출력
    printf("%s\n", s1);    // Hello: %s로 문자열 출력

    return 0;
}

문자(char)는 'a' 처럼 글자가 하나만 있는 상태를 뜻하고

문자열(char* )은 "Hello" 처럼 글자가 여러 개가 계속 이어진 상태

 

즉, 문자는 1바이트 크기의 char에 저장할 수 있지만, 문자열은 크기가 1바이트를 넘어서므로 char에 저장할 수 없음

→ 따라서 문자열은 변수에 직접 저장하지 않고 포인터를 이용해서 저장

 

 

 

내용 추가 참고 : dojang.io/mod/page/view.php?id=328 - 공부 정리 목적으로 참고