본문 바로가기
C 언어

C 언어 9일차 : 구조체

by Detol 2022. 12. 30.

오늘은 구조체에 대해서 알아보겠습니다.

구조체란 다양한 데이터 타입의 변수를 하나의 이름을 묶어주는 것 입니다.

 

구조체의 선언 방식입니다.

예시를 보겠습니다.

 

예시입니다.  st라는 이름을 가진 구조체를 선언헀습니다.

이 안에는 int형 변수 a와 float형 변수 b, char형 변수 c, char형 배열 d 가 있습니다.

struct st 데이터 형은 int, float, char, 5개의 인덱스를 가진 문자형 배열의

데이터 값들을 합친 값이 됩니다.

4 + 4 + 1 + (1 * 5) = 14byte

 

 

예제를 보겠습니다.

struct test
{
    int a; 
    float b;
    char c;
    char d[5];
};

struct test t1;   //t1이라는 구조체 변수 선언

t1.a = 10;
t1.b = 1.1f;   // 값 뒤에 f ==> double이 아니라 float임을 알려주기 위해 사용 (기본이 double이기 때문에)
t1.c = 'A';
strcpy(t1.d, "abc");

printf("t1.a => %d\n", t1.a);
printf("t1.b => %f\n", t1.b);
printf("t1.c => %c\n", t1.c);
printf("t1.d => %s\n", t1.d);

구조체를 선언하고 선언한 구조체를 사용하기 위해

구조체 test 데이터 타입을 가진 변수 t1을 선언합니다.    // ( 메모리 할당 )

그 후에 구조체변수.변수이름 형식을 통해 (ex) t1.a)) 구조체 안의 구성체(구조체의 멤버 변수)에 값을 다 넣어줍니다

 

그 후에 값이 제대로 들어갔는지 확인하기 위해 printf() 함수를 통해 확인합니다.

 

 

다음 예제로 이름, 국어 점수, 영어점수를 입력받아 입력받은 정보와 국어, 영어점수의 평균 점수를 같이 출력하는 소스를 만들어 보겠습니다.

char name[10];
int kor;
int eng;
float avg;

printf("이름 : ");
scanf("%s", name, 9); 
//name의 인덱스 값이 10이기 때문에 9개의 단어까지 입력받을 수 있다는 정보를 알려줌

printf("국어 점수 : ");
scanf("%d", &kor);

printf("영어 점수 : ");
scanf("%d", &eng);

avg = (kor + eng) / 2.0f;    //double이 아니라 float임을 알려주기 위해 사용 (기본이 double이기 때문에)

printf("학생 이름 : %s\n", name);
printf("국어 점수 : %d\n", kor);
printf("영어 점수 : %d\n", eng);
printf("평     균 : %.2f\n", avg);

 

구조체를 사용하지 않고 작성한 소스입니다.

이와 같은 결과를 만드는 소스를 구조체를 이용해 만들어보겠습니다.

struct student {
    char name[15];
    int kor;
    int eng;
    float avg;
};

struct student st1;    //구조체 변수 선언

printf("이름 : ");
scanf("%s", st1.name, 14);    //이름을 st1.name에 저장

printf("국어 점수 : ");
scanf("%d", &st1.kor);    //국어 점수를 st1.kor에 저장

printf("영어 점수 : ");
scanf("%d", &st1.eng);    //영어 점수를 st1.eng에 저장

st1.avg = (st1.kor + st1.eng) / 2.0f;    //국어 점수와 영어 점수의 평균을 st1.avg에 저장

printf("이름 : %s\n", st1.name);
printf("국어점수 : %d\n", st1.kor);
printf("영어점수 : %d\n", st1.eng);
printf("평균 : %0.2f\n", st1.avg);

 

구조체는 각각 변수를 선언하여 통제하는 것보다 한 번에 통제하기 유리하기 때문에 사용합니다.

 

 

다음은 구조체 포인터에 대해서 설명하겠습니다.

구조체 포인터는 일반 포인터 변수 선언 방식과 동일합니다.

그 대신에 st.name 같은 구조체 변수 안의 구성체에 접근을 할 때

-> 라는 화살표 연산자를 사용합니다.

 

예제 보겠습니다.

struct student {
    char name[15];
    int kor;
    int eng;
    float avg;
};

struct student st1;    //구조체 변수
struct student* p;    //구조체 포인터 변수 선언

p = &st1;

printf("이름 : ");
scanf("%s", p->name, 14);

printf("국어 점수 : ");
scanf("%d", &p->kor);

printf("영어 점수 : ");
scanf("%d", &p->eng);

p->avg = (p->kor + p->eng) / 2.0f;

printf("이름 : %s\n", p->name);
printf("국어점수 : %d\n", p->kor);
printf("영어점수 : %d\n", p->eng);
printf("평균 : %0.2f\n", p->avg);

 

위의 예제와 같은 소스를 포인터를 사용해 작성한 소스입니다.

 

 

다음 예제입니다.

// 구조체 포인터와 동적 메모리 할당 함수를 이용하여
//이름, 나이를 입력받아 출력하는 소스를 작성
//ex)
//입력할 학생의 숫자는 : 2
//이름 및 나이는 : lee 20
//이름 및 나이는 : kim 30
//명단
//이름 : lee, 나이 : 20
//이름 : kim, 나이 : 30

struct student {
    char name[10];
    int old;
};

int count = 0; //입력받을 학생의 수

printf("입력할 학생의 수는 : ");
scanf("%d", &count);

struct student* p = (struct student*)malloc(sizeof(struct student) * count);

for (int i = 0; i < count; i++) {
printf("이름 및 나이는 : ");
scanf("%s %d", p[i].name, &p[i].old);
}

printf("명단\n");

for (int i = 0; i < count; i++) {
printf("이름 : %s, 나이 : %d\n", p[i].name, p[i].old);
}

동적할당을 이용하기 위해서는 <malloc.h>를 포함시켜야 합니다.

동적할당을 이용한 예제입니다. 

입력받을 학생의 수가 몇명인지 모르기 때문에 동적할당을 이용합니다.

댓글