Language/C

C - Struct Array, pointer, 구조체 배열과 포인터

ShinyOcean 2021. 1. 28. 06:00

C언어를 주제로 한  열번째 포스팅은 구조체배열과 포인터에 대하여 다루어보겠습니다.

 

 

저번시간까지 여러가지 타입의 데이터를 저장할수 있는 구조체에 대하여 스터디 해보았습니다. 

이러한 구조체도 배열로 만들어 여러번 선언하지 않고 한번의 선언으로도 다수의 구조체 변수를 

사용할수 있습니다.

이번 포스팅은 구조체를 배열로 만들어 구조체배열에 접근하는 방법, 초기화하는방법, 이를 활용하는

방법에 대하여 다루어보겠습니다.

 

 

C 예제문제 12번 - 다음조건에 알맞은 프로그램을 작성하라.

p.606 
          struct
영화 -- 영화제목, 관객수
         
영화 5개 선정해서 struct 배열로 만들것!!!


init_movie(struct .... )
           
영화의 관객수를 기본 1000명으로 세팅함
           main
에서 for 루프로 각 영화에 대해 init 할 것


inc_attendance(struct ..xxxx, yyyy, zzzz)
함수는 
           
어떤 한 영화의 관객수를 zzzz(인자로 받은 어떤 값)만큼 더하기
           main
에서 두 세 개 영화의 관객수를 변경시켜보기.
           main
에서 모든 영화의 관객수에 2000명씩 더하기.

 

 

 

해결 과정)

 

Step1) movie 구조체 선언하기

p.606의 내용을 참고 하여 제목과 관객수를 포함하고 있는 구조체인 movie를 선언하였습니다

typedef를 사용하여 구조체의 선언과 동시에 movie라는 이름으로 타입을 정의 하였습니다.

 

typedef struct movie {

        char* title;       //제목

        int attendance;    //관객수

}movie;

 

Step2) 메인에서 movie구조체 배열을 선언하고  init_movieImformation() 함수로 영화명,관객수 초기화하기.

메인에서 movie 구조체를 번거롭게 다섯번 선언하는 것보다 유용하게 크기가 5인 배열로 선언하였고

movie movieArr[5];

init_movieImformation(movieArr);

 

이 구조체 배열의 주소를 매개변수로 들여와 각 원소의 titleattendance를 초기화 해줄 init_movieImformaition함수를 만들어서 초기화 해주었습니다,

void init_movieImformation(movie* m) {

        m->title = "명량";

        m->attendance = 17000000;

        (m + 1)->title = "신과함께";

        (m + 1)->attendance = 12000000;

        (m + 2)->title = "트랜스포머";

        (m + 2)->attendance = 9000000;

        (m + 3)->title = "암살";

        (m + 3)->attendance = 12700000;

        (m + 4)->title = "국제시장";

        (m + 4)->attendance = 11000000;

}

Init_movieImformation함수는 구조체 배열의 주소값을 매개변수로 받아들였고 주소값에 1씩더하여 배열의 다음인덱스로 접근하였습니다. 그렇게 접근한 다음 인덱스의 구조체에 title변수와 attendance변수 값을 초기화 하여주었습니다.

 

Step3) init_movie() 함수와 for문을 통해 기본 관객수를 1000명으로 모두 초기화 하기

init_movie 함수는 구조체의 포인터 값을 매개변수로 이용하여 직접 그 값을 초기화 해주었습니다. 구조체 멤버의 접은근 ->연산자를 통해 포인터로 받아들인 구조체의 멤버에 접근하였습니다. 그리고 값을 1000으로 초기화 해준후 아무것도 리턴 하지 않았습니다.

void init_movie(movie* m) {m->attendance = 1000;}.

 

Step4) inc_attendance() 함수를 선언하고 메인에서 호출하여 영화 두세개의 관객수 변경하기

inc_attendance 함수는 구조체의 포인터 값과 관객수를 더해줄 정수값을 매개변수로 받아 선언해주었습니다. 받아들인 구조체의 멤버에 step3와 마찬가지로 ->연산자를 통해 접근하였고, 접근한 변수 attendance에 매개변수로 받은 정수값을 더해주는 형식으로 함수를 코딩하였습니다. 그리고 리턴값은 없는 void타입으로 선언하였습니다.

void inc_attendance(movie* m, int n) {m->attendance += n;}

 

 

Step5) attendance_plus2000() 함수를 선언하고 메인에서 호출하여 모든 영화의 관객수 2000명씩 더하기

Attendance_plus2000함수는 step4와 마찬가지로 구조체의 포인터 값을 매개변수로 받아 들여 값을 증가시키는 과정은 동일 합니다 하지만, step4에서는 증가시킬값또한 매개변수로 받았지만 Attendance_plus2000함수는 구조체의 멤버 attendance에 정확히 2000만큼만 증가시킬것이기 떄문에 매개변수로 구조체의 포인터 값만 받아들입니다.

void attendance_plus2000(movie* m) {m->attendance += 2000;}

 

Step6) print_movieArr() 함수를 선언하고 메인에서 호출하여 초기화된 구조체 배열 출력하기.

Print_movieArr함수는 배열로 선언된 구조체 5개에 초기화 되어있는 멤버들을 화면에 출력 하는 함수 입니다. 구조체 배열을 매개변수로 받아들이고 함수내에서 받아들인 매개변수안의 값을 보기좋게 출력합니다. 5개원소를 같는 구조체배열 안에 값을 순서대로 출력해야 하기 때문에 for루프를 이용하였습니다.

void print_movieArr(movie Arr[]) {

        for (int i = 0; i < 5; i++) {

                 printf("title : %s\nattendance : %d\n\n", Arr[i].title, Arr[i].attendance);

        }

}

Final step) main 함수 내에서 문제정의에 언급되어있는내용에 맞게 함수를 호출하고 결과를 화면에 출력하기

main함수 안에는 지금까지 선언한 함수들이 사용될때마다 print_movieArr함수를 사용하여 달라지는 결과를 화면에 출력하여 주었습니다.

int main(void) {

        movie movieArr[5];

        init_movieImformation(movieArr);

        print_movieArr(movieArr);

 

        for (int i = 0; i < 5; i++) {

                 init_movie(movieArr+i);

        }

        printf("--------------init_movie함수 사용이후-------------------\n\n");

        print_movieArr(movieArr);

 

        inc_attendance(movieArr+1, 100);

        inc_attendance(movieArr+2, 300);

        inc_attendance(movieArr+3, 500);

        printf("--------------inc_attendance함수 사용이후-------------------\n\n");

        print_movieArr(movieArr);

 

        for (int i = 0; i < 5; i++) {

                 attendance_plus2000(movieArr+i);

        }

        printf("--------------attendance_plus2000함수 사용이후-------------------\n\n");

        print_movieArr(movieArr);

        return 0;

}

 

 

 

전체 코드)

 

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

typedef struct movie {

        char* title;       //제목

        int attendance;    //관객수

}movie;

void init_movie(movie* m) {m->attendance = 1000;}

void attendance_plus2000(movie* m) {m->attendance += 2000;}

void inc_attendance(movie* m, int n) {m->attendance += n;}

void print_movieArr(movie Arr[]) {

        for (int i = 0; i < 5; i++) {

                 printf("title : %s\nattendance : %d\n\n", Arr[i].title, Arr[i].attendance);

        }

}

void init_movieImformation(movie* m) {

        m->title = "명량";

        m->attendance = 17000000;

        (m + 1)->title = "신과함께";

        (m + 1)->attendance = 12000000;

        (m + 2)->title = "트랜스포머";

        (m + 2)->attendance = 9000000;

        (m + 3)->title = "암살";

        (m + 3)->attendance = 12700000;

        (m + 4)->title = "국제시장";

        (m + 4)->attendance = 11000000;

}

int main(void) {

 

        movie movieArr[5];

        init_movieImformation(movieArr);

        print_movieArr(movieArr);

 

        for (int i = 0; i < 5; i++) {

                 init_movie(movieArr+i);

        }

        printf("--------------init_movie함수 사용이후-------------------\n\n");

        print_movieArr(movieArr);

 

        inc_attendance(movieArr+1, 100);

        inc_attendance(movieArr+2, 300);

        inc_attendance(movieArr+3, 500);

        printf("--------------inc_attendance함수 사용이후-------------------\n\n");

        print_movieArr(movieArr);

 

        for (int i = 0; i < 5; i++) {

                 attendance_plus2000(movieArr+i);

        }

        printf("--------------attendance_plus2000함수 사용이후-------------------\n\n");

        print_movieArr(movieArr);

 

        return 0;

}

 

 

 

 

결과 콘솔)