ABOUT ME

Today
Yesterday
Total
  • [정글 WEEK04_알고리즘] 개발일지 - C 포인터, * 연산자, & 연산자
    카테고리 없음 2025. 4. 3. 18:37

     

    1. 포인터, 역참조 연산자 "*"

    *는 변수 선언 시에는 포인터 선언으로, 변수 사용 시에는 역참조에 쓰임

     

    포인터는 특정 변수 또는 데이터의 주소를 저장하는 특별한 변수

    역참조주소에 있는 값에 접근

     

    ❗️ 포인터도 변수이므로 메모리 어딘가에 저장됨

    int *i;   // int형 데이터를 '가리키는' 포인터 i 선언
    char *c;   // char형 데이터를 '가리키는' 포인터 c 선언
    double *d;   // double형 데이터를 '가리키는' 포인터 d 선언

     

    🗝️ 사용 맥락

    1) 함수에서 값 변경(Call by Reference)

    #include <stdio.h>
    
    void set_to_zero(int *ptr) { // 포인터 선언
        *ptr = 0; // 역참조 -> ptr이 가리키는 주소에 저장되는 값ㅇ르 0으로 설정
    }
    
    int main() {
        int a = 10;
        set_to_zero(&a); // a의 주소를 포인터 인자로 함수에 전달
    
        printf("%d\n", a);  // 출력: 0
        return 0;
    }

     

    2) 배열이나 자료구조의 데이터 처리

    #include <stdio.h>
    
    int arr[3] = {10, 20, 30};
    int *p = arr; // 포인터 선언, arr의 첫 번째 원소 주소로 초기화
    
    for(int i = 0; i < 3; i++)
        printf("%d ", *(p + i));  // 역참조를 통해 배열 주소에 있는 원소 접근

     

    3) 동적 메모리 할당 사용

    #include <stdio.h>
    
    int *p = (int*)malloc(sizeof(int) * 100); // 포인터 선언, malloc을 통해 동적으로 확보한 메모리 100개 주소로 초기화
    p[0] = 10;  // *(p + 0)과 동일 -> 역참조로 0번 주소에 10 할당

     

    4) 복잡한 데이터 구조 처리

    #include <stdio.h>
    
    typedef struct Node {
        int data;
        struct Node *next;
    } Node;
    
    Node *head = malloc(sizeof(Node)); // 포인터 선언 -> Node 구조체를 가리키는 포인터
    head->data = 10;  // (*head).data와 동일 -> 역참조 후 멤버 접근
    head->next = NULL;
    
    printf("%d\n", head->data); // 포인터 역참조로 접근

     

    🔗 포인터 vs 역참조

    #include <stdio.h>
    
    int main() {
        int a = 10;
        int *p = &a;  // a의 주소를 '포인터' p에 저장
    
        printf("변수 a의 값: %d\n", a);       // 10
        printf("변수 a의 주소: %p\n", &a);    // 0x7ffe...
        printf("포인터 p가 가리키는 주소: %p\n", p);   // &a → 0x7ffe... 
        printf("포인터 p가 가리키는 값: %d\n", *p);    // '역참조' → 10
    
        *p = 20;  // 포인터로 a의 값을 20으로 변경
        printf("변경 후 변수 a의 값: %d\n", a);  // 20
    
        return 0;
    }

     

     

    2. 주소 연산자 "&" 

    변수 앞에 붙여 해당 변수의 주소를 반환

     

    🗝️ 사용 맥락

    1) 포인터 변수 초기화 

    #include <stdio.h>
    
    int a = 10;
    int *p = &a; // '포인터 p'에 변수 a의 '주소' 할당

     

    2) 직접 주소 출력

    #include <stdio.h>
    
    printf("%p", &a);  // 변수 a의 포인터 주소 출력

     

    3) 함수 인자로 전달

    #include <stdio.h>
    
    // 함수 선언: 정수형 변수의 주소를 받아서, 값 변경
    void change(int *ptr) {
        *ptr = 100;  // 포인터를 역참조해서 원본 값 변경
    }
    
    int main() {
        int a = 42;
        printf("before: %d\n", a);   // 출력: 42
    
        change(&a);  // a의 주소 넘김 => change 함수에서 a 직접 수정
    
        printf("after: %d\n", a);    // 출력: 100
        return 0;
    }

     

    4) 입력 받은 값을 변수의 주소에 직접 접근해 저장(Call by Reference)

    int num; // int형 데이터를 저장하는 num 변수 할당
    scanf("%d", &num); //

     

     

     

    3. Linked List 구현

    🔗 Linked List

     - 메모리 공간이 연속적이지 않아도 되고,

     - 각 요소가 자신 다음 노드의 주소를 저장하는 포인터를 갖고 있음

     

    C에서 연결 리스트는 구조체포인터로 만듦

    #include <stdio.h>
    #include <stdlib.h>
    
    // 노드 정의
    typedef struct Node {
        int data;  // 실제 저장할 값
        struct Node* next;  // 다음 노드를 가리키는 포인터
    } Node;
    
    // 새 노드 생성 함수
    Node* create_node(int value) {  // 동적으로 노드 만들고 해당 주소 반환
        Node* new_node = (Node*)malloc(sizeof(Node));
        new_node->data = value;
        new_node->next = NULL;
        return new_node;
    }
    
    // 노드 추가 함수 (맨 끝에 추가)
    void append_node(Node** head, int value) {  // head를 직접 바꾸기 위해 이중 포인터 사용
        Node* new_node = create_node(value);  
    
        if (*head == NULL) {
            *head = new_node;
            return;
        }
    
        Node* current = *head;
        while (current->next != NULL) {
            current = current->next;  // 포인터를 따라가며 노드 순회
        }
    
        current->next = new_node;
    }
    
    // 리스트 출력 함수
    void print_list(Node* head) {
        Node* current = head;
        while (current != NULL) {
            printf("%d → ", current->data);
            current = current->next;  // 포인터를 따라가며 노드 순회
        }
        printf("NULL\n");
    }
    
    // 메모리 해제 함수
    void free_list(Node* head) {
        Node* current;
        while (head != NULL) {
            current = head;
            head = head->next;
            free(current);  // malloc된 메모리 직접 해제
        }
    }
    
    // 메인 함수
    int main() {
        Node* head = NULL;
    
        append_node(&head, 10);
        append_node(&head, 20);
        append_node(&head, 30);
    
        printf("Linked List: ");
        print_list(head);
    
        free_list(head);
        return 0;
    }

     

    댓글

Designed by Tistory.