

구조체는 자기 자신과 동일한 타입의 구조체를 가리키는 포인터 를 포함할 수 있습니다. 이를 활용하여 연결 리스트와 같은 자료구조를 구현할 수 있습니다.
#include <stdio.h>, int main(void), return 0; 등 구문은 특별히 필요하지 않은 경우 생략합니다.#include <stdio.h>
struct song // 음악 정보를 저장할 구조체
{
char *title;
char *singer;
int year;
};
void print_playlist(struct song *s);
// struct song * 형의 포인터를 매개변수로 받는 함수
int main(void){
struct song playlist[5] = {
{"파노라마", "이찬혁", 2022},
{"Hello Mr. My Yesterday", "애쉬그레이", 2010},
{"센치해", "WINNER", 2016},
{"Autumn Dream", "엔플라잉", 2019},
{"라일락", "아이유", 2021}
};
print_playlist(playlist); // 배열명을 함수에 전달
return 0;
}
void print_playlist(struct song *s){
for (int i = 0; i < 5; i++){
// (s + i): 배열요소의 주소
// ->로 각 멤버에 접근
printf("%s - %s (%d)\n", (s + i) -> title, (s + i) -> singer, (s + i) -> year);
}
}
// [출력]
// 파노라마 - 이찬혁 (2022)
// Hello Mr. My Yesterday - 애쉬그레이 (2010)
// 센치해 - WINNER (2016)
// Autumn Dream - 엔플라잉 (2019)
// 라일락 - 아이유 (2021)
playlist는 배열의 첫 번째 요소의 주소로, struct song 구조체 변수를 가리킴print_playlist 함수는 struct song *형 포인터 매개변수 s를 통해 배열을 참조(s + i)로 각 배열 요소의 주소 접근(s + i) -> 멤버로 구조체의 멤버에 접근s[i].멤버, *(s + i).멤버도 동일 기능 수행#include <stdio.h>
// 자기 참조 구조체: 연결리스트의 노드
struct node {
int value; // 값을 저장
struct node *next; // 다음 노드를 가리킴
};
struct node 구조체는, 자신의 타입인 다른 struct node를 가리킬 수 있는 포인터 next를 포함// 위 코드에서 계속
int main(void){
struct node n1 = {41, 0}, n2 = {9, 0}, n3 = {33, 0};
struct node *head = &n1; // 첫 노드를 가리키는 포인터
// n1의 next 멤버는 n2를, n2의 next 멤버는 n3를 가리킴
n1.next = &n2;
n2.next = &n3;
// head가 가리키는 n1의 value 출력
printf("head의 값: %d\n", head -> value);
// head로 n2의 value 출력
printf("head.next의 값: %d\n", head -> next -> value);
// [출력]
// head의 값: 41
// head.next의 값: 9
// 아래 코드에서 계속

head는 첫 노드 n1을 가리킴n1.next는 n2를, n2.next는 n3를 가리킴next 포인터를 따라가며 나머지 노드를 사용할 수 있음 // 위 코드에서 main 함수 계속
struct node *curr = head; // 현재 노드를 가리키는 포인터
// 모든 노드의 값을 출력
while (curr != NULL){
printf("%d ", curr -> value); // curr가 가리키는 노드의 value 출력
curr = curr -> next; // curr가 다음 노드를 가리키게 함
}
// [출력]
// 41 9 33
return 0;
}

curr를 사용head와 동일하게 n1을 가리킴curr = curr -> next를 반복하며 다음 노드로 이동n3의 next 값은 0curr에 저장하면 curr은 널 포인터가 되어 반복 종료typedef: 형 재정의struct 예약어와 함께 쓰는 것은 불편typedef struct 구조체이름 새_자료형_이름struct 구조체이름 대신 새자료형이름 사용 가능#include <stdio.h>
struct price {
int mandu; // 만두의 가격
int soondae; // 순대의 가격
int hotteok; // 호떡의 가격
};
// struct price 형을 Price 형으로 재정의
typedef struct price Price;
int main(void){
Price p1 = {5000, 6000, 3000}; // Price형으로 초기화
Price *pp = &p1; // Price *형 포인터 선언, 초기화
printf("만두 가격: %d\n", (*pp).mandu);
printf("순대 가격: %d\n", pp -> soondae);
printf("호떡 가격: %d\n", pp -> hotteok);
// [출력]
// 만두 가격: 5000
// 순대 가격: 6000
// 호떡 가격: 3000
return 0;
}
typedef struct price {
int mandu; // 만두의 가격
int soondae; // 순대의 가격
int hotteok; // 호떡의 가격
} Price;
학생 5명의 국어, 영어, 수학 점수를 입력해 총점, 평균, 학점을 구하고 총점 순으로 정렬해 출력합니다. 학점은 평균이 90점 이상이면 A, 80점 이상이면 B, 70점 이상이면 C, 그 외는 F로 평가합니다.
struct student -> Student형 구조체로 관리Student형 구조체 배열을 선언해 5명의 학생 정보를 저장#include <stdio.h>
typedef struct student {
int id; // 학번
char name[10]; // 이름
int scores[3]; // 국, 영, 수 점수
int sum; // 총점
double mean; // 평균
char grade; // 학점
} Student;
void input_data(Student *); // 학생 정보 입력
void sort_data(Student *); // 총점순으로 내림차순 정렬
void swap(Student *ps1, Student *ps2); // 두 변수의 값 변경
void output_data(Student *); // 학생 정보 출력
int main(void){
Student s_list[5];
input_data(s_list);
printf("# 정렬 전 데이터...\n");
output_data(s_list);
sort_data(s_list);
printf("# 정렬 후 데이터...\n");
output_data(s_list);
}
void input_data(Student *ps){
for (int i = 0; i < 5; i++){
printf("학번: ");
scanf("%d", &(ps->id));
printf("이름: ");
scanf("%s", ps->name);
printf("국어, 영어, 수학 점수: ");
ps->sum = 0;
for (int j = 0; j < 3; j++){
scanf("%d", &(ps->scores[j]));
ps->sum += (ps->scores)[j];
}
ps->mean = ps->sum / 3.0;
if (ps->mean >= 90.0){
ps->grade = 'A';
} else if (ps->mean >= 80.0){
ps->grade = 'B';
} else if (ps->mean >= 70.0){
ps->grade = 'C';
} else {
ps->grade = 'F';
}
ps++;
}
}
// Selection Sort
void sort_data(Student *ps){
for (int i = 0; i < 5; i++){
int l_idx = i;
for (int j = i + 1; j < 5; j++){
if (ps[j].sum > ps[l_idx].sum){
l_idx = j;
}
}
swap(ps + i, ps + l_idx);
}
}
void swap(Student *ps1, Student *ps2){
Student temp;
temp = *ps1;
*ps1 = *ps2;
*ps2 = temp;
}
void output_data(Student *ps){
for (int i = 0; i < 5; i++){
printf("%4d %s ", ps->id, ps->name);
for (int j = 0; j < 3; j++){
printf("%4d ", ps->scores[j]);
}
printf("%5d %.1lf %c\n", ps->sum, ps->mean, ps->grade);
ps++;
}
}
// [입력]
// 학번: 315
// 이름: 홍길동
// 국어, 영어, 수학 점수: 80 75 90
// 학번: 316
// 이름: 이순신
// 국어, 영어, 수학 점수: 88 92 100
// 학번: 317
// 이름: 서하윤
// 국어, 영어, 수학 점수: 95 99 98
// 학번: 318
// 이름: 유관순
// 국어, 영어, 수학 점수: 84 70 72
// 학번: 319
// 이름: 박신혜
// 국어, 영어, 수학 점수: 60 65 40
// [출력]
// # 정렬 전 데이터...
// 315 홍길동 80 75 90 245 81.7 B
// 316 이순신 88 92 100 280 93.3 A
// 317 서하윤 95 99 98 292 97.3 A
// 318 유관순 84 70 72 226 75.3 C
// 319 박신혜 60 65 40 165 55.0 F
// # 정렬 후 데이터...
// 317 서하윤 95 99 98 292 97.3 A
// 316 이순신 88 92 100 280 93.3 A
// 315 홍길동 80 75 90 245 81.7 B
// 318 유관순 84 70 72 226 75.3 C
// 319 박신혜 60 65 40 165 55.0 F