9.1 포인터 개요
1) 메모리
- 프로그램이 실행되기 위해 필요한 정보(값)을 저장하는 공간
- 1byte (8 bits) 단위로 물리 주소가 부여되어 있음
- 개념적으로, 메모리는 일렬로 연속되어 있는 크기가 1 byte인 방들의 모음이라고 볼 수 있음
- 일반적으로 주소의 길이는 4 bytes이고 주소는 16진수로 표현
2) 메모리와 변수의 관계
- 변수는 선언될 때, 메모리에 그 변수를 위한 공간이 할당됨
- 주소연산자(&): 변수에 할당된 메모리 공간의 시작 주소를 구해줌
- 한번 할당되면 주소는 고정된다.
3) C프로그램에서 변수의 의미
- 그 변수에 할당된 공간: 선언 또는 대입문의 왼쪽 변수로 사용될 때
- 그 변수에 저장된 값: 대입문의 오른쪽 변수, 조건식, 함수의 인수로 사용될 때
4) 포인터(자료형)
- 주소를 나타내는 특수 자료형
- 주소는 기본적으로 양의 정수로 표현됨
- 하지만 int와는 구별되어 처리됨
(1) 선언
- 변수명 앞에 *(참조연산자) 사용
char *pch;
(2) 연결
- &(주소연산자)를 이용해 포인터 변수를 다른 변수에 연결
pch = &ch;
(3) 참조
- *(참조연산자)를 이용해 포인터에 연결된 변수에 접근
printf("%c", *pch);
9.2 포인터 선언과 사용
1) 포인터(변수) 선언
- 변수명 앞에 *(참조연산자)만 덧붙이면 된다
- 기존의 자료형 표시 + 포인터라는 표시
int *pch;
char *pnum;
2) 초기화
- 일반변수 초기화 형태와 동일하다
- 초기화할 주소를 가진 변수(num)가 먼저 선언되어야 한다
int num, *pnum = #
3) 포인터 변수 선언의 다양한 형태
- 동일 기본 자료형에서 파생된 자료형의 변수는 모아서 선언 가능
- 그러나 가독성 때문에 추천 안함
4) 포인터 대입(연결)
- 포인터(변수)에 주소를 대입하여 특정 변수와 연결 시키는 것을 "가리킨다"라고 표현
pch = &ch;
5) 포인터 참조
- 포인터(변수)가 가리키는 변수에 접근하는 것
- 참조연산자 * 를 사용
printf("%c", *pch);
6) 참조 연산자를 이용한 대입
>>코드
char ch = 'A', *pch = &ch;
*pch = 'B' // 간접 접근: ch를 'B'로 변경
ch = 'C' // 직접 접근: ch를 'C'로 변경
7) 추가
- int *pnum = # 은 정수를 나타내므로 정수를 사용하는 어떤 형태나 계산에 사용가능
- 단, 참조연산자와 다른 연산자와의 우선순위에 주의해서 사용
8) 정리
- 주소연산자(&): 해당 변수의 주소값
- 변수 이름: 변수 영역 또는 변수에 저장된 값
- 참조연산자(*): 포인터가 가리키는 변수
- pnum과 &num의 값은 동일하지만, 지칭하는 부분은 다르다.
- pnum은 num과 연결된 포인터 변수의 값이고, &num은 num에 할당된 메모리 시작 주소이다.
9) Null 포인터
- 주소 값 0을 나타내는 특별한 기호
- 아무것도 가리키지 않음을 의미
- null의 값은 0 이므로, 조건문에서 사용하면 거짓에 해당
- 예기치 못한 오류 방지를 위해 포인터 변수를 null로 초기화
int *pnum = NULL;
10) 포인터 주의 사항
- 주소연산자(&)는 포인터를 포함한 모든 변수에 사용 가능
- 참조연산자(*)는 포인터 변수에서만 가능
- 포인터의 자료형과 연결된 변수의 자료형은 일치해야 한다
11) 포인터의 크기
- 포인터의 종류(자료형)에 관계없이 주소를 저장하기 위해 필요한 공간은 동일
- 단, 포인터의 크기는 시스템에 따라 다를 수 있음
9.3 배열과 포인터
1) 배열 이름의 비밀
- 배열 이름은 배열의 0번 원소의 시작 주소를 의미한다. (특별하다)
- 만약 ar[10]이란 배열이 있다면
>> ar은 ar[0]의 주소를 의미
>> &ar은 전체 배열(ar[])의 주소를 의미
2) 주소를 이용한 배열 참조
- 배열 이름은 주소를 의미하므로, 참조 연산자와 함께 사용 가능
- ar: 0번 원소의 주소( == &ar[0])
- *ar: 0번 원소의 주소에 저장된 값, 즉 0번 원소의 값을 의미
3) 배열 주소에 대한 증감 연산
- 배열 원소 하나의 크기만큼 증가 or 감소
- ar+i: 배열 ar의 i번째 원소의 주소
- *(ar+i): 배열 ar의 i번째 원소의 값
4) 배열을 포인터 변수에 연결하여 사용하기
- 배열 이름은 주소를 의미하므로, 포인터 변수에 대입가능
- 포인터 변수에 대한 증감연산
= 포인터 변수가 나타내는 자료형의 크기 단위로 끝자리가 증가 or 감소
5) 포인터 변수도 배열의 첨자 형태로 값을 참조할 수 있다
int ar[5] = {1, 2, 3, 4, 5};
int *p = ar;
6) 배열과 포인터의 관계 정리
- 배열과 포인터는 동일한 형태로 사용가능(둘다 주소이기 때문)
- 주소에 1을 더하면 원소의 크기만큼 주소가 증가
- 주소가 주어졌을 때, 해당 주소에 저장된 원소값은 다음 두가지형태로 참조 가능
>> ar[3]과 p[3]: 배열의 첨자 연산자 [] 사용
>> *(ar+3)과 *(p+3): 포인터의 참조 연산자 * 사용
7) 배열과 포인터 주의 사항
- 포인터를 배열의 중간 원소에 연결 시키는 것도 가능
- 포인터는 단지 자신이 가리키는 주소를 기준으로 배열처럼 쓰는 것일 뿐
- 포인터의 참조 연산자 사용 시 괄호에 유의
- 포인터 변수의 증감량은 가리키는 배열의 원소 크기가 아니라 포인터 자신의 자료형에 의해 결정
'프로그래밍 언어 개념정리 > C언어 개념 정리' 카테고리의 다른 글
C언어 개념 정리: 구조체 (0) | 2024.11.15 |
---|---|
C언어 개념 정리: 문자열 (1) | 2024.11.13 |
C언어 개념 정리: 디버깅 기초 (1) | 2024.11.11 |
C언어 개념 정리: 함수 (3) | 2024.11.10 |
C언어 개념 정리: 배열 (0) | 2024.11.09 |