—ฅ/ᐠ. ̫ .ᐟ\ฅ —

과목 일반

[자료구조] 0909 Review - 포인터, 배열, 문자열, 구조체

WIFI-Aircat 2024. 12. 9. 22:29
💾 Data Structure
: 0909 Review - Pointer, Array, String, Structure


🤍 1 - 'struct'

1. 단일 구조체 변수 ( `user.name` )
: 하나의 구조체 인스턴스
직관적으로 구조체의 각 멤버에 접근 가능


- ex) 개인 정보가 담긴 단일 사용자를 처리할 때

struct user user1;
user1.name = "cat";
printf("%s\n", user1.name);

 


2. 구조체 배열 ( `user[i].name` )
: 여러 개의 구조체 인스턴스를 배열로 관리
배열 인덱스로 각각 구조체에 접근 가능


- ex) 다수의 사용자 정보를 저장하고 처리할 때

struct user users[10];
users[0].name = "cat";
printf("%s\n", users[0].name);

 

 

3. 구조체 포인터 ( `user->name` )
: 동적 메모리나 포인터로 전달된 구조체
함수 간 구조체를 복사하지 않고 포인터로 전달 가능


- ex) 동적으로 메모리를 할당한 후 포인터로 구조체에 접근할 때

struct user* userPtr = (struct user*)malloc(sizeof(struct user));
userPtr->name = "cat";
printf("%s\n", userPtr->name);



요약
- `user.name` : 단일 구조체
- `user[i].name` : 여러 개의 구조체를 배열로
- `user->name` : 동적 메모리나 포인터
- 구조체에 접근하는 방식이 다른 것은 메모리 관리 데이터 접근 방식이 다르기 때문



🤍 2 - `'qsort'`

1. 정수 배열 ( `int[]` )
- 포인터를 `int*`로 캐스팅한 후 역참조하여 두 정수를 비교

 // 배열 선언
int arr[] = {5, 3, 8, 1, 2};
     
// comp 함수
int comp(const void* a, const void* b) {
    return (*(int*)a - *(int*)b);
}

 

 

2. 실수 배열 ( `double[]` )
- double 타입의 실수 값을 비교할 때 소수점 연산이 필요하므로 두 값을 뺀 결과로 비교

// 배열 선언
double arr[] = {3.5, 2.1, 4.8, 1.9};
     
// comp 함수
int comp(const void* a, const void* b) {
    double diff = *(double*)a - *(double*)b;
    return (diff > 0) - (diff < 0); // 양수, 음수, 0 반환
}



3. 구조체 배열
- 구조체의 특정 멤버(여기서는 `name` )를 기준으로 비교할 때는 포인터를 구조체로 캐스팅한 후 해당 멤버를 사용

// 구조체 정의
typedef struct {
    char name[20];
    int age;
} Person;

// 구조체 배열 선언
Person people[] = {{"Alice", 30}, {"Bob", 25}, {"Charlie", 35}};
   
// comp 함수 (이름을 기준으로 정렬):
int comp(const void* a, const void* b) {
    return strcmp(((Person*)a)->name, ((Person*)b)->name);
}


- 여러 멤버를 기준으로 정렬할 때

// comp 함수 (나이를 기준으로, 나이가 같으면 점수로 정렬)
int comp(const void* a, const void* b) {
    Person* s1 = (Person*)a;
    Person* s2 = (Person*)b;
    if (s1->age != s2->age)
        return s1->age - s2->age;
    else
        return (s1->score > s2->score) - (s1->score < s2->score);
}



4. 포인터 배열 ( `char* arr[]` )

- 포인터 배열의 각 요소는 문자열을 가리키는 포인터( `char*` ) (문자열의 주소를 저장하고 있음)
- `qsort`의 `a`, `b`는 배열의 요소를 가리킴
- 이를 `*(const char**)`로 포인터를 역참조한 후 포인터가 가리키는 실제 문자열을 비교

// 배열 선언: 각 요소는 문자열의 시작 주소를 가리킴
char* strings[] = {"apple", "banana", "cherry"};

// qsort 호출: 요소 크기는 `sizeof(char*)` (포인터의 크기)
qsort(strings, 3, sizeof(char*), comp);

// comp 함수: 포인터를 역참조하여 문자열을 비교
int comp(const void* a, const void* b) {
    return strcmp(*(const char**)a, *(const char**)b);
}



5. 이차원 배열 ( `char arr[20][20]` )
- 이차원 배열의 각 요소는 고정된 크기의 `char[20]` 배열 (요소가 문자열을 직접 포함)
- `qsort` `a`, `b`는 문자열 배열의 시작 주소를 가리킴
- 이를 `(const char*)`로 캐스팅하여 문자열 비교

    // 배열 선언: 각 요소는 20개의 문자를 저장할 수 있는 배열
    char strings[20][20] = {"apple", "banana", "cherry"};

    // qsort 호출: 요소 크기는 `sizeof(strings[0])` (각 행의 크기)
    qsort(strings, 3, sizeof(strings[0]), comp);

    // comp 함수: 문자열 배열의 시작 주소를 이용해 문자열 비교
    int comp(const void* a, const void* b) {
        return strcmp((const char*)a, (const char*)b);
    }

 



포인터 배열과 2D 배열의 구분 방법

- 포인터 배열: 각 요소는 문자열을 가리키는 포인터이므로, `*(const char**)a`로 포인터를 역참조하여 문자열을 비교
- 이차원 배열: 각 요소는 문자열을 직접 저장하는 char[] 배열이므로, `(const char*)a`로 배열의 시작 주소를 캐스팅하여 문자열을 비교

 

항목 포인터 배열 ( `char*` ) 이차원 배열 ( `char[20]` )
배열 선언 방식 `char* arr[]` `char arr[20][20]`
qsort 호출 시 요소 크기 sizeof(char*) `sizeof(char[20]) | sizeof(strings[0])`
타입 캐스팅 `(const char**)a`, `*(const char**)b` `(const char*)a` , `(const char*)b`


- 이차원 배열에서 `strings[0]`은 배열의 첫 번째 행을 가리킴.
(= 첫 번째 문자열을 저장하는 20칸짜리 배열인 `char[20]`)


 

반응형