본문 바로가기
문법관련/C

12.1 문자열과 포인터

by print_soo 2024. 6. 26.

컴파일러가 문자열을 처리하는 방식

  1. 문자열을 별도의 메모리 공간에 따로 저장해둔다.
  2. 첫 번째 문자의 메모리 공간의 주소를 100이라고 치면 문자열이 사용된 위치에는 100을 치환을 해서 사용한다.

이를 증명하는 예시는 아래와 같다.

#include <stdio.h>

int main() {

    printf("%c", *"apple");

    return 0;
}

//결과
//a

apple을 간접 참조 연산자를 달아서 출력하면 * (첫 번째 문자 주소) 이와 같이 되기 떄문에 첫 번째 문자인 a가 출력된다.

 

 

응용편1

#include <stdio.h>

int main() {

    printf("%c", *("apple" + 1));

    return 0;
}

//결과
//p
// [풀이]

100 101 102 103 104 105 
 [ a | p | p | l | l | e ]
 
 100 + 1 == 100 + (1 * char의 바이트수) == 101

 

 

응용편2

#include <stdio.h>

int main() {

    char *cp = "apple";

    while( *cp!='\\0' ) {
        printf("%s\\n", cp);
        cp++;
    }

    return 0;
}

//결과
//apple
//pple
//ple
//le
//e

 

// [풀이]

🔻
100 101 102 103 104 105 
 [ a | p | p | l | l | e | \\0 ]
 
apple출력

    🔻
100 101 102 103 104 105 
 [ a | p | p | l | l | e | \\0 ]
 
pple출력

        🔻
100 101 102 103 104 105 
 [ a | p | p | l | l | e | \\0 ]
 
ple출력

            🔻
100 101 102 103 104 105 
 [ a | p | p | l | l | e | \\0 ]
 
le출력

                    🔻
100 101 102 103 104 105 
 [ a | p | p | l | l | e | \\0 ]
 
e출력

 

 

이렇게 문자열을 포인터 변수에 저장해서 사용하는 이유는?

→ 배열 없이 문자열을 변경할 수 있기 때문이다.

 

#include <stdio.h>

int main() {

    char *cp = "apple";

    printf("%s\\n", cp); //apple

    cp = "banana";

    printf("%s\\n", cp); // banana

    return 0;
}

 

 

다만 아래와 같이 scanf로 입력받아서 값을 변경할 수는 없다.

#include <stdio.h>

int main() {

    char *cp = "apple";

    scanf("%s", cp);

    printf("%s", cp);
}

 

그 이유는 cp(포인터 변수)는 변수로서 다른 주소를 가르키도록 변경할 수 있지만, 그 주소가 가르키는 문자열은 읽기 전용 메모리 영역에 저장되어 있기 때문에 수정할 수 없다.

 

따라서 바꿀 수 있는 문자열을 원한다면 char 배열을 사용해야한다.


 

scanf 함수를 사용한 문자열 입력

 

#include <stdio.h>

int main() {

    char str[80];

    printf("문자열 입력 : ");
    scanf("%s", str); //배열 자체가 첫 번쨰 공간의 주소 값이기 때문에 &은 필요없다
    printf("입력된 단어 : %s", str);
}

// 결과
// 문자열 입력 : apple jam
// 입력된 단어 : apple

scanf로 %s를 사용했을 떄의 단점이 있는데 입력중 공백을 입력하면 공백 전 단어만 배열에 저장이 된다.

따라서 이 단점을 해결하는 것이 바로 gets 함수이다.


 

gets 함수를 사용한 문자열 입력

#include <stdio.h>

int main() {

    char str[80];

    printf("문자열 입력 : ");
    gets(str); 
    printf("입력된 단어: %s", str);
}

// 결과
// 문자열 입력 : apple jam
// 입력된 단어 : apple jam

gets함수: 공백까지 입력가능한 함수

하지만 이 함수에도 단점이 있는데 정해진 메모리 이상의 입력량도 제한없이 버퍼에 계속 저장한다.

따라서 이 단점을 보안한 함수가 있는데 바로 fgets 함수이다.


 

fgets 함수를 사용한 문자열 입력

#include <stdio.h>

int main() {

    char str[80];

    printf("문자열 입력 : ");
    fgets(str, sizeof(str), stdin);

    printf("입력된 단어: %s", str);

    return 0;
}

fgets 함수에는 3가지 인자가 있다.

  1. 배열명
  2. 배열의 크기
  3. 표준입력

'문법관련 > C' 카테고리의 다른 글

13. 변수  (0) 2024.07.04
12.2 문자열 연산함수  (0) 2024.06.27
11.3 getchar(), putchar()  (0) 2024.06.26
11-2. 버퍼를 이용하는 입력 함수  (0) 2024.06.25
11-1. 아스키코드  (0) 2024.06.25