사이먼's 코딩노트

[C언어] 공공재 / strcpy 본문

C언어

[C언어] 공공재 / strcpy

simonpark817 2024. 2. 19. 16:29

[공공재 지역]

[case #1]

#include <stdio.h>

int main() {

    char* str1 = "abc";
    char* str2 = "abcd";
    char* str3 = "abc";

    printf("str1 : %ld\n", (long)str1);
    printf("str2 : %ld\n", (long)str2);
    printf("str3 : %ld\n", (long)str3);

    return 0;
}
  • 위 코드에서 str1은 4바이트 짜리 '문자열(문자배열)' 상수를 생성한다.
  • 단, 해당 문자열 abc는 '공공재'만 저장되는 메모리의 특수한 구역에 저장된다.
  • '공공재' 라고 표현한 이유는 "abc"는 2번 이상 쓸 때부터는 문자열이 새로 생성되지 않고 기존에 생성된 배열의 시작 주소를 리턴하기 때문이다.
  • 실제로 str1에서 "abc"가 생성되면 str3에서의 "abc" 는 새로 생성되지 않고 공공재 지역에 있던 "abc"를 끌어와서 저장한다.
  • str2의 "abcd" 는 공공재 지역에 이미 생성된 이력이 없기 때문에 5바이트 짜리 문자열을 새로 생성하게 된다.
  • 출력문을 통해 str1, str2, str3 배열의 첫번째 주소를 출력해보면 str1과 str3의 주소는 같은 공공재 지역의 "abc" 문자열을 가지고 있기 때문에 동일하다.
  • str1의 주소가 4202500 라면 str3의 주소도 4202500이고, str2의 주소는 str1의 주소와 4 차이가 나게된다.
  • str2의 "abcd" 문자열은 새로 생성되어야 되기 때문에 str1에서 먼저 만들어진 "abc"의 4바이트(널문자 포함) 뒤에 4202504 주소가 생성된다.

 

[case #2]

#include <stdio.h>

int main(void) {
    // 지역 전체의 값을 수정해줘야한다.
    char* str1;  // 4바이트 배열
    str1 = "abc";
    str1 = "def";

    // 지정된 배열부분만 하나씩 수정이 가능
    char str2[4];        // 4바이트 배열
    str2[0] = 'a';
    str2[1] = 'b';
    str2[2] = 'c';
    str2[3] = '\0';

    str1[1] = '!';
    str2[1] = '!';

    printf("str1[0] : %c\n", str1[0]);
    printf("str2[0] : %c\n", str2[0]);

    printf("str1 : %s\n", str1);
    printf("str2 : %s\n", str2);

    return 0;
}
  • 공공재 지역에 "abc"를 저장한 str1이 있고, 배열 타입으로 "abc"를 저장한 str2이 있다.
  • 각각 저장된 문자열을 사용자 지정에 맞게 수정하기 위해선 위 코드와 같이 실행하면 된다.
  • str1의 경우 각 배열의 주소를 일일이 찾아가서 str1[0] = 'b' 같이 바꾸는 것이 통하지 않는다. 그 이유는 이미 공공재 지역에 해당 문자열을 저장해 놨기 때문에 지정된 배열 부분만 수정이 되지 않고 공공재 지역의 전체 문자열을 수정해줘야 한다.
  • str1 = "def"와 같이 전체를 수정해줘야 문자열이 수정된다.
  • str2의 경우 배열 타입으로 문자가 저장되어 있기 때문에 str2[1] = '!' 같이 바꾸는 것이 통한다.
  • 위 코드를 실행해보면 출력문에 통해 출력되는 문자와 문자열은 다음과 같다. (d, a, def, a!c)
  • str1은 "def"로 수정되었고, str1[1] = '!' 은 문법상 실행되지 않기 때문에 str1[0]은 d가 출력된다. str1 전체를 출력하면 def가 출력된다.
  • str2는 "abc"로 세팅되었고 str2[1] = '!'로 두 번째 배열의 문자를 수정하였기 때문에 str2[0]은 a가 출력되고 str2 전체를 출력하면 a!c가 출력된다.

 

[strcpy]

#include <stdio.h>
#include <string.h>

int main(void) {

    char* str1 = "abc";
    char str2[] = "abc";

    str1 = "bcd";
    strcpy(str2, "bcd");

    printf("str1 : %s\n", str1);
    printf("str2 : %s\n", str2);

    return 0;
}
  • 공공재 지역에 "abc"를 저장한 str1이 있고, 배열 타입으로 "abc"를 저장한 str2이 있다.
  • 각각 저장된 문자열을 "abc"에서 "bcd"로 변경하고 싶다면 위 코드와 같이 실행하면 된다.
  • str1의 경우 각 배열의 주소를 일일이 찾아가서 str1[0] = 'b' 같이 바꾸는 것이 통하지 않는다. 그 이유는 이미 공공재 지역에 해당 문자열을 저장해 놨기 때문에 지정된 배열 부분만 수정이 되지 않고 공공재 지역의 전체 문자열을 수정해줘야 한다.
  • str1 = "bcd"와 같이 전체를 수정해줘야 문자열이 수정된다.
  • str2의 경우 배열 타입으로 문자가 저장되어 있기 때문에 str2[0] = 'b' 같이 바꾸는 것이 통한다.
  • 하지만 한 번에 배열 안에 문자들을 변경하고 싶을 때는 위 코드처럼 strcpy() 문법을 사용할 수도 있다.
  • strcpy()를 사용하기 위해서는 #include <string.h>를 반드시 작성해줘야한다.

 

[문제]

  • 다음은 name1, name2, name3의 선언부분에서 총 몇 바이트의 메모리를 사용하는지 설명하세요.
#include <stdio.h>
#include <string.h>

int main(void) {
    
    char* name1 = "abc";
    printf("name1 : %s\n", name1);

    char name2[10] = "bbc";
    printf("name2 : %s\n", name2);

    char name3[10] = "bbc";
    printf("name3 : %s\n", name3);

    return 0;
}

 

1. name1

  • name1은 포인터 변수로 8바이트를 사용하고, "abc"는 널문자를 포함하여 4바이트를 사용하고 해당 문자는 공공재 지역에 저장된다.
  • 총 12 바이트를 사용한다.

2. name2

  • name2은 포인터 변수로 8바이트를 사용하고, "bbc"는 널문자를 포함하여 4바이트를 쓰지만 추가로 name2[10]로 배열의 크기가 지정되어 있기 때문에 10바이트를 더 사용한다. 해당 문자 "bbc" 도 역시 공공재 지역에 저장된다.
  • 총 22 바이트를 사용한다.

3. name3

  • name3은 포인터 변수로 8바이트를 사용하고, "bbc"는 이미 name2를 통해 공공재 지역에 저장되어 있기 때문에 따로 name3에서는 메모리를 쓰지 않는다. 추가로 name3[10]로 배열의 크기가 지정되어 있기 때문에 10바이트를 사용한다.
  • 총 18 바이트를 사용한다.
반응형

'C언어' 카테고리의 다른 글

[C언어] 포인터&배열 문제풀이(2)  (0) 2024.02.19
[C언어] 포인터&배열 문제풀이(1)  (0) 2024.02.19
[C언어] define / typedef / 문자 배열  (2) 2024.02.19
[C언어] scanf  (0) 2024.02.14
[C언어] 배열  (2) 2024.02.08