구조체라는 것은 하나 이상의 변수(포인터 변수와 배열 포함)를 묶어서 새로운 자료형을 정의하는 도구입니다. 즉, 구조체를 기반으로 우리는 새로운 자료형을 정의할 수 있습니다.

예를 들어 학생관리용 프로그램을 만든다고 하면 학생에 관련된 데이터를 저장합니다. (ex.학번, 나이, 학년, 반, 성별) 여러명의 학생의 데이터를 저장하고 관리하려면 어떻게 해야 할까요?
각각의 저장공간을 만드는 방법
ex)
int no1, no2, no3, no4, ...
int age1, age2, age3, age4, ...
int grade1, grade2, grade3, grade4, ...
int classNum1, classNum2, classNum3, classNum4, ...
unsigned char Gender1, Gender2, Gender3, Gender4, ...
배열을 이용하는 방법
ex)
int noArray[100];
int ageArray[100];
int gradeArray[100];
int classNumArray[100];
unsigned char GenderArray[100];
위에 두 방법은 데이터 하나하나에 접근하기도 힘들고 관리하기도 힘듭니다. 이럴 때 사용할 수 있는게 구조체라는 사용자 정의 자료형입니다.
구조체를 쉽게 풀어서 설명한다면 서로 연관성 있는 데이터를 하나로 묶어서 새로운 DataType을 만들어주는 기능이라고 생각하시면 됩니다.
구조체 선언은 아래와 같이 같은 카테고리에 넣을 변수들을 모아서 하나의 자료형이름으로 선언해주면 됩니다. 또한, 구조체는 두개 이상 선언이 가능합니다.
struct (구조체명)
{
(DataType1) (변수1);
(DataType2) (변수2);
}(구조체 변수 이름); <- 구조체 선언과 동시에 구조체 변수 선언이 가능합니다.
예시1)
struct Student { int no; int age; int grade; int classNum; unsigned char Gender; } student1; <- 구조체 자료형 변수선언 (Student student1; 과 동일)
예시2)
struct tagStudent { int no; int age; int grade; int classNum; unsigned char Gender; }; typedef struct tagStudent Student -> typedef 선언으로 구조체이름을 바꿀 수 있습니다. 여기 같은 경우에는 tageStudent를 Student로 바꿨습니다.
예시3)
typedef struct tagStudent { int no; int age; int grade; int classNum; unsigned char Gender; } Student; <- 구조체선언과 typedef선언은 한번에 가능합니다.
또한, 구조체안에서 구조체변수 선언도 가능합니다.
구조체는 배열과 많이 닮아 있지만, 차이점이 명확합니다. 배열은 요소마다 DataType이 같고 특정 요소에 접근하기가 힘들다는 단점이 있습니다. 구조체는 DataType이 다양하고 특정 요소에 접근하기가 너무나도 쉽습니다. 하지만 구조체와 다르게 배열은 모든 요소에 접근할 때 배열이 훨씬 빠르고 간단하게 접근이 가능합니다. 이것이 배열을 사용하는 이유입니다.
그럼 구조체를 이용한 몇가지 예시를 보도록 하겠습니다. 예시를 보시면 어떤식으로 사용하는지가 눈에 보일것 입니다.
에시1#include <stdio.h> struct tagCar { char modelName[30]; //구조체 안에 변수들을 '구조체 멈버' 라고 합니다. int speed; int limitSpeed; int wheelCount; }; typedef struct tagCar Car; int main() { Car car = { "에쿠스", 70, 220, 4 }; printf("모델명: %s\n현재속도: %d\n최고속도: %d\n바퀴수: %d\n", car.modelName, car.speed, car.limitSpeed, car.wheelCount); //구조체 멤버에 접근할 때는 .(period)연산자를 사용합니다. Car car2; printf("자동자 모델명을 입력하세요: "); scanf_s("%s", car2.modelName, sizeof(car2.modelName)); printf("현재 속도를 입력하세요: "); scanf_s("%d", &car2.speed); printf("최대 속도를 입력하세요: "); scanf_s("%d", &car2.limitSpeed); printf("바퀴수를 입력하세요: "); scanf_s("%d", &car2.wheelCount); printf("모델명: % s\n현재속도 : % d\n최고속도 : % d\n바퀴수 : % d\n", car2.modelName, car2.speed, car2.limitSpeed, car2.wheelCount); return 0; }
결과1모델명: 에쿠스 현재속도: 70 최고속도: 220 바퀴수: 4 자동자 모델명을 입력하세요: 벤츠 현재 속도를 입력하세요: 120 최대 속도를 입력하세요: 240 바퀴수를 입력하세요: 4 모델명: 벤츠 현재속도 : 120 최고속도 : 240 바퀴수 : 4
예시2#include <stdio.h> typedef struct tagAnimal { int type; //0:소, 1:돼지, 2:닭 char name[30]; float weight; float age; }Animal; int main() { Animal animalArray[10]; //구조체 배열 : 모든 요소의 DataType이 Animal이다. int length = sizeof(animalArray) / sizeof(animalArray[0]); for (int i = 0; i < length; i++) { int select = i % 3; switch (select) { case 0: sprintf(animalArray[i].name, "소_%d", i); animalArray[i].type = 0; animalArray[i].weight = 200 + (i * 3); animalArray[i].age = ((i + 1) * 10) % 5 + 2; break; case 1: sprintf(animalArray[i].name, "돼지_%d", i); animalArray[i].type = 2; animalArray[i].weight = 180 + (i * 3); animalArray[i].age = ((i + 1) * 10) % 5 + 2; break; case 2: sprintf(animalArray[i].name, "닭_%d", i); animalArray[i].type = 2; animalArray[i].weight = 4 + (i * 3); animalArray[i].age = ((i + 1) * 10) % 5 + 2; break; } } for (int i = 0; i < length; i++) { switch (animalArray[i].type) { case 0: printf("소:\n"); printf("이름: %s\n", animalArray[i].name); printf("몸무게: %f\n", animalArray[i].weight); printf("나이: %f\n", animalArray[i].age); break; case 1: printf("돼지:\n"); printf("이름: %s\n", animalArray[i].name); printf("몸무게: %f\n", animalArray[i].weight); printf("나이: %f\n", animalArray[i].age); break; case 2: printf("닭:\n"); printf("이름: %s\n", animalArray[i].name); printf("몸무게: %f\n", animalArray[i].weight); printf("나이: %f\n", animalArray[i].age); break; default: printf("Animal Type Error\n"); break; } } return 0; }
결과소: 이름: 소_0 몸무게: 200.000000 나이: 2.000000 닭: 이름: 돼지_1 몸무게: 183.000000 나이: 2.000000 닭: 이름: 닭_2 몸무게: 10.000000 나이: 2.000000 소: 이름: 소_3 몸무게: 209.000000 나이: 2.000000 닭: 이름: 돼지_4 몸무게: 192.000000 나이: 2.000000 닭: 이름: 닭_5 몸무게: 19.000000 나이: 2.000000 소: 이름: 소_6 몸무게: 218.000000 나이: 2.000000 닭: 이름: 돼지_7 몸무게: 201.000000 나이: 2.000000 닭: 이름: 닭_8 몸무게: 28.000000 나이: 2.000000 소: 이름: 소_9 몸무게: 227.000000 나이: 2.000000