컴퓨터 이론

포인터와 구조체 설명하기..

pwerty 2025. 4. 11. 22:22

팀 코어타임 이론 제공 전용 참고자료, C언어를 완전 처음 임하는 사람들에게 동기부여하는 내용이 주가 된다.
실질적인 사용 내용이랑은 거리가 좀 있지만, 나중 가서도 도움이 될 수 있는 점이 있겠거니 해서 남긴다.

대충 생각한 견적,

  • 어떻게 생겼는가?
    • 포인터 : 포인터는 다른 변수의 메모리 주소를 저장하는 변수이다. 즉, 데이터를 직접 복사하지 않고 주소를 이용해 참조 할 수 있게 해주는 도구이다.
    #include <stdio.h>
    int main() {
        int a = 10;    // 변수 선언
        int *p = &a;   // 포인터에 a의 주소 저장
    
        printf("a: %d\\n", *p); // 포인터를 통해 값 출력
    
        return 0;
    }
    
    
    • 구조체 : 구조체는 연관된 데이터를 하나의 이름 아래 묶어주는 직접 만들 수 있는 데이터 타입이다.
    struct Person {
        char name[50]; // 이름
        int age; // 나이
    };
    
  • 왜 쓰는가?
    • 포인터 : 겁나 큰 겁나 큰 겁나 큰 변수가 있다. 막 이거 하나 옮겼다가는 RAM이 100%가 된다. 이걸 어떤 함수에 그대로 복사하는 순간 컴퓨터는 꺼질거다. 그래서 변수를 들고 복사하는 수단 보단 변수를 이용해야 하는 함수가 변수의 위치를 참조하는 것이 컴퓨터 입장에서 훨씬 가벼운 액션이니 포인터라는 경유 하는 선택지를 고려 한 것이다.
      • 사람이 일반적으로 들 수 없는 물건을 쓰겠다고 생각하면, 그 물건을 사람 앞에 가져오기보단 사람이 그 물건 앞으로 가는게 상식적으로 맞듯, 사람이 함수고 물건이 변수라고 생각하면 된다.
    • 구조체 : 구조체로 제일 흔하게 할 수 있는 선언이 사람이다. 사람은 이름, 나이, 성별, 등 다양하게 담고있다. 이 구조체를 담을 수 있는 리스트(또는 배열)를 선언하면 이 양식에 맞춰서 많은 사람의 정보를 담을 수 있을 것이다. 하지만 구조체가 없다면 이름 리스트 따로. 나이 리스트 따로. 성별 리스트 따로. 이렇게 관리해야한다. 대충 생각하면 10번 인덱스에 있는 이름, 나이, 성별 가져오면 되겠다고 생각 할 수 있지만 그게 생각보다 녹록치 않다. 구조체는 이러한 상황에서의 휴먼 에러를 줄이기 위해 고안되었다.
      • 게다가 얘는 전에 배웠던 캐시 메모리의 지역성까지 만족시킬 수 있다. 개사기임
      • 배열 세개를 따로 두는 것은 무작위 메모리 배치때문에 지역성을 전혀 만족시키지 못한다.
  • 다른 영역에서의 간단한 비유
    • 포인터 : 지도 앱에서 식당에 대해 저장 해둔적 있지 않나? 근데 지도 앱에 포인터 개념을 적용하면 무슨 느낌이냐하면, 푸드트럭을 pinned 하는 느낌. 이 트럭이 어딜가든 나는 실제 위치를 계속 알 수 있다.
      • 실제 위치를 계속 알 수 있다는 것이 데이터의 접근과 동일한 행위라고 생각하면 된다.
    • 구조체는 달리 비유 할게 없고 추상화 할 수 있는 무언가에 대해 딱 관련된 데이터를 묶는데에 의의가 있다. 이야기했듯, 사람이라면 이름 나이 성별 전화번호. 얘는 나중에 추상화에 대해 더 깊게 다룰 클래스를 배우기 전에 선행으로 알아두면 도움이 된다.
  • 이거 진짜 배우면 좋나요?..

포인터나 구조체가 필수적이냐? 라고 하면 모든 언어에 대해선 그렇진 않다. 포인터나 구조체를 대체하거나 상위 호환인 요소가 즐비하지만, C언어에서만큼은 반드시 그래야 한다라고 말할 수 있다.

특히 포인터에서 파생된 Call by Reference, Call by Value라는 개념은 현대 프로그래밍에서도 유효하다.

  • 해결 해야 할 문제 : 친구가 나에게 재밌는 소설 책을 하나 보고 싶다고 했다. 전달 방법은 두가지이다.
    • Call by Ref : 내 방 → 책장 3번째 칸 → 맨 왼쪽에서 두번째 책을 가져가서 봐
      • 책(데이터)의 위치를 알려준다. 이 책은 현재까지의 진행상태로썬 한 권 밖에 없어서, 친구가 찢으면 상태가 반영된다.
    • Call by Val : 책의 복사본을 만들어서 친구에게 준다.
      • 책을 그냥 복사해서 주었다. 복사본에 뭔 짓을 하든 내 책엔 영향이 없다.
  • 동적 메모리 할당에 이게 필수적입니다..!!
    • 일단 동적 메모리 할당을 왜 해야하냐부터 설명해보겠다.
    • 우리가 했던 프로젝트를 생각해보면, 백준의 알고리즘 문제도 그렇고 미니 프로젝트도 그렇고 그냥그냥 그랬다. 입력이 10만 들어온다고 하면 그냥 처음부터 10만 배열 만들어놓고 하고 그랬다. 실제 돈받고 팔아먹을 프로젝트에는 그렇게 할 수가 없다. 메모리 할당이 동적으로 일어나는 것이 실제 프로그램 성능에 영향을 미치기 때문, 아무리 이론적인 이야기만 하지만 그 밑에는 자본이 뒷받침 되어야한다. 즉, 동적 메모리 할당조차 유지비, 돈과 연결된 이야기라는 것.
      • 이런 성능 최적화 연구조차 알고리즘을 공부하는 것과 목적은 크게 다르지 않다는게 된다.
      • 어쨌든 그렇게 되어서 동적 메모리 할당에 대한 주로 사용되는 명령어가 malloc, free 이런 계열이다. 잘 알아야한다.
        • malloc은 동적 메모리를 할당한 후 할당 메모리의 시작 주소를 반환한다.
        • free도 해제하기 위해선 매개변수로 주소가 필요하다.
        • 프로그램 실행 단계에서 일정한 메모리를 할당한다지만, 이전에 CSAPP 책에서 간략하게 짚고 넘어갔던 무작위 메모리 할당 같은것 때문에, 지금 주소값의 다음 주소값도 같은 프로그램에 대해 다룬다는 보장을 못한다. 그래서 메모리 주소를 기억하고 다루는 것이 여전히 중요한 기술이 된 것이다.
        • 왜 malloc과 free를 논 할 때 매개체로 주소값만 고려하나요? 다른 시도는 없었나요?
          • 네. 현실적으로 말이 안됩니다. 주소값만큼 더 깊이 메모리를 가리킬 방법이 없음.
  • 구조체는 상위호환으로 클래스가 있어서 그냥 있는가보다 하고 생각하면 됩니다. 클래스는 나중가서 필수적이나, 구조체는 지금 자료구조 직접 구현이라는 파트를 지나는데만큼만 필수적입니다.