이번 학기에 배우는 영상처리에서 C언어를 이용하여 작업을 진행하다가 포인터에 대한 추가적인 이해가 필요하다고 생각되어 내가 C언어에서 부족하다고 생각했던 부분들을 다시 공부해 볼 생각이다. C언어 하면 포인터이기 때문에 포인터의 기초부터 다시 리뷰해보자.
포인터란?
메모리
- 프로그램이 실행되기 위해 필요한 정보(값)을 저장하는 공간
- 1byte(8 bit) 단위로 물리 주소가 부여되어 있음
- 개념적으로, 메모리는 일렬로 연속되어 있는 크기가 1byte인 방들의 모음이라고 볼 수 있음
- 일반적으로 주소의 길이는 4bytes이고, 주소는 16진수로 표현
포인터
주소를 나타내는 특수 자료형
일반적으로 변수의 주소를 저장하며, “변수를 가리킨다”라고 표현함
주소는 숫자이므로, 기본적으로 정수로 표현됨. 하지만, int(정수형 자료형)와 구별되어 처리됨(다른 자료형)
따라서 선언할 때 포인터임을 명시해야 한다.
선언 방법 : 변수 명 앞에 *(참조연산자)만 붙이면 된다.
ex) char * pch;
int * pnum;
-> pch와 pnum은 똑같이 주소를 저장하는 변수지만 자료형이 다르므로 다른 자료형으로 취급
대입
- 포인터 (변수)에는 주소
만 대입될 수 있다. - 포인터 (변수)에 주소를 대입하여 특정 변수와 연결시키는 것을 “가리킨다”라고 표현하고, 그림에서는 화살표 ->로 표시
- 참조 연산 : 포인터 (변수)가 가리키는 변수에 접근하는 것
- 참조연산자 * (간접연산자, 포인터연산자 라고도 부름)를 사용
ex) *pch : 포인터 pch가 가리키는 변수, 0x3C번지에 저장된 값
1 | char ch = 'A', * pch; |
결과:
A 001EA03C
3 001EA042
1 |
|
결과 :
num1 = 4000 num2 = 2000 p = 004FF940
num1 = 004FF94C num2 = 004FF940 p = 004FF934
배열과 포인터
배열의 이름은 배열의 시작 주소를 의미한다. 즉, int ar[10] = {0}; 이라는 배열이 있을때 ar = &ar 과 같은 의미이다.
- 주소를 이용한 배열 참조
배열 이름은 주소를 의미하므로, 참조 연산자와 함께 사용이 가능하다.
ar : 배열의 시작 주소
*ar : 배열의 시작 주소에 저장된 값, 즉 0번째 원소를 의미
배열 주소에 대한 증감 연산 (ar의 값이 0xB4일 때)
ar + 1 의 결과는? 0xB5? 0xB8?
*(ar + 1)의 결과는 ?
1 | int ar[5] = {2, 3, 5, 7, -1}; |
결과 : 001E40B8 3 3
주소에 1을 더하면, 변수의 크기만큼 주소가 증가한다.
- 배열 주소에 대한 증감 연산은 배열 원소 하나의 크기 만큼 증가 or 감소
int 배열의 경우 : 4
ar + i : 배열 ar의 i번째 원소의 주소
*(ar + i) : 배열 ar의 i번째 원소의 값, 즉, ar[i]
배열의 시작 주소를 이용하여 배열을 포인터 형태로 사용할 수 있다.
주소의 증감 단위가 변수의 크기에 의해 결정되므로 배열의 자료형에 관계없이 *(ar + i) = ar[i] 가 성립한다.
배열을 포인터 변수에 연결하여 사용
배열 이름은 주소를 의미하므로, 포인터 변수에 대입이 가능1
2int ar[5] = {2, 3, 5, 7, -1};
int *p = ar;위와 같이 사용이 가능하며 포인터 변수도 배열의 첨자 형태로 값을 참조 할 수 있다. 즉 p[0] = *p이고 p[1] = *(p + 1) 이다.
포인터 인자와 주소 반환
- 두 변수를 교환하는 swap함수를 만들어보자실행 결과 : 10 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15void swap(int x, int y)
{
int tmp;
tmp = x;
x = y;
y = tmp;
}
void main()
{
int x = 10, y = 20;
swap(x, y);
printf("%d %d", x, y);
}
main 함수의 변수가 왜 안 바뀌는 지 메모리 그림을 확인해보자.
1 | void swap(int *px, int *py) |
실행 결과 : 20 10
이렇게, 함수의 인자로 변수의 주소값을 넘겨주고 swap함수에서 포인터 변수로 처리를 하게 되면 값이 정상적으로 바뀌는 것을 확인할 수 있다.
- main함수의 값이 왜 바뀌는 지 메모리 그림을 확인해보자