콘텐츠로 건너뛰기

C공부할 때 잘 이해안되던 코드들

1. 함수 포인터 (Function Pointer)

핵심: 함수의 주소를 값처럼 전달하여, 실행할 로직(Logic)을 상황에 따라 교체한다.

  • 동작 원리: $int (*cmp)(int, int)$는 “반환형이 int이고, 정수 2개를 인자로 받는 함수”를 가리키는 포인터다.
  • 활용: 실행할 함수를 갈아끼우는 콜백(Callback) 구조에 사용된다.
#include <stdio.h>

// 1. 동작을 결정할 함수들 (전략)
int OlderFirst(int age1, int age2) {
    if (age1 > age2) return age1;
    else if (age1 < age2) return age2;
    else return 0;
}

int YoungerFirst(int age1, int age2) {
    if (age1 < age2) return age1;
    else if (age1 > age2) return age2;
    else return 0;
}

// 2. 함수 포인터를 매개변수로 받는 함수 (실행기)
// cmp에는 OlderFirst나 YoungerFirst의 주소가 들어온다.
int WhoIsFirst(int age1, int age2, int (*cmp)(int n1, int n2)) {
    return cmp(age1, age2); // 전달받은 함수 실행
}

int main() {
    int age1 = 20;
    int age2 = 30;
    int first;

    printf("입장순서 1 (연장자 우선)\n");
    // OlderFirst 함수의 주소를 전달
    first = WhoIsFirst(age1, age2, OlderFirst);
    printf("결과: %d세 입장\n", first);

    printf("입장순서 2 (연소자 우선)\n");
    // YoungerFirst 함수의 주소를 전달
    first = WhoIsFirst(age1, age2, YoungerFirst);
    printf("결과: %d세 입장\n", first);

    return 0;
}

2. 구조체 포인터의 접근 (Accessing Struct Pointers)

핵심: 포인터를 통해 구조체 멤버에 접근할 때는 . 대신 ->를 사용한다.

  • (*pptr).xpos: 포인터를 먼저 역참조($*$)하여 구조체 원본을 찾고, 그 안의 멤버($.$)를 찾는다. (괄호 필수)
  • pptr->xpos: 위 과정을 한 번에 표현하는 문법. 가독성이 좋다.
#include <stdio.h>

struct point {
    int xpos;
    int ypos;
};

int main() {
    struct point pos1 = {1, 2};
    struct point pos2 = {100, 200};
    
    struct point * pptr = &pos1; // pos1을 가리킴

    // 1. (*ptr).멤버 방식
    (*pptr).xpos += 4;
    (*pptr).ypos += 5;
    printf("[%d %d] \n", pptr->xpos, pptr->ypos);

    // 2. ptr->멤버 방식 (더 많이 쓰임)
    pptr = &pos2; // pos2로 타겟 변경
    pptr->xpos += 1;
    pptr->ypos += 2;
    printf("[%d %d] \n", (*pptr).xpos, (*pptr).ypos);

    return 0;
}

3. 구조체 멤버로서의 포인터 (Nested Pointers)

핵심: 구조체 안에 다른 구조체의 이 아닌 주소를 저장한다.

  • 메모리 효율: struct point center로 선언하면 점의 데이터가 복사되지만, struct point *center로 선언하면 주소만 저장하므로 가볍다.
  • 초기화 주의: ring을 초기화할 때 &cen을 사용하여 외부 변수의 주소를 연결해 주었다.
#include <stdio.h>

struct point {
    int xpos;
    int ypos;
};

struct circle {
    double radius;
    struct point * center; // 다른 구조체를 가리키는 포인터 멤버
};

int main() {
    struct point cen = {2, 7};
    double rad = 5.5;

    // cen의 주소를 circle 구조체 내부에 저장
    struct circle ring = {rad, &cen};
    
    printf("원의 반지름: %g \n", ring.radius);
    
    // 접근 순서: ring.center (포인터) -> xpos (멤버)
    printf("원의 중심: (%d, %d) \n", ring.center->xpos, ring.center->ypos);
    
    return 0;
}

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다