C & C++/디딤돌 C언어

Part 25. 사용자 정의 동적 배열 사용(순차 보관, 인덱스로 보관)

언휴 2024. 1. 18. 08:52

Part 25. 사용자 정의 동적 배열 사용(순차 보관, 인덱스로 보관)

 

C언어 사용자 정의 동적 배열 사용, 순차 보관, 인덱스로 보관

91. 동적 배열 사용 예 – 동적 개체 정의

테스트를 위해 사용할 자료는 회원 번호와 이름을 멤버로 갖는 회원 데이터로 할게요.

typedef struct _Member Member;
#define MAX_NAME_LEN 20
struct _Member
{
    int mnum;
    char name[MAX_NAME_LEN+1];
};

그리고 동적으로 생성하는 함수, 소멸하는 함수, 출력하는 함수를 제공하세요.

◈ Member.h

#pragma once
typedef struct _Member Member;
#define MAX_NAME_LEN 20
struct _Member
{
    int mnum;
    char name[MAX_NAME_LEN+1];
};
Member *NewMember(int mnum,const char *name);
void DeleteMember(Member *member);
int MemberGetNum(Member *member);
const char *MemberGetName(Member *member);
void MemberView(Member *member);

회원 데이터를 동적으로 생성하는 함수에서는 먼저 동적으로 Member 형식 크기의 메모리를 할당받아야겠죠.
그리고 동적으로 생성한 Member 메모리의 멤버의 초기값을 입력 인자로 전달받은 값으로 설정하세요.

void MemberMember(Member *member,int mnum,const char *name);
Member *NewMember(int mnum,const char *name)
{
    Member *member = 0;
    member = (Member *)malloc(sizeof(Member));
    MemberMember(member,mnum,name);
    return member;
}
void MemberMember(Member *member,int mnum,const char *name)
{
    member->mnum = mnum;
    memset(member->name,0,sizeof(member->name));
    strncpy(member->name,name,MAX_NAME_LEN);
}

동적으로 생성한 회원 데이터를 소멸하는 함수에서는 자신의 메모리를 해제하세요.

void DeleteMember(Member *member)
{
   free(member);
}

그리고 회원 데이터를 콘솔 화면에 출력하는 함수도 제공하세요.

void MemberView(Member *member)
{
    printf("번호:%d 이름:%s\n",member->mnum,member->name);
}

◈ Member.c

#include "Member.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void MemberMember(Member *member,int mnum,const char *name);
Member *NewMember(int mnum,const char *name)
{
    Member *member = 0;
    member = (Member *)malloc(sizeof(Member));
    MemberMember(member,mnum,name);
    return member;
}
void MemberMember(Member *member,int mnum,const char *name)
{
    member->mnum = mnum;
    memset(member->name,0,sizeof(member->name));
    strncpy(member->name,name,MAX_NAME_LEN);
}
void DeleteMember(Member *member)
{
    free(member);
}
void MemberView(Member *member)
{
    printf("번호:%d 이름:%s\n",member->mnum,member->name);
}

92. 동적 배열 사용 예 – 순차 보관

먼저 순차적으로 보관하는 간단한 실습을 해 보아요.

순차적으로 보관할 때는 배열을 생성할 때 초기 저장소의 크기를 0으로 설정하세요.

EHArray *arr = 0;
arr = NewEHArray(0,0);

자료를 보관할 때는 PushBack 함수를 이용하세요.

EHArrayPushBack(arr,member);

보관한 자료를 확인할 때는 Begin함수와 End함수를 이용해 얻어온 Iterator 개체를 이용하세요.
Iterator의 간접 연산을 취하면 보관한 형식 개체를 참조할 수 있어요.
주의할 점은 자신이 보관한 형식으로 명시적 형변환을 취해야 한다는 거예요.

Iterator seek;
Iterator end;
Member *member = 0;
 
seek = EHArrayBegin(arr);
end = EHArrayEnd(arr);
 
for(   ; seek != end; ++seek)
{
    member = (Member *)(*seek);
    MemberView(member);
}

동적 배열에서는 배열 내부에서 동적으로 생성한 자료만 소멸하죠.
배열 외부에서 동적으로 생성한 자료를 소멸하세요.

for(   ; seek != end; ++seek)
{
    member = (Member *)(*seek);
    DeleteMember(member);
}
DeleteEHArray(arr);

93. 동적 배열 사용 예 – 인덱스로 보관

보관할 데이터의 개수가 정해져 있고 특정 키에 따라 보관할 인덱스를 결정할 수 있다면 GetAt, SetAt 함수를 이용하세요.

동적 배열을 생성할 때 최대 보관할 저장소의 크기와 초기값 0을 인자로 전달하세요.

int max = 0;
printf("최대 관리할 회원 수를 입력하세요.\n");
scanf_s("%d",&max);
arr = NewEHArray(max,0);

보관할 때는 SetAt을 이용하고 검색할 때는 GetAt을 이용하세요.
보관한 자료를 확인할 때는 GetAt 함수를 이용하는데 보관한 형식으로 형변환하여 사용하세요.

EHArraySetAt(arr,i,member);
member = (Member *)EHArrayGetAt(arr,i);
MemberView(member);

배열 외부에서 동적으로 생성한 자료를 소멸하세요.

for(i=0; i<max;i++)
{
    member = (Member *)EHArrayGetAt(arr,i);
    DeleteMember(member);
}

94. 사용하는 예제 코드

◈ Program.c

#include <stdio.h>
#include "Member.h"
#include "EHArray.h"
 
Member *MakeMember(int nth);
void ExampleSeq();
void ExampleIndex();
 
int main()
{
    ExampleSeq();
    ExampleIndex();
    return 0;
}
Member *MakeMember(int n)
{
    char name[MAX_NAME_LEN+1]="";  
    printf("%d 번 회원 이름 입력:",n);
    scanf_s("%s",name);  
    return NewMember(n,name);
}
void InputSeq(EHArray *arr);
void ViewSeq(EHArray *arr);
void EndSeq(EHArray *arr);
void ExampleSeq()
{
    EHArray *arr = 0;
    arr = NewEHArray(0,0);
    InputSeq(arr);    
    ViewSeq(arr);
    EndSeq(arr);
}
void InputSeq(EHArray *arr)
{
    int num = 0;
    Member *member = 0;
    printf("생성할 회원 번호:");
    scanf_s("%d",&num);
    member = MakeMember(num);
    EHArrayPushBack(arr,member);
}

void ViewSeq(EHArray *arr)
{
    Iterator seek;
    Iterator end;
    Member *member = 0;
    seek = EHArrayBegin(arr);
    end = EHArrayEnd(arr);
    for(   ; seek != end; ++seek)
    {
        member = (Member *)(*seek);
        MemberView(member);
    }
}
void EndSeq(EHArray *arr)
{
    Iterator seek;
    Iterator end;
    Member *member = 0;
 
    seek = EHArrayBegin(arr);
    end = EHArrayEnd(arr);
 
    for(   ; seek != end; ++seek)
    {
        member = (Member *)(*seek);
        DeleteMember(member);
    }
    DeleteEHArray(arr);
}
 
EHArray *MakeArray(void);
void InputIndex(EHArray *arr);
void ViewIndex(EHArray *arr);
void EndIndex(EHArray *arr);
void ExampleIndex()
{
    EHArray *arr = 0;
    arr = MakeArray();
    InputIndex(arr);
    ViewIndex(arr);
    EndIndex(arr);
}
 
 
EHArray *MakeArray(void)
{
    int max = 0;
    printf("최대 관리할 회원 수를 입력하세요.\n");
    scanf_s("%d",&max);
    return NewEHArray(max,0);
}
void InputIndex(EHArray *arr)
{
    int i = 0;
    Member *member = 0;
    int max = EHArrayGetCapacity(arr);
    for(i=0; i<max;i++)
    {
        member = MakeMember(i+1);
        EHArraySetAt(arr,i,member);
    }
}

void ViewIndex(EHArray *arr)
{
    int max = 0;
    int i = 0;
    Member *member = 0;
    max = EHArrayGetCapacity(arr);
    for(i=0; i<max;i++)
    {
        member = (Member *)EHArrayGetAt(arr,i);
        MemberView(member);
    }
}
void EndIndex(EHArray *arr)
{
    int max = 0;
    int i = 0;
    Member *member = 0;
 
    max = EHArrayGetCapacity(arr);
 
    for(i=0; i<max;i++)
    {
        member = (Member *)EHArrayGetAt(arr,i);
        DeleteMember(member);
    }
    DeleteEHArray(arr);
}