'혼공 C언어' 17-1강 구조체
데이터 구조와 처리는 프로그래밍에서 어떻게 해야 프로그램에서 데이터를 잘 구성하고 처리할까라는 고민을 던지는 아주 중요한 파트다. 특히, 임베디드 프로그램이 필요로 하는 하드웨어(자율주행자 부품, IoT 제품, 심지어 무선 로봇 청소기)처럼 메모리 크기가 중요한 프로그램을 작성할 때는 메모리를 최소화할 방법을 고민해야 한다(서현우, 2023).
C 언어에서의 구조체(Struct)는 서로 다른 자료형의 데이터들을 하나로 묶어 단일 자료형으로 다루기 위해 사용한다. 또한 배열처럼 반복문을 이용해 많은 데이터를 효율적으로 처리할 수 있다. 구조체는 사용자가 만드는 자료형이다.
구조체(Structure)도 전역변수와 마찬가지로 main() 함수 앞에서 선언되면 프로그램 전체에서 사용할 수 있고, 함수 안에서 선언하면 지역변수처럼 함수 안에서만 쓸 수 있다. 구조체 선언은 특이하게 블록의 끝을 나타내는 } 뒤에 ;(세미콜론)을 찍으면 끝난다. 그 이후부터 사용자가 정의한 새로운 자료형을 컴파일러가 인식할 수 있다.
구조체는 선언하고 아래, 소스 코드에서처럼 구조체 변수를 선언하면 이 구조체 변수를 통해 구조체 내부의 멤버에 접근할 수 있다. 자바를 해봤더라면, 메인 메서드에서 멤버의 사용과 같이 멤버에 접근하는 게 동일하게 느껴질 것이다. 또한 DB SQL 쿼리문에서 Union 함수를 통해 두 개 테이블 합칠 때(join) 사용한 도트(.)와도 동일한 접근 방식이다.
구조체를 선언하고 멤버를 사용하는 방법
만약 아래 소스코드처럼 student 구조체에 신상명세에 관한 부분이 추가된다면 profile 구조체를 활용할 수 있다.
다른 구조체를 멤버로 갖는 구조체 사용
구조체는 복합 자료형의 데이터를 한 번에 저장하기 때문에, 구조체 멤버의 크기가 들쑥날쑥한 경우 멤버 사이에 패딩 바이트(Padding Byte)를 넣어 멤버를 가지런히 정렬한다. 이를 바이트 얼라이먼트(Byte Alignment)라고 한다.
아래 소스코드는 1바이트 크기의 자료형(short)인 num 멤버에 이어 8바이트 크기의 자료형(double)인 grade 멤버, 그리고 가장 큰 double형보다 작은 그 외 자료형의 멤버들을 선언했다.
그러면 자료형이 double인 멤버가 메모리를 할당하는 기준이 된다. 즉, struct student 구조체는 grade 멤버의 크기가 가장 크므로 8바이트가 기준 단위가 된다. 따라서 num 멤버, ch1 멤버, ch2 멤버만 첫 번째 8바이트 블록 내에 임의로 할당될 수 있다. 왜냐면 int 자료형 멤버인 score는 4바이트 단위로 끊어서 할당되기 때문에, 첫 블록의 어디에도 위치할 수 없다. 시스템마다 다르지만, 아래 두 번째 도식처럼 전체 크기는 32바이트인 구조체가 선언될 수 있다.
결국 멤버의 순서에 따라 구조체의 크기가 달라질 수 있으므로 패딩 바이트가 가장 작도록 구조체를 선언하면 메모리를 아낄 수 있다. 또는 위의 소스 코드에서 #include 헤더 및의 #pragma pack(1) 헤더 구문을 추가하여 바이트 얼라인먼트를 1로 설정가능(패딩 바이트가 필요 없음)하다.
'혼자 공부하는 C언어'의 17-1강의 소스코드를 직접 참고하려면 아래 필자의 깃헙(github)에서 직접 다운로드할 수 있다.
참조
서현우. (2023). 혼자 공부하는 C언어 (2nd ed., Vol. 1). 한빛미디어.