현재 선택한 정보처리 과정

정보처리기사 실기 이론 학습

이론 목록으로 돌아가기

C 포인터·배열·이중 포인터

포인터 변수의 주소, 저장한 주소, 역참조한 값을 나누어 추적한다.

예상 읽기 3

실기 학습 목표

포인터 변수의 주소, 저장한 주소, 역참조한 값을 나누어 추적한다.

핵심 이론

int *p=&x에서 p는 x의 주소, *p는 x의 값이다. *p를 바꾸면 x가 바뀐다. int **pp=&p에서 *pp는 p이고 **pp는 x의 값이다.

같은 배열 안에서 p+1은 다음 원소를 가리킨다. 이동 바이트 수는 대상 자료형 크기에 비례한다. a[i]는 *(a+i)와 같은 원소 접근이다.

*p++는 *(p++)로 해석되어 포인터가 이동한다. (*p)++는 가리키는 값을 증가시킨다. ++*p는 가리키는 값을 먼저 증가시킨다.

이차원 배열에서 행 포인터의 이동 단위는 한 행이다. 배열 끝 다음 주소는 계산할 수 있지만 역참조할 수 없다. 초기화하지 않은 포인터·해제된 메모리·범위 밖 접근의 출력을 정상 숫자로 가정하지 않는다.

개념 도식

좌우로 이동해 그림을 확인하세요.그림 크게 보기
C 포인터·배열·이중 포인터의 관계와 흐름을 보여 주는 도식
C 포인터·배열·이중 포인터의 관계와 흐름을 보여 주는 도식

주소를 담은 변수와 그 주소의 값을 분리한다

int a[]={10,20,30}; int *p=a; int **pp=&p;에서는 a의 세 칸, p라는 주소 저장 칸, pp라는 주소 저장 칸을 각각 그린다. p는 a[0]을 가리키고 pp는 p를 가리킨다. *pp는 p에 저장된 주소이며 **pp는 그 주소에서 읽은 정수 10이다.

실행문주소의 변화배열의 변화
p++p가 a[1]을 가리킴없음
**pp=25없음a[1]이 25
(*p)++없음a[1]이 26

포인터에 1을 더하면 대상 자료형 한 개만큼 이동한다. 정수형 포인터의 p+1을 무조건 1바이트 이동으로 계산하지 않는다. *p++*(p++)이므로 기존 대상의 값을 사용한 뒤 p가 이동하고, (*p)++는 p를 고정한 채 대상 값을 증가시킨다.

배열 포인터와 포인터 배열도 다르다. int (*r)[3]의 r+1은 정수 3개인 한 행을 건너뛰고, int *r[3]은 정수 포인터 세 개를 담는 배열이다. 선언 전체를 외우기보다 괄호와 대괄호가 무엇을 묶는지 확인한다. 실기에서는 실제 객체 범위 안의 이동과 유효한 주소만 추적한다. 해제된 주소나 지역변수 수명이 끝난 주소의 값을 임의로 정답 숫자로 추측하지 않는다.

풀이 예시

다음 C17 프로그램이 표준 출력에 기록하는 내용을 쓰시오. 마지막 줄바꿈의 유무는 답안에서 구별하지 않는다.

C코드 영역 안에서 좌우로 이동할 수 있습니다.
#include <stdio.h>
void advance(int **cursor) {
    *cursor += 2;
    **cursor += 4;
}
int main(void) {
    int a[] = {5, 10, 15, 20};
    int *p = a;
    advance(&p);
    printf("%d %d %d\n", (int)(p - a), *p, a[0]);
    return 0;
}

예시 정답

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
2 19 5

풀이 과정

cursor는 p의 주소이다. *cursor를 2 증가시키면 p 자체가 a[2]로 옮겨진다. 그 원소에 4를 더해 19가 되며 a[0]은 5로 유지된다.

답안 점검

위 풀이 예시의 답을 가린 뒤, 핵심 이론의 규칙을 적용해 직접 풀어 보세요. 코드와 계산 문제는 중간값·단위·최종 출력의 순서를, 용어 문제는 지문의 핵심 단서와 답의 의미를 점검하세요. 해설과 다른 부분이 있으면 어느 조건을 놓쳤는지 확인하고 연결된 실기 문제로 다시 연습하세요.