포인터와 배열의 차이
포인터와 배열의 차이를 알아보기 전에
먼저 배열의 이름은 무엇을 의미하는지 알아보겠습니다.
배열의 이름은 포인터입니다. 단, 값 변경이 불가능한 상수 형태의 포인터입니다.
이해를 위해 예제를 보겠습니다.
#include <stdio.h>
int main(void) {
int arr[3] = {0, 1, 2};
printf("배열의 이름: %p \n", arr);
printf("배열의 이름: %p \n", &arr[0]);
printf("배열의 이름: %p \n", &arr[1]);
printf("배열의 이름: %p \n", &arr[2]);
//arr = &arr[i]; // 컴파일 오류 발생
return 0;
}
위 코드를 통해 다음과 같은 사실들을 이끌어낼 수 있습니다.
1. &사용하면 주소값이 반환된다.
2. int형 배열을 선언하여 각 요소별로 할당된 메모리 크기는 4바이트이다.
3. 모든 배열 요소가 메모리 공간에 나란히 할당된다.
4. 배열의 이름은 첫번째 요소의 주소값을 의미한다.
5. 배열에 다른 주소값을 대입할 수 없다.
배열의 이름과 포인터 변수는 상수인지 변수인지 차이만 있을 뿐 둘 다 포인터입니다.
그래서 둘 다 [], * 연산이 가능합니다.
다음 문장을 모두 동일한 결과가 나옵니다.
int main(void)
{
int arr[3] = {11, 22, 33};
int * ptr=arr;
printf(%d\n", *(ptr+0));
printf(%d\n", ptr[0]);
printf(%d\n", *(arr+0));
printf(%d\n", arr[0]);
}
하지만 포인터와 배열의 차이도 있습니다.
네 가지를 알아보겠습니다
1 sizeof
sizeof(배열)과 sizeof(포인터)는 다른 값을 반환합니다.
sizeof(배열) : 배열의 총 크기 반환
sizeof(포인터) : 포인터의 크기 반환
int nums[3] = {34, 135, 49 };
int* ptr = nums;
size_t size1 = sizeof(nums); // 12 = 3 * 4
size_t size2 = sizeof(ptr); // 4
2 문자열 초기화
C는 C#이나 Java 처럼 문자열 자료형이 없습니다. 그래서 문자열을 표현할 때 char 배열을 만듭니다.
예로 'Friday'라는 단어를 저장한다면 총 6(+1)개의 요소를 가진 char 배열을 생성합니다.
마지막에 한 자리를 추가하는 이유는 문자열이 끝나는 지점을 알려주기 위해 '널 문자(Null character)'를 넣기 위해서 입니다.
널문자: 값은 0으로 '\0' (백 슬래시(\)와 0을 합쳐서 표현)
■ 배열로 초기화하는 경우
- 데이터가 스택메모리에 저장되어 후에 문자열 수정 가능합니다 .
■ 포인터 변수로 초기화하는 경우
- 포인터 변수는 스택에, 실제 문자열은 데이터 섹션에 저장되어 후에 문자열 수정 못합니다.
- 문자열이 읽기 전용이 됩니다.
참고 이미지
- 문자열을 배열로 초기화하는 경우
- 문자열을 포인터 변수로 초기화하는 경우
3 대입
포인터 변수에 값을 대입할 수 있으나( = 주소 값 변경 가능)
배열은 한 번 만들면 고정되어 다른 주소로 바꿀 수 없습니다.
char str1[] = "My String";
char* str2 = "Your String";
str1[0] = 'O'; //문자열 변경 가능
str2[0] = 'X'; //문자열 변경 불가능
4 포인터 산술 연산
포인터는 산술 연산 가능
배열은 산술 연산 불가능
그래서 배열의 주소를 증가하거나 감소하고 싶다면
포인터에 배열의 주소를 대입 후 그 포인터 변수를 증가/감소하면 됩니다.
++pointer;
--pointer;
pointer += 1;
pointer -= 1;
++array; //컴파일 오류
--array; //컴파일 오류
array += 1; //컴파일 오류
array -= 1; //컴파일 오류
-----------------------------------
-----------------------------------
'컴퓨터 공학 > C, C++' 카테고리의 다른 글
[ C ] 포인터 이해하기5_값과 주소를 보호하는 const/const 읽는 방법 (387) | 2020.07.19 |
---|---|
[ C ] 포인터 이해하기4_값에 의한 전달 vs 참조에 의한 전달/from 윤성우 or 포프 (389) | 2020.07.18 |
[ C ] 포인터 이해하기2_참조와 역참조/ 역 참조 연산자 * (611) | 2020.07.18 |
[ C ] 포인터 이해하기1_포인터 변수란?/선언 방법 / & 연산자 (393) | 2020.07.17 |
[ C ] 메모리 이해하기11_동적 메모리의 소유권 문제 (398) | 2020.07.17 |
댓글