정보처리기사 실기를 공부하면서
시험범위 내에서 가장 어려운 부분은 C언어 포인터 부분이라고 생각되서,
이번기회로 정리 겸 복습하는 시간을 가졌습니다.
1. 포인터란?
포인터 : 주소를 저장하는 변수
예를 들어 정수형 변수 x를 선언하면, 컴퓨터의 메모리(RAM) 공간 중 일부가 x를 저장하기 위해 할당됩니다.
예를 들어, x가 저장된 메모리 주소가 0x0010이라고 가정해봅시다.
이때 변수 x의 주소값을 저장하려면 포인터가 필요합니다.
즉, x의 주소를 저장하는 변수가 포인터입니다.
int *p=&x;

여기서 p는 x의 주소를 저장하는 포인터이며, *p를 통해 x의 값을 간접적으로 접근하거나 수정할 수 있습니다.
2. 포인터는 어떻게 사용되는가?
포인터는 '주소를 저장하는 변수' 인 만큼 주소를 통해서 변수에 직접 접근 합니다.
일반 변수는 이름으로 접근하지만, 포인터는 메모리 주소(&x)를 저장하여, 해당위치의 값을 읽고 쓸 수 있다.
int x=5;
int *p=&x; //p에 x의 주소 저장
*p=10; //p가 가리키는 메모리에 10을 저장 => x값이 10로 변경
&가 붙으면 주소를 의미하는 것으로 &x는 x의 주소를 의미한다.
코드를 기반으로 포인터가 어떻게 작동하는지 알아보자.
1) 변수 선언
int x=5;

4바이트 크기의 변수 x를 선언하고, 그 공간에 값 5를 저장합니다.
2) 포인터 선언
int *p=&x; //p에 x의 주소 저장

- int *p → “정수형 변수를 가리키는 포인터” p를 선언
- &x → 변수 x의 메모리 주소 (예: 0x0010)
- p = &x → 포인터 p의 메모리 셀에 x의 주소를 저장
- 결과적으로, p는 “x가 위치한 메모리”를 가리키는 변수가 됩니다.
cf)
< 포인터에 자료형을 명시하는 이유 >
메모리에서 각 기본형 변수는 크기가 다릅니다.
- int a→ 4 byte
- char b → 1 byte
- double c → 8 byte
역참조 시 읽기/쓰기 범위 결정
시작주소는 알고있지만, a는 4byte를 읽어야 하고, b는 1byte, c는 8byte를 읽어야 하는지,모르기에 포인터에도 자료형을 명시한다.
ex.
int *ptr_a=&a;
char *ptr_b=&b;
double *ptr_c=&c;
3)
*p=10; //p가 가리키는 메모리에 10을 저장 => x값이 10으로 변경

- p 자체를 읽으면 → 0x0010 (주소값)
- *p 연산은 → “p가 가리키는 주소(0x0010)의 메모리 셀
- *p = 10; → p가 가리키는 위치에 10을 저장 ⇒ x의 값이 10으로 변경
3. 값 전달 vs 주소 전달: 포인터가 필요한 이유
값이 전달되는 방식에는 Call by Value (값 복사), Call by Reference (주소 전달) 가 있다.
Call by Value (값 복사)
- 가장 기본적인 함수 호출 방식입니다.
- 함수에 값의 복사본이 전달되므로, 함수 안에서 값을 바꾸더라도 원래 변수에는 아무 영향이 없습니다.
Call by Reference (주소 전달)
- 포인터를 통해 변수의 메모리 주소 자체를 함수에 넘기는 방식입니다.
- 함수 내부에서 포인터를 사용해 원본 데이터를 직접 수정할 수 있습니다.
- 그래서 함수 안에서 변경한 값이 함수 밖에서도 반영됩니다
→ 원본 변수를 함수 내에서 바꾸고 싶다면, 반드시 포인터(주소 전달)를 사용해야 합니다.
(1) Call by Reference — 포인터를 이용한 값 변경
#include <stdio.h>
//두 변수의 값을 서로 변환하는 포인터 함수
void swap(int *x, int *y){
//포인터는 *x
//int 형의 어떠한 값을 가리키는 포인터 x를 만들었다
int temp;
temp=*x; //포인터 x가 가리키는 위치의 값을 넣어줌
*x=*y;
*y=temp;
}
int main(void)
{
int x=1;
int y=2;
swap(&x,&y);
printf("x=%d\ny=%d\n",x,y);
return 0;
}
출력결과

함수가 x, y의 주소를 받아 원본 값 자체를 바꾸었습니다.
(2) Call by Value — 포인터 없이 값만 넘긴 경우
#include <stdio.h>
//포인터를 이용하지 않고 바꿀 경우
void swap(int x, int y){
int temp;
temp=x;
x=y;
y=temp;
}
int main(void)
{
int x=1;
int y=2;
swap(x,y);
printf("x=%d\ny=%d\n",x,y);
return 0;
}
출력결과

swap() 함수 안에서는 값이 바뀌었지만, main 함수의 x, y는 그대로입니다.
이유는 단순히 복사본만 바뀌었기 때문입니다.