Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

나의 IT일지

구조체 기본 본문

프로그래밍 언어/C언어

구조체 기본

세레프 2023. 3. 1. 07:10

 우리는 배열을 통해 변수를 묶어서 데이터를 관리한다. 배열같은 경우는 같은 자료형의 변수만 묶어서 사용할 수 있다. 하지만, 우리는 데이터의 자료형이 다른 변수를 한번에 묶어서 관리해야 하는 경우가 존재한다. 예를들면, 어느 선생님들의 이름과 성별, 전화번호나 주소등등 개인정보를 저장할 경우, 서로 다른 배열을 만들어서 저장해야한다. 

#include<stdio.h>
#include<string.h> // strcmp함수를 사용하기 위한 헤더파일

void find(char*);

void main() {
	char name[100];
	int a;
	printf("이름 입력:");
	scanf("%s", name);
	find(name);
}

void find(char* find_name){
	char* name[] = { "이창호", "김성주", "고성진" };
	char* address[] = { "서울특별시","부산광역시","인천광역시" };
	char* tel[] = { "aaaa-bbbb","abcd-efgh","cccc-dddd" };
	char* lesson[] = { "c언어","linux","Cisco" };
	long* birth[] = { 850217,900418,891130};



	int i;
	for (i = 0; i < 3; i++) {
		if (!strcmp(name[i], find_name)) {//두 문자열을 비교하는 함수
			printf("%s의 주소: %s\n", name[i],address[i]);
			printf("%s의 전화번호: %s\n", name[i], tel[i]);
			printf("%s의 강의: %s\n", name[i], lesson[i]);
			printf("%s의 생년월일: %d\n", name[i], birth[i]);

			return;
		}
	}
printf("입력한 이름이 목록에 없다.");	
}

 이렇게 각각의 배열로 데이터를 저장하여 사용하면, 한 선생님의 정보를 불러서 처리해야 할 때 모든 배열을 불러야 하는 문제점이 생긴다. 그래서 우리는 여러 자료형을 묶어서 사용할 수 있는 방법에 대해서 알아야 한다.

 

구조체

 구조체여러 자료형의 변수를 모아만든 사용자 정의 데이터 자료형으로, 데이터를 구분하는 속성멤버변수 멤버변수를 모아놓은 필드, 멤버변수에 저장되는 데이터레코드로 구성되어 있다.

 

 구조체를 만드는 방법은 구조체의 필드를 만드는 과정과 레코드를 저장 할 수 있는 변수를 만드는 과정으로 나뉜다.

구조체 자료형 생성방법(구조체 선언) 구조체 변수 생성방법
struct 구조체명{

    자료형 변수명1;  //멤버 변수명1
    자료형 변수명2;  //멤버 변수명2

};
struct 구조체명 변수명

 이때, struct는 예약어로, 구조체 선언이 끝나고 구조체명과 함께 사용하면 구조체형이라는 새로운 자료형이 된다. 즉, 구조체선언을 통해 필드의 구성을 저장하여 변수가 데이터를 저장할 수 있는 형태를 정의하는 자료형구조체형이라고 한다.

 

 필드 생성하는 방법은 "struct 구조체명"을 정의하는 것으로, 큰 틀을 만들고 그 안에 데이터를 구분 할 수 있는 멤버 변수을 만들어 자료형을 정의한다. 그리고 구조체 변수 생성방법에서는 구조체선언에서 선언된 구조체형의 틀을 기준으로 생성된 변수 속성 데이터를 저장할 수 있는 공간을 만든다.

 

 이때, 자료형 생성하는 코드프로그램 전체로 사용할 때는 main함수 밖에서 main함수 내에서만 사용할 때는 main함수 안에서 진행한다. 그리고 구조체에 변수를 생성하는 코드main함수 안에서 진행한다.

 

 추가적으로 구조체를 선언할 때, 같이 해당 구조체의 틀을 가진 변수를 선언할 수 있는데 방법은 다음과 같다.

  struct 구조체명{

    자료형 변수명1;  //멤버 변수명1
    자료형 변수명2;  //멤버 변수명2

}변수명;
 

 위의 방법은 구조체를 생성하면서 해당 구조체의 변수를 만드는 방법으로, 함수 외에서 선언할 경우에는 변수와 구조체를 전역으로 사용이 가능하며, 함수 내에서 선언 할 경우에는 해당 함수 내에서만 해당 변수와 구조체를 사용할 수 있다.

 

#include<stdio.h>

//선생님의 신상정보(이름 주소 전번 강의과목 생일)를 구조체로 저장
struct teacher {
	char name[11];    	//11byte
	char address[30]; 	//30byte
	char tel[11];     	//11byte
	char lesson[20];  	//20byte
	long birth;		//4byte
};

void main() {
	struct teacher teacher1;
	printf("sizeof(struct teacher):%d\n", sizeof(struct teacher)); 
    //구조체를 사용할 때에는 struct를 붙여야 함
	printf("sizeof(ter1):%d\n", sizeof(teacher1)); 
}

  구조체와 구조체형으로 저장공간 형태를 선언한 변수의 저장공간이 76byte로 동일 한 것을 알 수 있다. 이는 구조체를 구성하는 필드의 멤버변수의 합이며, 구조체는 기본 자료형을 이용해서 필드를 만들고, 변수 선언을 하면 필드의 멤버변수에 맞는 데이터를 저장하는 변수를 만들어 진다. 즉, 구조체가 큰 틀을 만들고 그것을 토대로 데이터를 저장할 수 있는 변수를 만들기 때문에, 구조체의 저장공간과 구조체형을 자료형으로 사용하는 변수의 저장공간이 같은 것이다.

#include<stdio.h>
#include<string.h>

void find(char*);

struct teacher {
	char name[11];   
	char address[30]; 
	char tel[11];     
	char lesson[20];  
	long birth;		 	
};

void main() {

	char name[100];
	int a;
	printf("이름 입력:");
	scanf("%s", name);
	find(name);
}

void find(char* find_name) {
	struct teacher teacher1 = { "이창호","서울특별시","aaaa-bbbb","C언어",850217 };
	struct teacher teacher2 = { "김성주","부산광역시","abcd-efgh","linux",900418 };
	struct teacher teacher3 = { "고성진","인천광역시","cccc-dddd","Cisco",891130 };

	int i;
	for (i = 0; i < 3; i++) {
		if (!strcmp(teacher1.name, find_name)) {
			printf("%s의 주소:%s\n", teacher1.name, teacher1.address);
			printf("%s의 전화번호:%s\n", teacher1.name, teacher1.tel);
			printf("%s의 강의과목:%s\n", teacher1.name, teacher1.lesson);
			printf("%s의 생일:%d\n", teacher1.name, teacher1.birth);
			return;
		}

		else if (!strcmp(teacher2.name, find_name)) {
			printf("%s의 주소:%s\n", teacher2.name, teacher2.address);
			printf("%s의 전화번호:%s\n", teacher2.name, teacher2.tel);
			printf("%s의 강의과목:%s\n", teacher2.name, teacher2.lesson);
			printf("%s의 생일:%d\n", teacher2.name, teacher2.birth);
			return;
		}

		else if (!strcmp(teacher3.name, find_name)) {
			printf("%s의 주소:%s\n", teacher3.name, teacher3.address);
			printf("%s의 전화번호:%s\n", teacher3.name, teacher3.tel);
			printf("%s의 강의과목:%s\n", teacher3.name, teacher3.lesson);
			printf("%s의 생일:%d\n", teacher3.name, teacher3.birth);
			return;
		}
	}
printf("입력한 이름이 목록에 없다.");	
}

 선생님의 개인정보에 접근할 때에는 "teacher.멤버 변수명"의 구조로 접근한다. 이는 변수의 내용에 접근할 때의 형태는 "변수명.멤버 변수명"이다. 

 

 그리고 구조체를 이용해 새로운 사람의 개인정보를 저장할 수 있다.

#include<stdio.h>

//선생님의 신상정보(이름 주소 전번 강의과목 생일)를 구조체로 저장
struct teacher {
	char name[11];    
	char address[30]; 
	char tel[11];     
	char lesson[20];  
	long birth;		  
};
void main() {
	struct teacher teacher2;
	printf("name:");
	scanf("%s", teacher2.name);
	printf("address:");
	scanf("%s", teacher2.address);
	printf("tel:");
	scanf("%s", teacher2.tel);
	printf("lesson:");
	scanf("%s", teacher2.lesson);
	printf("birth:");
	scanf("%d", &teacher2.birth);

	printf("선생님 이름:%s\n", teacher2.name);
	printf("선생님 주소:%s\n", teacher2.address);
	printf("선생님 전화번호:%s\n", teacher2.tel);
	printf("선생님 강의과목:%s\n", teacher2.lesson);
	printf("선생님 생일:%s\n", teacher2.birth);

}

 이때, 입력받은 생일을 저장할 때, "teacher2.birth"가 아닌 "&teacher2.birth"인것을 볼 수 있다. 이는 멤버 변수가 어떠한 자료형인가에 따라 달라지게 되는데, 문자열인 멤버 변수는 배열의 형태를 가지고 있기 때문에, "&"없이 주소로 접근이 가능하지만 정수형이나 실수형인 경우에는 "&"통해 접근해야 한다. 즉, "변수명.멤버 변수명"의 자료형은 멤버 변수의 자료형에 따라서 결정이 된다.

'프로그래밍 언어 > C언어' 카테고리의 다른 글

구조체 포인터  (1) 2023.03.03
구조체 배열  (1) 2023.03.02
동적 메모리 할당 2  (0) 2023.02.28
동적 메모리 할당 1  (0) 2023.02.25
포인터 배열과 배열 포인터  (0) 2023.02.24
Comments