Study/C Language

char *name vs char name[]

imaginefuture-1 2025. 3. 8. 22:40

🚀 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[]을 적절히 선택해야 합니다! 🚀