티스토리 뷰

BackEnd/C

[13일차] 배열과 포인터

JINSUKUKU 2021. 2. 23. 22:35

2021.02.23.화

배열의 주소

✔  배열은 같은 자료형의 변수를 메모리를 연속으로 할당한다.

✔  그러므로 배열의 요소들은 일정한 간격으로 주소를 갖게 되는데, 이는 자료형의 크기와 같다.

✔  만약 배열 arr가 100번지부터 할당된다면, arr[0]은 100~103번지를 가지고 arr[1]은 104~107번지를 가진다.

✔  배열의 요소는 위와같이 자료형과 같은 크기의 공간을 할당받게되고, 그 첫번째 공간의 주소가 곧 요소의 주소가 된다.

✔  그리고 배열은 할당 받은 전체 공간의 첫번째 메모리의 주소를 가지게 된다.

✔  결국 배열의 첫번째 요소의 주소를 알게되면, 배열의 주소뿐만 아니라 다른 요소의 주소도 쉽게 알 수 있다.

#include <stdio.h>

int main(void){
  int arr[3];
  
  printf("배열의 주소 : %p\n", arr);
  printf("첫번째 요소의 주소 : %p\n", &arr[0]);
  printf("두번째 요소의 주소 : %p\n", &arr[1]);
  printf("세번재 요소의 주소 : %p\n", &arr[2]);
}

✔ 주소를 출력할 수 있는 형식지정자 %p와 주소연산자 &를 사용해서 배열과 배열의 요소들의 주소를 확인할 수 있다.

✔ 배열명은 곧 주소를 의미하므로 주소연산자 & 가 필요 없다.

주소를 확인하면 요소의 주소가 자료형의 크기만큼 차이가 발생하는 것을 확인할 수 있다.

 

 

 주소값의 연산
주소 ± 정수 → 주소 ± (정수*변수 자료형의 크기)

✔  주소는 자료형의 크기만큼 차이를 가지므로, 주소를 연산하여 배열의 다음 요소에 접근할 수 있지 않을까?

✔  매 번 자료형의 크기만큼 주소 값에 더하거나 뺄 수 없으므로, 주소의 연산은 위와 같은 방식으로 진행된다.

int arr[3] = { 1, 2, 3 };

*(arr + 0) == arr[0] //1
*(arr + 1) == arr[1] //2
*(arr + 2) == arr[1] //3

✔ 배열 자체의 주소에 1을 더했다는 것은 사실 1*변수 자료형의 크기임으로

배열의 주소를 100이라고 가정했을 때, 100 + ( 1 * 4byte ) 가 된다. 즉 arr[1]의 주소인 104가 된다.

이렇게 주소값의 연산과 간접 참조 연산자 *을 사용해 배열의 다른 요소에 접근할 수 있다.

주소값의 뺄셈도 같은 원리로 진행된다.

int arr[3] = { 1, 2, 3 };
int *p = &arr[2];

*(p - 0) == arr[2] //3
*(p - 1) == arr[1] //2
*(p - 2) == arr[0] //1

✔ 만약 소괄호가 없다면, 간접 참조 연산자 * 을 사용해 접근한 주소에 저장된 값과 연산이 되므로 주의하자.

int arr[3] = { 1, 2, 3 };
int *p = &arr[2];

*p - 0 == 1 - 0  //1
*p - 1 == 1 - 1  //0
*p - 2 == 1 - 2  //-1

 

 

배열명의 역할을 하는 포인터
int arr[3] = { 1, 2, 3 };
int *p = arr;

p[0] == arr[0]
p[1] == arr[1]
p[2] == arr[2]

 배열명은 곧 주소를 의미하므로 포인터에 저장할 수 있고, 이런 경우는 대괄호를 사용해 배열과 같이 표현할 수 있다.

✔ 배열과 같이 표현할 수 있으므로 for문을 사용해 배열의 요소에 접근할 수 있다.

#include <stdio.h>

int main(void)
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	int * p = arr;
	for(int i=0; i<5; i++){
		printf("%d ",*(p+i));
		printf("%d \n",p[i]);
	}
	return 0;
}

/*
실행결과
1 1
2 2
3 3
4 4
5 5
*/

 

 

배열명, 포인터와 매개변수

  포인터 변수에 배열의 주소를 저장하고, 함수의 매개 변수로 받게 된다면 함수에서 main 함수의 배열의 값에 접근할 수 있다.

  하지만 배열을 직접 매개변수로 전달하는 경우에도 주소값이 전달된다.

✔  배열을 매개변수로 사용해도 포인터로 인지하는 이유는, 배열의 길이가 길어지면 저장된 값이 많아지므로 복사해 사용하는 것이 비효율적이기때문에 포인터로 인지하기로 약속했기 때문이다.

 배열을 직접 매개변수로 사용하는 것 보다 포인터를 사용하는 것을 추천한다.

  그리고 외부에서 배열의 값을 수정할 수 있는 경우, 의도치않게 값을 변경할 수 있으므로 주의하자. 

#include <stdio.h>


void test(int *p, int arr[]);


int main(void){
	int arr[3] = { 1, 2, 3 };
    int *p = arr;
    
    test(p, arr);
    
    printf("%d\n", arr[0]);	//10
    printf("%d\n", arr[1]);	//20
    printf("%d\n", arr[2]);	//3
	return 0;
}


void test(int *p, int arr[]){
	p[0] = 10;
	arr[1] = 20;
}

 

 

 

 

 

 

 

 

 

 

[참고] 한빛미디어-혼자 공부하는 C언어 유튜브 강의 / 엘리스 트랙-혼자 공부하는 C언어 / 길벗-C언어 코딩 도장 / 위키백과

'BackEnd > C' 카테고리의 다른 글

[15일차] 문자열 관련 함수의 원형  (0) 2021.02.25
[13-14일차] 문자/문자열  (0) 2021.02.25
[12일차] 포인터  (0) 2021.02.23
[11일차] 함수/배열 복습  (0) 2021.02.23
[10일차] 제어문 복습  (0) 2021.02.20
댓글
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
최근에 올라온 글
글 보관함
Total
Today
Yesterday