C 언어에서 구조체(structure)는 서로 다른 자료형의 변수들을 하나의 이름 아래 묶어 관리할 수 있게 해주는 강력한 기능입니다. 이 글에서는 구조체의 기본 개념부터 선언 방법, 구조체 변수 선언, 초기화 및 멤버 접근 방법까지 다양한 예제 프로그램과 함께 자세히 살펴보겠습니다.
구조체란 무엇인가?
구조체는 서로 다른 데이터 타입을 가진 변수들의 집합을 하나의 이름으로 그룹화한 것입니다. 예를 들어 책 정보를 저장할 때 페이지 수(int), 저자 이름(char 배열), 가격(float)처럼 성격이 다른 데이터를 하나의 단위로 다룰 수 있습니다.
구조체의 선언과 초기화
구조체를 선언하는 일반적인 형식은 다음과 같습니다.
struct tagname{
datatype member1;
datatype member2;
datatype member n;
};
각 요소의 의미는 다음과 같습니다.
- struct: 구조체를 정의하는 키워드
- tagname: 구조체의 이름을 지정
- member1, member2 ...: 구조체를 구성하는 데이터 항목들
예제
struct book{
int pages;
char author[30];
float price;
};
구조체 변수 선언 방법 3가지
구조체 변수는 다음과 같은 세 가지 방법으로 선언할 수 있습니다.
// 1) 구조체 정의와 동시에 변수 선언
struct book{
int pages;
char author[30];
float price;
}b;
// 2) 태그 이름 없이 변수 선언
struct{
int pages;
char author[30];
float price;
}b;
// 3) 구조체 정의 후 별도로 변수 선언
struct book{
int pages;
char author[30];
float price;
};
struct book b;
구조체의 초기화와 멤버 접근
구조체 멤버와 구조체 변수 사이의 연결은 멤버 연산자(member operator), 즉 마침표(.) 연산자를 통해 이루어집니다. 구조체를 초기화하는 방법은 크게 네 가지가 있습니다.
방법 1: 정의와 동시에 초기화
struct book{
int pages;
char author[30];
float price;
} b = {100, "balu", 325.75};
방법 2: 정의 후 변수 초기화
struct book{
int pages;
char author[30];
float price;
};
struct book b = {100, "balu", 325.75};
방법 3: 멤버 연산자(.) 사용
struct book{
int pages;
char author[30];
float price;
};
struct book b;
b.pages = 100;
strcpy(b.author, "balu");
b.price = 325.75;
문자형 배열인 author 멤버에는 대입 연산자(=)를 직접 사용할 수 없으므로, 반드시 strcpy() 함수를 이용해 문자열을 복사해야 한다는 점에 유의하세요.
방법 4: scanf() 함수로 입력받기
struct book{
int pages;
char author[30];
float price;
};
struct book b;
scanf("%d", &b.pages);
scanf("%s", b.author);
scanf("%f", &b.price);
위에서 선언한 구조체의 내용은 main 함수에서 다음과 같이 출력할 수 있습니다.
main(){
struct book b;
clrscr();
printf("enter no of pages, author, price of book");
scanf("%d%s%f", &b.pages, b.author, &b.price);
printf("Details of book are");
printf("pages =%d, author = %s, price = %f", b.pages, b.author, b.price);
getch();
}
심화 예제: 자기 참조 구조체
다음은 구조체 안에 자기 자신을 가리키는 포인터를 포함하는 자기 참조 구조체(self-referential structure) 예제입니다. 이러한 구조는 연결 리스트(linked list)와 같은 자료구조를 구현할 때 널리 활용됩니다.
#include<stdio.h>
struct aaa{
struct aaa *prev;
int i;
struct aaa *next;
};
main(){
struct aaa abc,def,ghi,jkl;
int x=100;
abc.i=0;
abc.prev=&jkl;
abc.next=&def;
def.i=1;
def.prev=&abc;
def.next=&ghi;
ghi.i=2;ghi.prev=&def;
ghi.next=&jkl;
jkl.i=3;
jkl.prev=&ghi;
jkl.next=&abc;
x=abc.next->next->prev->next->i;
printf("%d",x);
}
실행 결과
2
결과 분석: abc.next는 def를 가리키고, def.next는 ghi를 가리킵니다. 이후 ghi.prev는 다시 def를, def.next는 ghi를 가리키므로, 최종적으로 x에는 ghi의 i 값인 2가 저장되어 화면에 출력됩니다.