본문 바로가기

개발

C - 구조체 배열을 함수에 사용할 때!!

모든 언어가 그렇지만 C언어는 계속 잊어먹는다. 내가 제대로 익히지 못해서가 제일 크다. 그래서 이번에도 다시 정주행을 하고 있는데, 그 과제를 하면서 생긴 이슈에 대한 기록이다. 

1
2
3
4
5
6
struct Book {
    char name[30];
    char author[30];
    char pub[30];
    int borrowed;
};
cs

 도서 관리 프로그램을 짜는것이 목표인데, 우선 이런 Book이라는 구조체를 작성하고 이 Book들이 많이 모여 있는 library라는 배열을 만들었다. -강좌에서 이렇게 시키지는 않았음 이 배열 안에 원소들에 접근해서 결론적으로 각 원소의 멤버들의 값을 바꾸고 싶은게 우리가 원하는 것이다. 그런데 함수로 모듈화를 하면, 포인터로 이 주소값을 넘겨야 하는데 이에 대한 이슈이다. 

 결론적으로 구조체 배열 다루는 함수!!! 에 대한 설명이 되겠다!!!


1
void show_all(struct Book* library, int total_number);
cs


인자로 넘겨야 하는 변수의 타입은 이렇다. 구조체들로 이루어진 배열을 보내는 것이니까!! 하지만 이는 구조체 배열이 아닌 단일 구조체를 넘길 때에도 똑같다. main문에서 어떻게 사용하느냐의 차이이다. 아래의 예시를 보면 이해가 될 것이다.

1
2
3
4

 5
6
7
8
9
10
11
12
void show_all(struct Book* library, int total_number);
 
---- main 문에서 ---
 
struct Book library[100]; 로 선언을 했다면
show_all(library, total_book_number); 
    이렇게 넘겨야 하고
 
struct Book book[100];이렇게 선언을 했다면
show_all(&book, total_book_number); 
    이렇게 넘겨야 한다!!
cs


 그러면 구조체 배열을 넘겼다하고, i번째의 구조체에 접근해서 그 구조체의 멤버들을 바꾸고 싶다고 하자. 간단히 각 구조체의 모든 멤버들을 print하는 함수라고 했을 때, 나는 처음에 이렇게 생각을 했었다. 


1
2
3
4
5
6
7
8
9
10
11
12
void show_all(struct Book* library, int total_number) {
    for (int i = 0; i < total_number; i++) {
        printf("번호 : %d // 책 이름 : %s // 지은이 : %s // 출판사 : %s //",
 i, (library)[i]->name, (library)[i]->author, (library)[i]->pub);
        if ((library)[i]->borrowed) {
            printf(" 대출중\n");
        }
        else {
            printf(" 대출 가능\n");
        }
    }
}
cs


 (library)[i]->name 이렇게!! 그런데 애초에 문법 오류가 뜨는 것이다!! 그래서 이렇게 고쳐 보았다. 


1
2
3
4
5
6
7
8
9
10
11
void show_all(struct Book* library, int total_number) {
    for (int i = 0; i < total_number; i++) {
        printf("번호 : %d // 책 이름 : %s // 지은이 : %s // 출판사 : %s //",
 i, (library + i)->name, (library + i)->author, (library + i)->pub);
        if ((library + i)->borrowed) {
            printf(" 대출중\n");
        }
        else {
            printf(" 대출 가능\n");
        }
    }
}

cs


 아하!! 이렇게 쓰는 거구만~ 깨달음을 얻었지만, 사실 이렇게 쓰는 경우가 많을지는 모르겠다. 그래서 이렇게 글을 남겨 나중에 할 고생을 방지해 본다.