📌 포인터와 배열의 차이점
| 구분 | 설명 |
|------|------|
| 포인터 | 특정 메모리 주소를 저장하는 변수 |
| 배열 | 같은 타입의 데이터를 연속된 메모리에 저장하는 구조 |
| 배열 이름 | 배열의 시작 주소를 가리키는 포인터처럼 동작 |
void Test(int a)
{
a++;
}
Call by Value) a에 원본 값이 복사되어 함수 내부에서 수정해도 원본에는 영향이 없음 a++ 실행 후 함수가 종료되면 복사본이 소멸됨📌 메모리 변화
| 메모리 영역 | 변수 | 값 |
|------------|------|----|
| Stack | main의 a | 0 |
| Stack | Test의 a (복사본) | 1 |
➡ 결과적으로 원본 a 값은 유지됨 (0)
void Test(char a[])
{
a[0] = 'x';
}
a[])은 포인터로 치환(char* a)됨 📌 메모리 변화
| 메모리 영역 | 변수 | 값 |
|------------|------|----|
| Stack | test2 | "Hello World" |
| Stack | a (포인터) | test2의 시작 주소 |
➡ a[0] = 'x' 실행 후 test2의 첫 번째 문자가 'x'로 변경됨
main() 함수const char* test1 = "Hello World";
test1은 문자열 리터럴을 가리키는 포인터 .data 영역(읽기 전용)에 저장되므로 수정 불가test1[0] = 'R';을 시도하면 컴파일 오류 발생char test2[] = "Hello World";
test2[0] = 'R';
test2는 "Hello World"를 배열로 선언 (Stack 영역에 저장) "Rello World"📌 문자열 저장 방식 차이
| 변수 | 저장 영역 | 수정 가능 여부 |
|------|------|------|
| const char* test1 | .data (읽기 전용) | ❌ |
| char test2[] | Stack (변경 가능) | ✅ |
➡ 포인터(const char*)와 배열(char[])의 차이를 이해하는 것이 중요!
int a = 0;
Test(a);
cout << a << endl;
a는 값으로 전달되므로 원본이 유지됨 (출력 결과: 0)Test(test2);
cout << test2 << endl;
test2는 배열 이름(주소)으로 전달되므로 함수에서 변경 가능Test() 함수에서 test2[0] = 'x' 실행됨 → 출력 결과: "xello World"📌 배열을 함수에 전달하면 컴파일러가 자동으로 포인터로 치환
void Test(char a[]) // char[]를 받지만
void Test(char* a) // 실제로는 이렇게 처리됨
📌 함수 인자 전달 방식 비교
| 전달 방식 | 특징 | 원본 영향 |
|------|------|------|
| 값 전달 (int a) | 값 복사 | ❌ |
| 주소 전달 (char* a) | 원본 주소 전달 | ✅ |
➡ 배열을 함수로 전달할 때 값이 변경될 수 있음을 주의!
📌 포인터와 배열의 공통점
+1)을 하면 다음 원소의 주소로 이동 가능📌 포인터와 배열의 차이점
| 구분 | 포인터 | 배열 |
|------|------|------|
| 메모리 크기 | 8바이트(주소 저장) | 여러 개의 원소 저장 |
| 변경 가능 여부 | 포인터 주소 변경 가능 | 배열 이름 변경 불가 |
| 배열 복사 | 원소 복사 필요 | 직접 복사 불가 |
char* ptr = test2; // 가능
test2 = ptr; // 불가능 (배열 이름은 상수)
➡ 배열은 데이터를 저장하는 닭장🐔, 포인터는 주소를 저장하는 바구니🗑️
for (int i = 0; i < 10; i++)
{
monsters[i].hp = 100 * (i + 1);
monsters[i].attack = 10 * (i + 1);
monsters[i].defence = (i + 1);
}
monsters[i]를 통해 배열을 순회하며 데이터 초기화 for (int i = 0; i < 10; i++)
{
StatInfo& monster = *(monsters + i); // 포인터 연산
monster.hp = 100 * (i + 1);
}
➡ 배열은 인덱스(monsters[i])를 활용하면 가독성이 높아짐
int numbers1[10] = {1,2,3,4,5}; // 앞부분 초기화, 나머지는 0
int numbers2[] = {1,2,3,4,11,24}; // 크기 자동 결정
char helloStr[] = {'H','e','l','l','o','\0'}; // 널 종료 포함
➡ 배열을 초기화하지 않으면 임의의 값(쓰레기 값)이 저장될 수 있음