본문 바로가기
Language&Framework&Etc/C

포인터와 배열! 함께 이해하기(13-1) 포인터와 배열의 관계

by 머리올리자 2020. 12. 7.

배열 이름도 포인터!

배열의 이름은 무엇을 의미하는가?

  • 배열의 이름은 포인터다
  • 그 값을 바꿀 수 없는 '상수 형태의 포인터' 이다.
#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]);
	return 0;

}

 

 

"int형 배열요소간 주소 값의 차는 4바이트다"

 

"모든 배열요소가 메모리 공간에 나란히 할당된다"

 

위 그림과 같이 배열이 할당되었다

"배열의 첫 번째 바이트의 주소 값이 0x0116F6D4인데, 배열의 이름을 출력한 결과도 이와 같다."

"배열의 이름은 배열의 시작 주소 값을 의미하며, 그 형태는 값의 저장이 불가능한 상수"

 

비교조건                           비교대상 포인터 변수 배열의 이름
이름이 존재하는가? 존재한다 존재한다
무엇을 나타내거나 저장하는가? 메모리 주소 값 메모리 주소 값
주소 값의 변경이 가능한가? 가능하다 불가능하다

배열의 이름은 '상수 형태의 포인터'

배열의 이름을 가리켜 '포인터 상수'

 

"배열의 이름도 포인터이기 때문에 배열의 이름을 피연산자로 하는 * 연산이 가능"

 

1차원 배열이름의 포인터 형과 배열이름을 대상으로 하는 * 연산

"1차원 배열이름의 포인터 형은 배열의 이름이 가리키는 대상을 기준으로 결정하면 된다"

 

int arr1[10] -> (int* )

double arr2[30] -> (double *)

 

#include <stdio.h>

int main(void)
{
	int arr1[3] = { 0, 1, 2 };
	double arr2[3] = { 0.1, 1.1, 2.1 };

	printf("%d %g \n", *arr1, *arr2);
	*arr1 += 100;
	*arr2 += 300;

	printf("%d %g \n", arr1[0], arr2[0]);

	return 0;
}

 

포인터를 배열의 이름처럼 사용할 수도 있다.

배열의 이름과 포인터 변수는 변수냐 상수냐의 특성적 차이가 있을 뿐, 둘 다 포인터이기 때문에 포인터 변수로 할 수 있는 연산은 배열의 이름으로도 할 수 있고, 배열의 이름으로 할 수 있는 연산은 포인터 연산으로도 할 수 있다.

#include <stdio.h>

int main(void)
{
	int arr[3] = { 0, 1, 2 };
	int* ptr = &arr[0]; // int* ptr = arr; 과 동일

	printf("%d %d \n", ptr[0], arr[0]);
	printf("%d %d \n", ptr[1], arr[1]);
	printf("%d %d \n", ptr[2], arr[2]);
	printf("%d %d \n", *ptr, *arr);

	return 0;
}

위처럼 포인터 변수를 배열의 이름처럼, 배열의 이름을 포인터 변수처럼 사용하는 경우도 거의 없다.

하지만 이런 일이 가능하다는 사실은 알고 있어야 한다.

 

 

참고 : [윤성우 열혈 C 프로그래밍] - 대부분의 내용 및 코드는 이 책에서 개인 공부 정리 목적으로 참고하였습니다.