구조체 재정의
struct만을 활용해 구조체를 정의할 수 있지만 typedef를 활용하면 구조체를 데이터 타입과 같이 활용할 수 있다.
// typedef struct (구조체_이름) { 구조체_필드 } 구조체_자료형_이름;
typedef struct {
int num;
char string[5];
} NewStruct;
int main(void)
{
NewStruct var;
return 0;
}
구조체 포인터
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x;
int y;
} Point;
void InitStruct(Point*);
int main(void)
{
Point* p = (Point*) malloc(sizeof * p);
if (p == NULL) return -1;
InitStruct(p);
printf("(%d, %d)\n", p->x, p->y);
free(p);
return 0;
}
void InitStruct(Point* p)
{
(*p).x = 3;
p->y = 7;
}
구조체를 복사해 함수로 전달할 수도 있지만, 구조체가 큰 경우 메모리 공간이 낭비된다는 단점이 있다. 따라서 구조체의 포인터를 넘겨 구조체를 조작할 수 있다.
#include <stdlib.h>
// 구조체* 포인터_변수 = (구조체*) malloc(메모리_)
Point* p = (Point*) malloc(sizeof * p);
if (p == NULL) return -1;
free(p);
구조체 포인터를 선언하기 위해서는 <stdlib.h>의 malloc을 이용한 동적 할당이 필요하다. 만약 정상적으로 할당이 되지 않으면 NULL 포인터를 가리킨다. 포인터를 사용한 후 free를 통해 해제할 수 있다.
void InitStruct(Point* p)
{
(*p).x = 3;
p->y = 7;
}
포인터를 통해 접근할 때 1) '간접참조(*) + 멤버 접근(.)'을 통해 접근하거나 2) '포인터->맴버'를 통해 접근할 수도 있다.
연결 리스트
#include <stdio.h>
typedef struct list {
int item;
struct list* next;
} Node;
int main(void)
{
Node a = { 1, 0 }, b = { 2, 0 }, c = { 3, 0 };
a.next = &b;
b.next = &c;
Node* head = &a;
Node* current = head;
while (current != NULL) {
printf("%d ", current->item);
current = current->next;
}
return 0;
}
초기 상태는 위와 같은 형태로 각각의 Node가 독립적으로 선언되어 있다. 하지만 포인터를 연결시키면 연결 리스트와 같은 형태로 만들 수 있다.