[자료구조 - C언어] 자료구조 제14강: Music Library Program(1), (2)

2022. 10. 27. 18:57CS/자료구조

728x90

//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎

 

0. 실행 예

  • Data file name? - 프로그램을 실행하면 어떤 데이터 파일을 load 할지 물어본다.
    • 입력 없이 Enter를 치면 데이터 파일로부터 데이터를 읽지 않고 프로그램을 실행
  • status - 저장된 모든 노래의 번호, 가수, 제목, 파일의 경로명을 출력
    • 노래의 번호는 입력 순서대로 번호 할당
    • 출력 시 가수 이름 알파벳 순으로 출력
      • 동일한 가수 이름이면 노래 제목으로 알파벳 순으로 출력
  • add - 가수 이름, 제목, 파일명으로 추가
    • 파일명은 지정하지 않아도 된다.
  • search - 가수 이름과 노래 제목으로 검색
    • 제목 없이 가수 이름만 검색해도 된다.
  • play 4 - 4번 노래를 play
  • remove 6 - 6번 노래를 목록에서 삭제
  • save as my_collection.txt - 목록을 파일에 저장
  • exit - 종료
  • 파일 형식
    가수#노래제목#경로#
    LESSERAFIM#Sour Grapes# #
    • 가수#노래제목#경로# 순서
    • #문자를 필드 간의 구분자
    • 존재하지 않는 항목의 경우 하나의 공백 문자로 표시
      • 모든 라인은 반드시 구분자로 끝난다.

 

1. 자료 구조

  • Artist - 한명의 가수를 표현하는 구조체
    • Artist 끼리 단방향 연결 리스트(next 필드)
    • head와 tail 필드로 SNode를 가리킨다.
  • 노드와 데이터의 분리 → 다양한 접근 경로를 제공하기 위해서
    • Song - 노래 정보를 담고 있는 구조체, 연결 리스트가 아닌 데이터 객체 역할
    • SNode - Node 역할, 하나의 SNode는 하나의 Song 객체를 가짐,  SNode 끼리는 양방향 연결 리스트, Song은 제목의 알파벳 순으로 정렬

  • Artist들을 이니셜로 분류해서 이니셜 각 그룹(’A’)을 하나의 단방향 연결리스트로(artist_directory) 저장
    • 모든 가수를 검색할 필요 없어짐
  • Artist의 이름의 알파벳 순으로 정렬
  • Artist의 head와 tail에 SNode가 연결되어 있고, 각각의 SNode는 각각의 Song 객체를 가짐

  • Song들을 “index를 SIZE로 나눈 나머지”가 동일한 것들끼리 분류하여
    • 32 % SIZE = 2
    • 12 % SIZE = 2
    • 62 % SIZE = 2
  • 동일한 그룹을 하나의 단방향 연결리스트로(index_directory) 저장
  • index_directory에는 SNode가 연결리스트로 저장되어 있고, 각각의 SNode는 각각의 Song 객체를 가짐
  • index로 정렬은 하지 않음
  • index_directory의 SNode는 Artist의 SNode와는 별개이지만, 같은 Song을 가리킬 수 있다.

 

2. 프로그램을 여러 개의 소스파일로 구성하기

  • C프로그램은 여러 개의 소스파일들로 구성된다.
  • 각각의 소스파일은 확장자.c 를 가진다.
  • 하나의 소스파일은 main이라는 이름의 함수를 가져야 한다.
  • 프로그램을 여러 개의 소스파일로 분할할 경우의 장점
    • 서로 연관된 함수들과 변수들이 하나의 파일에 있다: 전체 프로그램을 몇 개의 모듈로 구성하는 모듈화
      → 프로그램의 구조가 좀 더 알기 쉽고 명료
    • 수정된 파일만 개별적으로 컴파일 할 수 있으므로 컴파일 시간 절약
    • 소프트웨어 재사용 용이

2-1. 소스파일 구성

  • 서로 연관된 함수들과 변수들을 하나의 파일에 넣는다
    • main.c - 사용자와의 상호작용과 main함수
    • library.c - 프로그램의 중요한 기능
    • string_tools.c - string 처리 관련, 도구적 성격

2-2. 여러 개의 소스 파일로 분할할 경우 해결해야 할 문제점

  • c 프로그램의 4가지 구성 요소: 메크로, 타입 정의, 변수, 함수

2-2-1. 다른 파일에 정의된 함수, 메크로, 타입 정의

  • 어떻게 다른 파일에 정의되어 있는 함수를 호출?
  • 어떻게 다른 파일들이 메크로타입 정의를 공유?
    • header 파일과 source 파일을 분리한 후 다른 파일에서 header 파일을 include
    • .c 프로그램에서 .h 헤더 파일을 include 한다 == 파일에 추가된다.
    //library.h
    //library.c가 가진 것 중에서 다른 파일에서 사용되어야 하는 것들을 library.h 헤더 파일로 옮김
    
    #define MAX 100
    typedef struct song Song;
    struct song{
        ...
    };
    
    void add_song();
    void find_song();
    int remove_song();
    //library.c
    #include "library.h"
    
    void add_song()
    {...}
    void find_song()
    {...}
    int remove_song()
    {...}
    //main.c
    #include "library.h"
    
    void process_command(){
        ...
        add_song();
        ...
    }
    • 다른 소스 파일과 공유할 매크로, 타입 정의를 헤더 파일에 넣는다
    • 다른 소스 파일과 공유할 함수는 헤더 파일에는 프로토타입을, 소스파일에는 실제 구현을

2-2-2. 다른 파일에 정의되어 있는 변수

  • 어떻게 다른 파일에 정의되어 있는 변수를 사용?
    • 변수의 선언(declaration): 컴파일러에게 변수의 존재를 알려줌
    • 변수의 정의(definition): 실제로 메모리를 할당
    • 변수는 여러 번 선언될 수 있지만, 정의는 한 번만 해야 된다.
    • 선언과 정의를 동시에 하는 방법
      int i;
    • 정의하지 않고 선언만 하는 방법 - 컴파일러에게 변수가 다른 파일에 정의되어 있음을 알려주는 역할
      extern int i;
      extern int a[];    //배열의 크기를 지정할 필요 없음int i;
  • 공유 변수의 선언은 헤더 파일에 두고, 공유 변수를 사용하는 모든 소스 파일은 헤더 파일을 include, 소스 파일 중 오직 한 곳에서 공유 변수를 정의
  • 서로 다른 파일 간의 변수는 최대한 공유하지 않는 것이 좋다.
    //file.h
    extern int gloval_variable;    //변수 선언
    
    //file1.c
    #include "file.h"
    int gloval_variable;            //변수 정의
    printf("%d\n", gloval_variable++);
    
    //file2.c
    #include "file.h"
    printf("%d\n", gloval_variable++);

2-2-3. 중첩된 Include

//file1.h
#include "file3.h"

//file2.h
#include "file3.h"

//prog.c
#include "file1.h".   //file3.h 포함
#include "file2.h"    //file3.h 포함
  • prog.c 에서 file3.h가 2번 include 되며 중첩된 include 발생
  • 중복된 헤더 파일이 항상 오류인 것은 아니다
    • 매크로 정의, 함수 프로토타입, 그리고 외부 변수의 선언은 여러 번 중복되어도 상관없지만
    • 타입 정의가 중복되는 것은 컴파일러 오류를 야기
      • #ifndef - #endif 지시어 이용
        • #ifndef BOOLEAN_H BOOLEAN_H라는 메크로가 정의되어 있지 않으면 이후 문장은 유효, 정의되어 있다면 없는 것으로 취급
      //boolean.h
      
      #ifndef BOOLEAN_H   //파일 이름을 대문자로 바꿔서 쓰는 관습
      #define BOOLEAN_H   //BOOLEAN_H 메크로 정의
      
      //실제 내용
      #define TRUE 1
      #define FALSE 0
      typedef int Bool;
      
      #endif
      //여기까지                        

 

 

 

 


부경대학교 권오흠 교수님의 [c로 배우는 자료구조 및 여러 가지 예제 실습] 강의 정리입니다. 감사합니다.

https://www.youtube.com/watch?time_continue=1157&v=v1LuuJ97NJs&feature=emb_title 

 

728x90