컴공과컴맹효묘의블로그

C언어 포인터와 배열에 대한 쉬운 설명 본문

컴퓨터/C언어

C언어 포인터와 배열에 대한 쉬운 설명

효묘 2019. 8. 17. 14:58
반응형
포인터와 1차원 배열

C언어에서의 배열 변수는 사실 포인터 입니다. 값이아닌 주소를 가리키고 있습니다.

#include<stdio.h>
int main(){
	int array[3]={10,20,30};
    printf("%x %x %x\n", &array[0], array, array+0);//&array[0]==array==array+0
    printf("%x %x\n",&array[1], array+1);
    
    return 0;
}

실행결과

62fe10 62fe10 62fe10
62fe14 62fe14

위 코드는 array[0]의 주소가 어디에 있는지 알려줍니다. 코드를 보시면, &array[0]==array==array+0 임을 알 수 있습니다. 세 개의 표현 모두 같은 주소를 가리키고 있으므로, 세 개의 코드는 모두 같은 표현이라고 볼 수 있습니다.

 

 

 

 

 

 

그리고, array는 포인터와 비슷하게 작동함을 알 수 있습니다.

이 주소들이 각각 무엇을 가리키는지 보도록 하죠.

 

주소에 저장되어있는(참조) 값을 알기위해서는 * 연산자가 필요합니다.

*&array[0]==*array==*(array+0) == array[0]

 

#include<stdio.h>
int main(){
	int array[3]={10,20,30};
    printf("%x %x %x\n", &array[0], array, array+0);
    printf("%d %d %d\n", *&array[0], *array, *(array+0));
    printf("%x %x\n",&array[1], array+1);
    
    return 0;
}

실행결과

62fe10 62fe10 62fe10 
10 10 10
62fe14 62fe14

모두 같은 값을 참조한다는것을 알 수 있습니다.

 

그리고 array는 int형 배열이므로, array와 array+1은 4바이트가 차이납니다.

 

 

 

 

 

 

이번에는 배열 주소의 크기를 알아보겠습니다.

#include<stdio.h>
int main(){
	int array[3]={10,20,30};
	//64bit 환경에서 모든 자료형 포인터의 크기는 8바이트 (==64bit)
    printf("%d %d %d\n",sizeof(array), sizeof(array+0), sizeof(&array[0]));
    
    return 0;
}

실행결과

12 8 8

array, array+0, &array[0]이 모두 같은 뜻인줄 알았는데, 다른 결과가 나왔습니다.

 

참고로 주소의 크기는 64bit 환경 기준으로 모두 8바이트 입니다. (32bit는 4byte)

 

아무튼 주소의 크기가 다 다르게 나온 이유는, array는 &array[0]이나 array+0과 다르게 배열 전체의 주소를 가리키기 때문입니다. 

 

따라서 array는 배열 전체 크기인 4x3=12(int크기 * 배열원소개수)바이트, 나머지는 배열의 한 원소에 대한 주소인 8바이트를 가지고 있습니다.

 


 

 

 

포인터로 배열에 접근하기

포인터로 1차원 배열에 접근할 수 있습니다. 그리고 제가 함수로 배열을 받아야 할 때 자주 사용하는 방법이기도 합니다.

 

#include<stdio.h>
int main(){
	int array[3]={10,20,30};
	int* p=NULL;
	
	p=array;
	
	printf("%d %d %d\n",p[0], *p, *(p+0));
	printf("%d %d\n",p[1], *(p+2));
	printf("%d\n",p[10]);
	 
    return 0;
}

실행결과

10 10 10
20 30
4199400

int형 포인터로 p를선언해주고, p=array를 해줍니다. 그리고 array의 주소를 가진 포인터 변수 p는 배열처럼 행동할 수 있습니다. p[10]과 같이 정의된 배열 범위를 나가면, 쓰레기값이 들어오기도 합니다.

 

 

 

 

 

#include<stdio.h>
int main(){
	int array[3]={10,20,30};
	int* p=NULL;
	
	p=array+1;
	
	printf("%d %d %d",p[-1], p[0], p[1]);
	 
    return 0;
}

실행결과

10 20 30

포인터로 배열을 받을 때 주소 가감산을 하여 응용을 할 수도 있습니다.

 

포인터를 이용해서 배열을 받을 때에는, 메모리공간을 줄일 수 있다는 큰 장점이 있습니다. 포인터를 사용하지 않고, 배열을 복사하려면 같은 크기의 배열을 하나 더(혹은 더 많이) 만들어야하는데, 포인터 변수는 큰 공간을 차지하지 않고도 많은 기능을 수행할 수 있습니다.

 

#include<stdio.h>
int main(){
	int array[3];
	int* p=NULL;
	
	p=array;
	*p=10;
	printf("%d %d %d\n",p[0], p[1], p[2]);
	
	p=p+1;
	*p=20;
	printf("%d %d %d\n",p[-1],p[0],p[1]);
	
	p=p+1;
	*p=30;
	printf("%d %d %d\n",p[-2],p[-1],p[0]);
	
    return 0;
}

실행결과

10 0 35
10 20 35
10 20 30

이런식으로 자기 자신에 주소를 가감산해서 응용할 수도 있습니다.

 

 

 

이번 포스팅은 여기까지하고 다음에는 포인터와 2차원 배열에대해 써보도록 하겠습니다.

반응형
Comments