🚀 char *name vs char name[] 메모리 관점에서의 일상 비유
💡 메모리를 "도서관"으로, 문자열을 "책"으로 비유해 볼게요!
📌 char *name (포인터 방식)
📖 도서관에서 책을 "대여하는" 방식
✔ 포인터는 책을 직접 복사하지 않고, 도서관에서 "책의 위치(참조)"만 가져옴!
✔ 즉, 같은 책을 여러 번 복사하지 않고, 원래 있는 책을 가리킴.
📝 비유 예시:
🔹 "물병자리"라는 책이 도서관에 있음.
🔹 char *name = "물병자리"; → 책을 직접 들고 오는 게 아니라, 도서관에 "어디에 있는지 주소"만 저장
🔹 모든 사람이 같은 책을 읽으려면 그냥 같은 주소를 참조하면 됨 (불필요한 복사 없음)
🚀 장점:
✔ 메모리 절약 → 같은 문자열을 여러 개 복사할 필요 없음.
✔ 빠른 접근 → 문자열을 복사하지 않고 참조만 함.
📌 char name[] (배열 방식)
📖 도서관에서 "책을 복사해서 소장하는" 방식
✔ 배열을 사용하면 문자열을 "새로운 공간"에 복사해서 저장해야 함!
✔ 즉, 도서관에서 "책을 직접 빌리는" 것이 아니라, "책을 복사해서 내 방에 보관"하는 방식.
📝 비유 예시:
🔹 "물병자리"라는 책이 도서관에 있음.
🔹 char name[] = "물병자리"; → 도서관에서 이 책을 복사해서 내 책장에 따로 보관
🔹 새로운 공간이 필요하고, 같은 책을 여러 개 복사해야 해서 메모리가 더 많이 듦.
🚨 단점:
✔ 메모리 낭비 → 같은 문자열을 여러 개 저장할 경우, 불필요한 중복 발생.
✔ 배열 크기 제한 → char name[20];처럼 크기를 미리 정해야 함.
🎯 최종 비교: 메모리 친구의 입장
방식 도서관 비유 메모리 효율 사용 용도
char *name | 도서관에 있는 책의 위치(주소)만 가져옴 | ✅ 메모리 절약 | 문자열을 공유할 때 |
char name[] | 책을 복사해서 내 방에 보관함 | ❌ 메모리 낭비 | 문자열을 수정할 때 |
💡 즉, char *name을 쓰면 같은 문자열을 여러 번 복사하지 않아도 되고, 메모리가 절약됨! 🚀
💡 하지만 char name[]을 쓰면 복사된 문자열을 직접 수정할 수 있음.
📌 정리:
✔ 메모리를 아끼고 싶다면? → char *name 사용.
✔ 문자열을 직접 수정해야 한다면? → char name[] 사용.
이제 이해되셨죠? 😃📖✨
프로그램은 만든다 했을때,
그럼 어떤 프로그램의 용도냐에 따라 char *name이거나 char name[]이 다르겠네?
보통 어떤 기준이 돼?
🚀 char *name vs char name[] 선택 기준
💡 "어떤 프로그램을 만들 것인가?"에 따라 선택이 달라집니다!
✔ 메모리를 절약해야 하는지?
✔ 문자열을 수정할 필요가 있는지?
✔ 프로그램이 다루는 데이터가 변하는지?
이런 요소에 따라 char *name과 char name[] 중 적절한 방식을 선택해야 합니다.
📌 char *name을 사용하는 경우
📖 ✅ 문자열을 변경할 필요가 없고, 중복을 피해야 하는 경우
✔ 문자열이 고정되어 있고, 여러 곳에서 재사용될 가능성이 있는 경우.
✔ 같은 문자열을 여러 개 복사하는 것은 메모리 낭비가 되므로 포인터 방식이 유리.
📌 사용 예제 (메모리 절약이 중요한 프로그램)
1️⃣ 대량의 데이터가 있는 프로그램 (예: 사전, 데이터베이스)
- 예를 들어 영어 단어 사전 프로그램에서 "Apple", "Banana", "Cherry" 같은 단어를 계속 참조해야 함.
- 단어를 매번 복사하면 메모리 낭비 → 포인터 사용 (char *name)이 적절함
struct Word {
char *name;
};
struct Word dictionary[] = {
{"Apple"},
{"Banana"},
{"Cherry"}
};
2️⃣ 고정된 문자열을 여러 곳에서 사용할 경우 (예: 로그 메시지, 메뉴 선택 등)
- "로그인 성공", "로그인 실패" 같은 문자열을 여러 곳에서 사용할 때
- 매번 복사하는 것은 불필요한 낭비!
- 고정된 문자열을 포인터로 관리하면 더 효율적임
char *messages[] = {"로그인 성공", "로그인 실패", "비밀번호 오류"};
printf("%s\n", messages[0]); // "로그인 성공" 출력
3️⃣ 입력된 문자열을 가리키는 경우 (예: 사용자 입력 처리)
- 프로그램이 사용자가 입력한 문자열을 다룰 때 → 포인터가 유리함
- char name[100]; 대신 char *name = input;으로 사용 가능
char input[100];
scanf("%s", input);
char *name = input; // 입력된 문자열을 포인터로 참조
✔ 문자열을 저장하는 것이 아니라 "어디에 저장되어 있는지 주소"만 가짐
✔ 메모리 낭비를 줄일 수 있음
📌 char name[]을 사용하는 경우
📖 ✅ 문자열을 직접 수정해야 하는 경우
✔ 문자열의 내용이 변경될 가능성이 있는 경우 → 배열 방식이 적절함
✔ 포인터를 사용하면 문자열을 수정할 수 없음 (리터럴 수정 불가)
📌 사용 예제 (문자열을 직접 수정해야 하는 프로그램) 1️⃣ 사용자가 입력한 문자열을 변경해야 하는 경우 (예: 채팅 프로그램, 텍스트 편집기)
- 사용자가 입력한 메시지를 수정해야 하는 경우, 배열이 필요함
- char *name을 사용하면 문자열을 변경할 수 없음!
char name[100]; // 사용자가 입력할 문자열을 저장하는 배열
scanf("%s", name);
name[0] = 'X'; // 첫 글자를 강제로 'X'로 변경 가능
✔ 이렇게 하면 char name[]을 사용했기 때문에 문자열을 수정할 수 있음!
✔ 하지만 char *name = "hello";였다면, name[0] = 'X'; 하면 오류 발생!
2️⃣ 버퍼를 사용해야 하는 경우 (예: 네트워크 패킷, 파일 입출력)
- 파일을 읽고 내용을 변경할 필요가 있을 때
- 네트워크에서 받은 데이터를 가공할 때
char buffer[1024]; // 파일에서 읽은 데이터를 저장할 버퍼
fgets(buffer, sizeof(buffer), file);
buffer[0] = 'A'; // 받은 데이터 일부를 수정할 수 있음
✔ 포인터(char *buffer)를 사용하면 수정이 불가능하지만, 배열은 가능!
3️⃣ 여러 개의 문자열을 따로 저장해야 하는 경우 (예: 여러 사용자 입력 저장)
- 포인터를 사용하면 기존 데이터를 덮어쓸 수 있음 → 배열을 사용하면 독립적으로 저장 가능
- 채팅 프로그램에서 여러 사용자 메시지를 저장하는 경우
char messages[3][50]; // 3개의 메시지를 저장할 배열
strcpy(messages[0], "안녕하세요");
strcpy(messages[1], "반갑습니다");
strcpy(messages[2], "C 언어 재밌어요");
✔ 각 메시지가 별도로 저장되므로, 이전 메시지가 사라지지 않음
✔ 포인터(char *messages[])를 사용하면, 같은 공간을 가리켜서 덮어쓰는 문제가 발생할 수 있음
🚀 최종 결론: 어떤 기준으로 선택해야 할까?
✔ 메모리를 절약해야 한다면? → char *name
✔ 문자열을 변경해야 한다면? → char name[]
✔ 여러 개의 문자열을 저장해야 한다면? → char name[][] (2차원 배열)
선택 기준 char *name (포인터) char name[] (배열)
문자열 수정 필요 | ❌ 수정 불가 (리터럴) | ✅ 수정 가능 |
메모리 사용 | ✅ 효율적 (중복 방지) | ❌ 메모리 낭비 가능 |
문자열 길이 | ✅ 동적 할당 가능 (malloc) | ❌ 크기 고정됨 |
사용 예시 | 사전, 로그 메시지, 메뉴 목록 | 채팅 프로그램, 네트워크 버퍼, 사용자 입력 저장 |
💡 즉, 프로그램의 특성에 맞춰 char *name과 char name[]을 적절히 선택해야 합니다! 🚀
'Study > C Language' 카테고리의 다른 글
int arr[3] = {1};가 {1, 0, 0}으로 인식되는 이유 (0) | 2025.03.08 |
---|---|
C언어에서 main() 함수 이름을 바꿀 수 있는가? (0) | 2025.03.04 |
씹어먹는 C언어 혼자 실습 (3) switch문 (0) | 2024.10.17 |
씹어먹는 C언어 혼자 실습 (2) (0) | 2024.10.16 |
씹어먹는 C언어 혼자 실습 (1) (0) | 2024.10.16 |