[C언어] 구조체

0

C언어

목록 보기
5/7


구조체

  • 구조체 란?
    하나 이상의 변수를 묶어서 좀 더 편리하게 사용 할 수 있도록 도와주는 도구
  • 지금까지는 자료형이 다른 변수를 사용하기 위해서는 하나하나 선언해줘야 했고, 이는 똑같은 구조의 변수를 여러번 사용해야 하는 프로그램을 만든다면 매우 불편할 것.

주소록을 만들기 위해 학생구조체를 정의하고 사용하는 코드를 만들어보자.

#include <stdio.h>

struct student
{
	char name[15];
	int s_id;
	int age;
	char phone_number[14];
};

int main()
{
	struct student goorm;
	
	printf("이름 : ");
	scanf("%s", goorm.name);
	printf("학번 : ");
	scanf("%d", &goorm.s_id);
	printf("나이 : ");
	scanf("%d", &goorm.age);
	printf("번호 : ");
	scanf("%s", goorm.phone_number);
	
	printf("이름 : %s, 학번 : %d, 나이 : %d, 번호 : %s\n",
    goorm.name, goorm.s_id, goorm.age, goorm.phone_number);
	
	return 0;
}

구조체는 새로운 자료형을 만드는 것과 같다고 할 수 있기 때문에, 위와 같이 보통 main함수 전에 선언합니다. 어떤 함수 안에 선언하면 그 함수 안에서만 사용할 수 있기 때문인데, 만약 main함수 안에 선언한다면 main함수 안에서만 사용 할 수 있습니다.

구조체 멤버

#include <stdio.h>

struct student
{
	int age;
	char phone_number[14];
	int s_id;
};

int main()
{
	struct student goorm = { .age = 20, .phone_number = "010-1234-5678", 10 };
	struct student codigm = { 22, "010-8765-4321"};

	printf("나이 : %d, 번호 : %s, 학번 : %d\n", 
    goorm.age, goorm.phone_number, goorm.s_id);
	printf("나이 : %d, 번호 : %s, 학번 : %d\n", 
    codigm.age, codigm.phone_number, codigm.s_id);

	return 0;
    //실행결과
    //나이 : 20, 번호 : 010-1234-5678, 학번 : 10
	//나이 : 22, 번호 : 010-8765-4321, 학번 : 0
}

구조체 멤버의 값을 main에서 선언을 할 때 대입해서 초기화 할 수 있습니다. 초기화 할때는 멤버 연산자 .중괄호 를 사용합니다. 구조체는 배열처럼 멤버 전체를 초기화 할 수 있고, 원하는 변수만을 초기화 할 수도 있습니다.
초기화 할때는 { .멤버이름 = 값} 과 같은 형태로 초기화 할 수 있으며, 멤버이름을 적지 않고 초기화 할 수도 있습니다. 멤버 이름을 적지 않을 때는 구조체를 정의했던 순서대로 값이 들어갑니다. 또한 값을 따로 넣어주지 않은 멤버는 0으로 초기화 됩니다.


typedef를 이용한 구조체 선언

  • 구조체를 선언할때 좀더 편리한 방법이 있는데, 바로 typedef를 이용하는것.
  • typedef를 사용할때는 구조체 이름을 생략할 수 있는데, 먼저 구조체 이름을 생략하지 않고 사용하는 방법에 대해서 알아보겠습니다.

typedef

  • typedef 키워드는 C언어에서 자료형을새롭게 이름을 붙일때 쓰는 키워드 입니다. typedef를 사용하면 main함수에서 구조체를 선언할때 매번 struct를 써줄 필요가 없습니다. 이 typedef를 사용할 때에는 구조체 별칭이 필요한데, 구조체 별칭은 구조체를 정의할때 중괄호 뒤에 써주면 됩니다.
#include <stdio.h>

typedef struct _Student {
	int age;
	char phone_number[14];
} Student;

int main(){
	Student goorm;
	
	printf("나이 : ");
	scanf("%d", &goorm.age);
	printf("번호 : ");
	scanf("%s", goorm.phone_number);
	
	printf("----\n나이 : %d\n번호 : %s\n----", goorm.age, goorm.phone_number);
	
	return 0;
}

이렇게 구조체 이름을 굳이 적지 않아도 구조체를 선언하고 사용하는 것이 가능합니다. 이렇게 구조체 이름을 따로 지정하지 않고 별칭만 사용하는 것을 익명 구조체라고 합니다. typedef를 이용해 구조체 별칭을 사용할 때에도 문법은 똑같으므로 멤버에 접근할 때는 똑같이 .를 이용하면 됩니다.


구조체 배열

  • 일반 변수에 배열이 있듯이 구조체에도 배열이 있습니다. 학생 정보를 저장하는 구조체를 만들어서 수십 수백명의 정보를 저장해야 한다면, 일반 변수처럼 구조체도 일일히 선언하는 것보다 배열을 쓰는 것이 훨씬 편리할 것입니다. 구조체 배열을 선언하는 방법은 일반적인 배열을 선언하는 방법과 같은데, 선언 및 초기화 하는 방법을 보도록 하겠습니다.
#include <stdio.h>

typedef struct {
	char name[30];
	int age;
} Student;

int main(){
	Student goorm[3] = { {.name = "해리 포터"}, 
    					{.name = "헤르미온느 그레인저"}, 
    					{.name = "론 위즐리"} };
	
	goorm[0].age = 10;
	goorm[1].age = 10;
	goorm[2].age = 10;
	
	printf("이름 : %s / 나이 : %d\n", goorm[0].name, goorm[0].age);
	printf("이름 : %s / 나이 : %d\n", goorm[1].name, goorm[1].age);
	printf("이름 : %s / 나이 : %d\n", goorm[2].name, goorm[2].age);
	
	return 0;
}

구조체 포인터

#include <stdio.h>

typedef struct {
    int s_id;
    int age;
} Student;

int main(){
    Student goorm;
    Student *ptr;
    
    ptr = &goorm;
    
    (*ptr).s_id = 1004;
    ptr->age = 20;
    
    printf("goorm의 학번 : %d, 나이: %d\n", goorm.s_id, goorm.age);
    //실행결과
    //goorm의 학번 : 1004, 나이: 20
}

(*ptr).s_idptr->s_id 로 표현 할 수 있다.

중첩 구조체

  • 구조체 안에 구조체를 선언 할 수 있다.
#include <stdio.h>

typedef struct {
	char name[15];
	int age;
} Teacher;

typedef struct {
	char name[15];
	int age;
	Teacher teacher; 
} Student;

int main(){
	Student Student;
	Teacher Teacher;
	
	Student.teacher.age = 30;
	Teacher.age = 40;
	
	return 0;
}

이런 식으로 다른 구조체를 멤버로 포함할 수 있는데, 이럴경우 Student만의 Teacher 구조체를 이용하고 싶으면 Student.teacher.age와 같이 연속으로 멤버를 참조해야 사용 할 수 있다.

왜 굳이 구조체를 중첩으로 넣어서 복잡하게 만들까?

이런 식으로 구조체를 중첩하게 되면 여러가지 정보를 관리하기에 용이하다. 예를 들어, 학교에는 학생마다 담임선생님이 있을 것입니다. 그 담임 선생님의 정보를 학생 정보마다 넣고 싶을 경우, 위와 같이 학생 구조체 안에 선생님 구조체를 넣어서 관리할 수 있음.

자기 참조 구조체

  • 구조체는 자기 자신을 참조하도록 자기와 똑같은 타입의 구조체를 멤버로 가질 수 있다.
typedef struct {
	char name[15];
	int age;
	struct Student *ptr; 
} Student;

연결리스트나 트리를 만들때 사용된다고 함.


구조체 실습

  • 3명의 학생 이름을 받아 평균 출력하기
#include <stdio.h>

typedef struct
{
	char name[20];
	int kor; // 국어
	int eng; // 영어
	int math; // 수학
	float avg; // 평균
} Student;

int main()
{
	Student S[3];
	
	for(int i=0;i<3;i++)
	{
		scanf("%s",S[i].name);
		scanf("%d",&S[i].kor);
		scanf("%d",&S[i].eng);
		scanf("%d",&S[i].math);
		S[i].avg = (S[i].kor+S[i].math+S[i].eng)/3.0;
	}

	for(int i=0;i<3;i++)
	{
		printf("%s ",S[i].name);
		printf("%.1f\n",S[i].avg);
	}
	
	return 0;
}


한 눈에 끝내는 c언어 기초 를 공부하고 작성한 글입니다.

0개의 댓글