사이먼's 코딩노트
[C언어] 공공재 / strcpy 본문
[공공재 지역]
[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 |