컴퓨터과학과

컴퓨터과학과 학생 게시판

조회 수 130 추천 수 5 댓글 2
Atachment
첨부 '1'

단축키

Prev이전 문서

Next다음 문서

포인터의 개념은 C프로그래밍, 자료구조와 컴퓨터구조를 학습할 때 반드시 숙지하여야 하는 개념입니다.

 

포인터의 개념과 사용방법은 나와 있지만  

왜 불편하게 이런 걸 사용하게 되었을까라는 의문에 대한 설명은 없어서 정리했습니다. (Gemini 이용)

============================================================================

포인터가 제공하는 기능(직접적인 메모리 접근, 주소 전달 등)이 왜 절실하게 필요했는지 이해하려면,

C 언어가 탄생했던 1970년대의 컴퓨팅 환경C 언어의 탄생 목적을 들여다봐야 합니다.

한마디로 말하면 **"극도로 부족한 자원 환경에서, 운영체제(OS)를 직접 만들기 위해서"**였습니다.

주요 이유는 크게 3가지입니다.


1. 하드웨어 자원이 극도로 부족했습니다.

지금 우리는 수십 기가바이트(GB)의 램(RAM)을 쓰지만, C 언어가 개발된 1970년대 초반 컴퓨터(예: DEC PDP-11)의 메모리는 수십 킬로바이트(KB) 수준이었습니다. (지금의 스마트폰 사진 한 장 크기보다도 훨씬 작습니다.)

  • 문제점: 함수로 데이터를 넘길 때마다 값을 복사(Copy)하면, 아까운 메모리가 금방 가득 차고, 복사하는 데 CPU 시간을 다 써버려 컴퓨터가 느려집니다.

  • 해결책 (포인터): "데이터를 복사하지 말고, 데이터가 어디 있는지(주소)만 알려주자."

    • 이렇게 하면 1MB짜리 데이터를 넘기든, 1KB짜리를 넘기든, 딱 주소값 크기(약 2~4바이트)만 사용하면 되므로 메모리와 속도 문제를 동시에 해결할 수 있었습니다.

2. 운영체제(Unix)를 만들기 위해 탄생한 언어입니다.

C 언어의 아버지 데니스 리치는 **유닉스(Unix)**라는 운영체제를 만들기 위해 C를 만들었습니다.

운영체제는 하드웨어를 관리하는 대장 프로그램입니다.

Memory Mapped IO diagram 이미지

Shutterstock

  • 문제점: 모니터에 글자를 띄우거나, 키보드 입력을 받거나, 디스크를 돌리려면 특정한 하드웨어 메모리 주소에 직접 신호를 줘야 합니다. (이를 Memory Mapped I/O라고 합니다.)

  • 해결책 (포인터): "특정 메모리 번지(예: 0xA0000000)를 콕 집어서 값을 쓰거나 읽을 수 있는 기능이 필요하다."

    • 포인터가 있으면 *0xA0000000 = 1; 처럼 하드웨어의 특정 위치를 직접 조작할 수 있습니다. 다른 고급 언어(Python, Java 등)에서는 보안상의 이유로 막아둔 기능이지만, OS 개발에는 필수적입니다.

3. '이식성 있는 어셈블리어'가 필요했습니다.

C 언어 이전에는 시스템 프로그래밍을 **어셈블리어(기계어와 1:1 대응되는 매우 어려운 언어)**로 했습니다.

어셈블리어는 빠르고 하드웨어 제어가 가능하지만, CPU 종류가 바뀌면 코드를 처음부터 다시 짜야 했습니다.

  • 문제점: 하드웨어를 제어할 만큼 강력하면서도, CPU 종류에 상관없이 쓸 수 있는 언어가 필요했습니다.

  • 해결책 (포인터): 어셈블리어의 **'간접 주소 지정 방식(Indirect Addressing)'**을 고수준 언어로 구현한 것이 바로 포인터입니다.

    • 포인터를 사용하면 기계어 수준의 정밀한 메모리 제어가 가능하면서도, 문법은 사람이 읽을 수 있는 형태를 유지할 수 있었습니다.


요약: 그 당시에는 '선택'이 아니라 '필수'

 

당시 상황 포인터가 필요했던 이유
메모리가 너무 비싸고 작음 데이터를 복사할 여유가 없어서 **참조(주소)**만 넘겨야 했음
하드웨어를 직접 제어해야 함 비디오 카드, 사운드 카드 등의 특정 주소에 직접 접근해야 했음
속도가 생명임 불필요한 연산을 줄이기 위해 메모리 다이렉트 접근이 필요했음

즉, 포인터는 "하드웨어의 성능을 극한으로 끌어내면서도, 사람이 코딩하기 편하게 만들기 위한" 천재적인 발명품이었던 것입니다.


 

이중 포인터가 필요한 이유는?

**이중 포인터(Type **ptr)**는 말 그대로 **"포인터의 주소를 담는 포인터"**입니다.

싱글 포인터(*)만으로도 많은 것을 할 수 있는데 굳이 별을 두 개(**)나 붙여서 사용하는 핵심적인 이유는

"외부에서 선언된 포인터 변수 자체를 바꾸기 위해서"입니다.

 

가장 중요한 이유 3가지를 정리해 드립니다.

1. 함수 안에서 '포인터가 가리키는 방향'을 바꾸고 싶을 때 (가장 중요)

함수에 변수를 보낼 때 값을 바꾸려면 주소(포인터)를 보냈죠?

마찬가지로 포인터 변수의 값(주소)을 함수 안에서 바꾸려면 이중 포인터를 보내야 합니다.

  • 싱글 포인터: "A번지에 가서 내용물(값)을 바꿔라."

  • 이중 포인터: "내 수첩에 적힌 A번지라는 주소 자체를 B번지로 고쳐 써라."

실패하는 경우 (싱글 포인터 사용)

=======================================================

void try_change(int *p) {
    int b = 20;
    p = &b; // 함수 안에서만 p가 b를 가리키게 됨.
} // 함수가 끝나면 이 작업은 증발함. 원본 포인터는 여전히 엉뚱한 곳을 가리킴.

=======================================================

성공하는 경우 (이중 포인터 사용)

=======================================================

void real_change(int **pp) { // 포인터의 주소를 받음

    static int b = 20;
    *pp = &b; // "주소의 주소"를 찾아가서, "저장된 주소값"을 바꿔버림
}

int main() {
    int a = 10;
    int *ptr = &a;
    real_change(&ptr); // ptr 자체의 주소를 넘김
    // 이제 ptr은 b를 가리키고 있음
}
===============================================================================
현실 예시: 친구에게 "내비게이션 목적지 좀 바꿔줘"라고 부탁하려면, 
​​​​​​​내비게이션(포인터) 자체를 친구에게 건네줘야(참조) 친구가 조작할 수 있는 것과 같습니다.

2. 동적 2차원 배열을 만들 때

C 언어에서 int arr[3][4]; 처럼 크기가 고정된 2차원 배열 말고, 실행 중에 크기가 결정되는 2차원 배열을 만들 때 이중 포인터가 필수적입니다.

  • 원리:

    1. int ** 포인터로 '행(Row)'들의 시작 주소를 담을 리스트를 만듭니다.

    2. 각각의 행 포인터가 실제 데이터가 들어있는 '열(Column)' 1차원 배열을 가리킵니다.

이렇게 하면 각 행마다 길이가 다른 '들쑥날쑥한 배열(Jagged Array)'도 만들 수 있어 메모리를 효율적으로 쓸 수 있습니다.


3. 문자열 목록(배열)을 다룰 때

여러 개의 단어(문자열)를 묶어서 처리할 때 사용합니다. 우리가 main 함수를 쓸 때 자주 보는 그 형태입니다.

C

 

int main(int argc, char **argv)

여기서 char **argv문자열들의 배열을 의미합니다.

  • char * (문자열 하나)

  • char *들이 여러 개 모여 있으니, 이것들을 가리키는 것은 char ** (이중 포인터)가 됩니다.

예를 들어, "Hello", "World", "C" 세 단어를 저장한다면:

  1. 각 단어는 메모리 어딘가에 char 배열로 저장됩니다.

  2. 이중 포인터는 이 세 단어의 시작 주소들을 가지고 있는 배열을 가리킵니다.


요약

구분 설명
변수 값 변경 int * 필요 (변수의 주소를 알아야 함)
포인터 값 변경 int ** 필요 (포인터의 주소를 알아야 함)
2차원 구조 행과 열로 이루어진 동적 메모리 관리 시 필요
문자열 리스트 여러 개의 문자열을 관리할 때 필요 (char **)

 

열공 하시기 바랍니다.

  • ?
    Nightsky 2025.12.06 15:46
    비회원은 댓글은 읽을 수 없습니다.
    로그인 후에 바로 열람 가능합니다 ^^
  • ?
    스마일뤄 2025.12.08 21:37
    비회원은 댓글은 읽을 수 없습니다.
    로그인 후에 바로 열람 가능합니다 ^^

컴퓨터과학과

컴퓨터과학과 학생 게시판

List of Articles
번호 분류 제목 글쓴이 조회 수 날짜
공지 (필독) 공지 모음 / 방송대 커뮤니티 포인트 얻는 방법 및 입문서 416 게시판관리 9611 2022.12.24
공지 방송통신대학교 커뮤니티 홍보하고 포인트 적립하자! 73 게시판관리 4381 2023.09.20
공지 🎖 활동 메달 안내 및 기준 37 게시판관리 1444 2025.07.30
공지 📢 자료 업로드 규정 안내 (AI 사용 여부·출처 표기 의무화) 과거자료 재동록자 적발 시 IP차단 12 게시판관리 811 2025.11.14
1075 과공지 2025 데이터분석 경진대회 예비심사 결과 발표 안내 new noir 11 2026.01.28
1074 일반 대학생이 되면 발생하는 특전이 있습니다. 1 newfile 예린지 43 2026.01.28
1073 일반 방송대_컴퓨터과학과_2026_개설과목 엑셀파일입니다. newfile 예린지 25 2026.01.28
1072 질문 직장인 3학년 편입생 입니다.(졸업 학점 이수 관련) 2 new 홍이장군 22 2026.01.28
1071 질문 대체로 변경 3 update 쌉뚱보 58 2026.01.27
1070 과공지 2026 컴퓨터과학과 개설교과목 안내(개편사항 반영_260126) file noir 57 2026.01.27
1069 질문 회사 재직중 3학년 편입 도전!! 19학점 수강신청 어떨까요? 2 updatefile Luckyzzz 78 2026.01.26
1068 일반 3학년 편입 수강 과목 추천 file 김홍도 53 2026.01.26
1067 일반 슨배님들 3학년 컴과 편입생 수강계획 평가 부탁드려요..!! 1 updatefile 야루루루롤 60 2026.01.25
1066 질문 직장다니는 이번 편입 3학년인데 과목이렇게 괜찮을까요? file 코드워프 57 2026.01.25
1065 질문 3학년 1학기 편입생입니다. 수강신청 조언을 부탁드리고 싶습니다. 1 updatefile jayy 84 2026.01.24
1064 일반 선배님들 수강신청 조언부탁드립니다~ 1 updatefile 배삐삐 63 2026.01.24
1063 일반 3학년 컴퓨터과학과 노베이스 편입생 수강신청에 조언 부탁드립니다. 3 updatefile angelglow 144 2026.01.23
1062 질문 1학년 입학 예정입니다. 수강신청 도움 부탁 드립니다. 2 나리킨 77 2026.01.23
1061 일반 3학년 편입생 과목평가 부탁드립니다. Cohpe 68 2026.01.22
1060 일반 편입생 과목 추천 부탁드립니다. 4 세잎네잎 135 2026.01.22
1059 일반 3학년 편입생 수강신청 질문입니다 2 복숭아타르트 122 2026.01.22
1058 일반 [1월 24일] 장애인/노약자/차상위계층 외 일상생활 처우개선 프로젝트 모임 file Gotithelab 47 2026.01.21
1057 질문 입학식 관련 질문입니다. 2 kalsuend 94 2026.01.20
1056 일반 오픈소스 기반 데이터 분석 지난학기 수강하셨던 분 간단한 감상평 부탁드립니다 2 심청이후손 78 2026.01.18
목록
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 54 Next
/ 54