프로그래밍/C

C언어 구조체

swedu 2023. 1. 17. 23:47
728x90
반응형

2023.1.17. 최초 작성

 

 

 

 

C언어에서 기본으로 제공하는 자료형들을 묶어서 만든 새로운 구조의 자료형을 구조체라고 한다.

프로그램에서 연관성 있는 데이터는 배열 자료구조에 담아 사용하는데, 배열은 같은 자료형만을 저장하기 때문에 아쉬운 부분이 있다.

 

구조체를 이용해 원하는 구조로 사용자 정의 자료형을 만들어 사용하면 C언어의 기본 자료형만을 사용하는 것 보다 훨씬 편리하다.

 

아래 코드는 구조체를 정의하고 배열로 선언하여 사용하는 예제이다.

#include <stdio.h>
#include <string.h>
typedef int _int;   // int 타입을 _int 타입으로 정의 (별칭)
typedef char _char; // char 타입을 _char 타입으로 정의 (별칭)
typedef struct student {
	_char name[10];
	_int kor;
	_int eng;
	_int math;
} stu;  // struct student 타입을 stu 타입으로 정의 (별칭)
void main() {
	stu students[3]; // 구조체 타입의 배열 선언
	strcpy(students[0].name, "kim");
	students[0].kor = 88;
	students[0].eng = 70;
	students[0].math = 90;
	strcpy(students[1].name, "lee");
	students[1].kor = 81;
	students[1].eng = 77;
	students[1].math = 85;
	strcpy(students[2].name, "hong");
	students[2].kor = 70;
	students[2].eng = 80;
	students[2].math = 73;
	for (int i = 0; i < sizeof(students) / sizeof(stu); i++) {
		printf("이름 : %s, ", students[i].name);
		printf("국어 : %d, ", students[i].kor);
		printf("영어 : %d, ", students[i].eng);
		printf("수학 : %d\n", students[i].math);
	}
}

[실행 결과]

이름 : kim, 국어 : 88, 영어 : 70, 수학 : 90

이름 : lee, 국어 : 81, 영어 : 77, 수학 : 85

이름 : hong, 국어 : 70, 영어 : 80, 수학 : 73

 

 

위 코드에서 typedef는 자료형을 다른 이름으로 정의하는 것으로 별칭을 만드는 개념이다.

구조체는 원래 사용할 때 struct student라고 써야 하는데 typedef에 의해 stu라는 짧은 이름으로 사용할 수 있다.

예제 코드에서는 구조체뿐 아니라 int_int, char_char이라고 타입을 정의하여 사용하였다.

 

아래 코드는 구조체 변수의 크기와 주소를 출력하는 예제이다.

#include <stdio.h>
struct student {  // 구조체 정의
	char name[10];
	int kor;
	int eng;
	int math;
	long tot;
	double avg;
};
void main() {
	struct student stu; // 구조체 변수 선언
	printf("stu의 주소 : %p, 크기 : %zd\n", &stu, sizeof(stu));
	printf("stu.name의 주소 : %p, 크기 : %zd\n", &stu.name, sizeof(stu.name));
	printf("stu.kor의 주소 : %p, 크기 : %zd\n", &stu.kor, sizeof(stu.kor));
	printf("stu.eng의 주소 : %p, 크기 : %zd\n", &stu.eng, sizeof(stu.eng));
	printf("stu.math의 주소 : %p, 크기 : %zd\n", &stu.math, sizeof(stu.math));
	printf("stu.tot의 주소 : %p, 크기 : %zd\n", &stu.tot, sizeof(stu.tot));
	printf("stu.avg의 주소 : %p, 크기 : %zd\n", &stu.avg, sizeof(stu.avg));
}

[실행 결과]

stu의 주소 : 000000EF810FFC58, 크기 : 40

stu.name의 주소 : 000000EF810FFC58, 크기 : 10

stu.kor의 주소 : 000000EF810FFC64, 크기 : 4

stu.eng의 주소 : 000000EF810FFC68, 크기 : 4

stu.math의 주소 : 000000EF810FFC6C, 크기 : 4

stu.tot의 주소 : 000000EF810FFC70, 크기 : 4

stu.avg의 주소 : 000000EF810FFC78, 크기 : 8

 

 

실행 결과를 보면 구조체 변수 stu의 전체 크기는 40byte이다.

그런데 내부의 용량을 보면 name10byte이고 나머지 kor, eng, math, tot4byte, 마지막으로 avg8byte이다. 모두 더하면 34byte이다.

 

6byte가 남는데 실행 결과의 주소의 간격을 확인해 보면 원인을 알 수 있다.

name의 크기가 10byte라고 출력되었으나 kor 사이의 주소 간격을 보면 12byte 차이가 난다.

tot의 크기가 4byte라고 출력되었으나 avg 사이의 주소 간격을 보면 8byte 차이가 난다.

 

구조체 변수 내부의 멤버들은 크기를 확보할 때 꼭 필요한 용량만 효율적으로 공간을 확보하는 것이 아니라 멤버들 중 큰 용량을 기준으로 배수의 크기만큼 할당하는 성향이 있다. 이것은 컴퓨터 입장에서 계산이 간단하기 때문이다.

용량의 낭비를 줄이는 대신 빠른 계산을 선택한 것이라고 할 수 있다.

 
 
728x90
반응형

 

728x90
반응형

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

C언어 함수 포인터  (0) 2023.01.19
C언어 포인터 배열과 배열 포인터  (0) 2023.01.19
C언어 문자열 다루기  (0) 2023.01.17
CONST를 이용한 상수화  (1) 2023.01.16
C언어 포인터 변수  (0) 2023.01.16