01. 책을 구조체로 표현하자. 책에 대한 정보는 제목(문자열, 최대 100문자), 저자(문자열, 최대 100문자), 장르(열거형) 등으로 구성된다. 구조체 book을 이용하여 책 정보를 표현해보자. 책의 장르는 COMIC, SF, DOCU, DRAMA 중의 하나로 분류하고 열거형으로 구현된다. {"바람과 함꼐 사라지다", "마가렛 미첼", DRAMA }의 값을 가지는 구조체 변술르 생성했다가 다시 화면에 출력해보자.

#include <stdio.h>
typedef enum { COMIC, SF, DOCU, DRAMA }GENRE;
struct book {
char title[100];
char author[100];
GENRE type;
};
int main() {
char* genre[] = { "COMIC", "SF","DOCU", "DRAMA" };
struct book a = { "바람과 함께 사라지다", "마가렛 미첼", DRAMA };
printf("{ %s, %s, %s }", a.title, a.author, genre[a.type]);
}
02. 1번 문제에서 정의한 2개의 구조체를 받아서 책의 저자가 일치하는지를 검사하는함수 equal_author()을 작성해보자. equal_author()은 다음과 같은 원형을 가진다. b1과 b2의 저자가 같으면 1을 반환하고 그렇지 않으면 0을 반환한다. 함수를 작성하여 테스트 한다.

#include <stdio.h>
#include <string.h>
typedef enum { COMIC, SF, DOCU, DRAMA }GENRE;
struct book {
char title[100];
char author[100];
GENRE type;
};
int equal_author(struct book b1, struct book b2) {
if (strcmp(b1.author,b2.author)==0) { // b1.author == b2.author (X)
return 1;
}
return 0;
}
int main() {
char* genre[] = { "COMIC", "SF","DOCU", "DRAMA" };
struct book b1 = { "노인과 바다", "헤밍웨이", DRAMA };
struct book b2 = { "누구를 위하여 종을 울리나", "헤밍웨이", DRAMA };
printf("b1 = { %s, %s, %s} \n", b1.title, b1.author, genre[b1.type]);
printf("b2 = { %s, %s, %s} \n", b2.title, b2.author, genre[b2.type]);
printf("equal_author()의 반환값: %d \n",equal_author(b1, b2));
}
03. 구조체를 이용하여 이메일을 표현할 수 있는 구조체를 정의하고, 적당한 초기값을 부여하고 출력하는 프로그램을 작성하라, 구조체의 멤버는 제목(title), 수신자(sender), 발신자(receiver), 내용(content), 날짜(date), 우선순위(pri) 등으로 구성된다.

#include <stdio.h>
struct mail {
char title[50];
char sender[50];
char receiver[50];
char content[100];
char date[20];
int pri;
};
int main() {
struct mail a = { "안부 메일","chulsoo@hankuk.ac.kr","hsh@hankuk.ac.kr","안녕하십니까? 새해 복 많이 받으세요.","2023/1/1",1 };
printf("제목: %s \n", a.title);
printf("수신자: %s \n", a.sender);
printf("발신자: % s \n", a.receiver);
printf("내용: %s \n", a.content);
printf("날짜: %s \n", a.date);
printf("우선순위: %d \n", a.pri);
}
04. 구조체를 이용하여 복소수를 다음과 같이 정의하고 복소수의 덧셈을 수행하는 함수를 작성하고 테스트하시오.

#include <stdio.h>
struct complex {
double real;
double imag;
};
struct complex complex_add(struct complex c1, struct complex c2);
int main() {
struct complex c1, c2, c3;
c1 = (struct complex){ 1,2 };
c2 = (struct complex){ 2,3 };
c3 = complex_add(c1, c2);
printf("%.2f+%.2fi \n", c1.real, c1.imag);
printf("%.2f+%.2fi \n", c2.real, c2.imag);
printf("%.2f+%.2fi \n", c3.real, c3.imag);
}
struct complex complex_add(struct complex c1, struct complex c2) {
struct complex c3;
c3.real = c1.real + c2.real;
c3.imag = c1.imag + c2.imag;
return c3;
}
05. 2차원 평면에서 점은 (x, y) 좌표로 나타낼 수 있다. 따라서 하나의 점은 다음과 같은 point라는 구조체로 정의할 수 있다. 이 point 구조체를 받아서 두 점의 좌표가 일치하면 1을 반환하고 그렇지 않으면 0을 반환하는 함수 int equal(struct point p1, struct point p2)를 작성하고 테스트하라.

#include <stdio.h>
struct point {
int x, y;
};
int equal(struct point p1, struct point p2);
int main() {
struct point a = { 1,2 };
struct point b = { 3,5 };
if (equal(a, b)) {
printf("(%d, %d) == (%d, %d) \n", a.x, a.y, b.x, b.y);
}
else {
printf("(%d, %d) != (%d, %d) \n", a.x, a.y, b.x, b.y);
}
}
int equal(struct point p1, struct point p2) {
if ((p1.x == p2.x) && (p1.y == p2.y)) {
return 1;
}
return 0;
}
06. 앞의문제에서 equal() 함수를 다음과 같이 구조체의 포인터를 받도록 변경하여서 작성하고 테스트하라.

#include <stdio.h>
struct point {
int x, y;
};
int equal(struct point *p1, struct point *p2);
int main() {
struct point a = { 1,2 };
struct point b = { 3,5 };
if (equal(&a, &b)) {
printf("(%d, %d) == (%d, %d) \n", a.x, a.y, b.x, b.y);
}
else {
printf("(%d, %d) != (%d, %d) \n", a.x, a.y, b.x, b.y);
}
}
int equal(struct point *p1, struct point *p2) {
if ((p1->x == p2->x) && ((*p1).y == (*p2).y)) {
return 1;
}
return 0;
}
07. 2차원 공간에 있는 점의 좌표를 받아서 이 점이 속하는 사분면의 번호를 반환하는 함수 int quadrant(struct point p)를 작성하고 테스트하라. 앞의 point 구조체를 사용한다.

#include <stdio.h>
struct point {
int x, y;
};
int quadrant(struct point p);
int main() {
struct point p = { -1,2 };
printf("(%d, %d)의 사분면 = %d \n", p.x, p.y, quadrant(p));
}
int quadrant(struct point p) {
if (p.x > 0 && p.y > 0) return 1;
else if (p.x < 0 && p.y > 0) return 2;
else if (p.x < 0 && p.y < 0) return 3;
else return 4;
}
08. 원의 중심을 나타내는 point 구조체를 사용할 수 있다. 원을나타내는 circle 구조체를 정의해보자. 이 circle 구조체를 받아서 다음과 같은기능을 하는 함수를 작성하고 테스트해보자.

#define PI 3.14
(a) 원의 면적을 계산하는 함수 double area(struct circle c)
double area(struct circle c) {
return c.radius * c.radius * PI;
}
(b) 원의 둘레를 계산하는 함수 double perimeter(struct circle c)
double perimeter(struct circle c) {
return c.radius * 2 * PI;
}
(c) typedef을 사용하여 struct circle을 CIRCLE로 정의 한 후에 (a)와 (b)를 다시 작성해보자.
#include <stdio.h>
#define PI 3.14
struct point {
int x, y;
};
typedef struct circle {
struct point center;
double radius;
}CIRCLE;
double area(CIRCLE c);
double perimeter(CIRCLE c);
int main() {
CIRCLE c = { 0,0,10}; // {0,0,10} { .center.x = 0, .center.y = 0, .radius = 10} 둘다 가능
printf("원의 중심점: (%d, %d) \n", c.center.x, c.center.y);
printf("원의 반지름: %.0lf \n", c.radius);
printf("원의 면적=%.2lf \n", area(c));
printf("원의 둘레=%.2lf \n", perimeter(c));
}
double area(CIRCLE c) {
return c.radius * c.radius * PI;
}
double perimeter(CIRCLE c) {
return c.radius * 2 * PI;
}
09. 각각의 음식에 대하여 음식의 이름, 칼로리 정보를 구조체로 표현한다. 사용자가 하루 동안 먹은음식들을 입력받아 구조체의 배열에 저장하고 하루 동안 먹은 음식의 칼로리를 계산하는 프로그램을 작성해보자.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
struct food {
char name[100];
int calories;
};
int sum_calories(struct food* food_array, int size);
int main() {
struct food food_array[3] = { { "hambuger", 900 },{ "bulgogi", 500 },{ "sushi", 700 } };
int size = sizeof(food_array) / sizeof(struct food);
printf("총 칼로리=%d \n", sum_calories(food_array, size));
}
int sum_calories(struct food* food_array, int size) {
int sum = 0;
for (int i = 0; i < size; i++) { // sizeof 연산불가
sum += food_array[i].calories; // (food_array+i)->calories 도 가능
}
return sum;
}
// if 매개변수가 (struct food food_array[]) , (struct food *food_array) -> sizeof 연산 불가능
// 매개변수가 (char *s),(char s[]) 의 경우도 sizeof 불가 -> starlen 사용하기 (단, char *s[] 의 경우 가능)
10. 직원을 나타내는 구조체 employee가 사번(정수), 이름(문자열), 전화번호(문자열), 나이(정수) 등으로 구성된다. 구조체의 배열을 선언하고 10명의 데이터로 초기화해보자. 이중에서 나이가 20 이상 30이하인 직원을 찾아서 출력하도록 해보자. typedef을 사용하여서 구조체 타입을 정의해서 사용해보자.

#include <stdio.h>
typedef struct {
int num;
char name[100];
int age;
char tel[100];
}EMPLOYEE;
int main() {
EMPLOYEE people[10] = {
{ 1, "홍길동1", 20, "111-1111" },
{ 2, "홍길동2", 25, "111-1112" },
{ 3, "홍길동3", 60, "111-1113" },
{ 4, "홍길동4", 40, "111-1114" },
{ 5, "홍길동5", 50, "111-1115" },
{ 6, "홍길동6", 45, "111-1116" },
{ 7, "홍길동7", 32, "111-1117" },
{ 8, "홍길동8", 23, "111-1118" },
{ 9, "홍길동9", 29, "111-1119" },
{ 10, "홍길동10", 62, "111-1120" }
};
for (int i = 0; i < sizeof(people) / sizeof(people[0]); i++) {
if ((people[i].age >= 20) && (people[i].age <= 30)) {
printf("이름: %s 나이=%d \n", people[i].name, people[i].age);
}
}
}
11. 전화번호부를 구성하기 위하여 이름, 집전화번호, 휴대폰 번호로 구성되는 구조체를 정의한 후에 이 구조체의 배열을 선언하여 전화번호부를 구성한다. 3명의 데이터를 사용자로부터 받아서 저장하여 보라. 사용자로부터 이름을 입력받아서 전화번호를검색하는 프로그램을 작성해보자.

#include <stdio.h>
#include <string.h>
struct tel_book {
char name[20];
char home_tel[100];
char cel_tel[100];
};
int main() {
struct tel_book list[3];
char find_name[100];
int size = sizeof(list) / sizeof(list[0]);
for (int i = 0; i < size; i++) {
printf("이름을 입력하시오: ");
scanf("%s", list[i].name);
printf("집전화번호: ");
scanf("%s", list[i].home_tel);
printf("휴대폰 번호: ");
scanf("%s", list[i].cel_tel);
printf("\n");
}
printf("검색할 이름: ");
scanf("%s", find_name);
for (int i = 0; i < size; i++) {
if (strcmp(find_name, list[i].name) == 0) {
printf("집전화번호: %s \n", list[i].home_tel);
printf("휴대폰 번호: %s \n", list[i].cel_tel);
break;
}
}
}
12. 포커 게임에서 사용되는 카드를 구조체 card로 정의하고 52개의 카드를 구조체의 배열로 나타내라. 52개의 카드를 적절한 값으로 초기화 하고 값들을 출력하는 프로그램을 작성해보자. card 구조체는 다음과 같은 멤버값을 가진다고 가정해보자. 먼저 카드의 수는 정수로 표현되며 멤버의 이름은 value라고 하라. vlaue는 1부터 13까지의 값을 가질 수 있다. 카드의 타입은 하나의 문자로 표현되며 멤버의 이름은 suit라고 하라. suit는 'c', 'd', 'h', 's'의 값을 가질 수 있다.

#include <stdio.h>
struct card {
char suit;
int value;
};
int main() {
struct card cards[52];
int size_st = sizeof(cards) / sizeof(struct card);
int arr[] = { 'c', 'd','h', 's' };
int* p = arr;
for (int i = 0; i < size_st; i++) {
cards[i].suit = *p;
cards[i].value = (i % 13 + 1);
if ((i % 13 + 1) == 13) {
p++;
}
}
for (int i = 0; i < size_st; i++) {
printf("%d:%c ", cards[i].value, cards[i].suit);
}
}
13. 삼각형, 사각형, 원을 동시에 표현할 수 있는 공용체를 설계하라. 삼각형은 밑변과 높이, 사각형은 가로와 세로, 원은 반지름만을 저장하도록해보자. 현재의 공용체가 표현하고 있는 도형의 종류는 열거형 변수를 사용하여 나타낸다. 사용자로부터 도형의 종류와 도형의 데이터를 받아서 저장하여보자.

#include <stdio.h>
enum type_list{TRI, RECT, CIRC};
struct shape {
int type;
union {
struct { int base, height; }tri;
struct { int width, height; }rect;
struct { int radius; }circ;
}data;
};
int main() {
struct shape p;
printf("도형의 타입을 입력하시오(0,1,2): ");
scanf("%d", &p.type);
switch (p.type) {
case TRI:
printf("밑변과 높이를 입력하시오(예를 들어서 100 200): ");
scanf("%d %d", &p.data.tri.base, &p.data.tri.height);
printf("면적은 %d \n",(int)(0.5 * p.data.tri.base * p.data.tri.height));
break;
case RECT:
printf("밑변과 높이를 입력하시오(예를 들어서 100 200): ");
scanf("%d %d", &p.data.rect.width, &p.data.rect.height);
printf("면적은 %d \n", (int)(p.data.rect.width * p.data.rect.height));
break;
case CIRC:
printf("반지름을 입력하시오: ");
scanf("%d", &p.data.circ.radius);
printf("면적은 %d \n", (int)(3.14 * p.data.circ.radius * p.data.circ.radius));
break;
default:
printf("도형의 타입을 잘못 입력했습니다.");
}
}
// (int) 형변환 필수
// ex) printf("%d",3.14); - > 이상한 값 출력, printf("%d,(int)3.14);
14. 데이터베이스의 기능을 하는 간단한 프로그램을 작성하여보자. 이 프로그램은 mpc와 같은 음악파일을 관리한다. 사용자는 음악 파일을 추가, 삭제, 출력할수 있으며 제목을 가지고 특정 곡을 탐색할수 있다. 사용자 인터페이스는 다음과 같다.

#include <stdio.h>
#include <string.h>
enum genre_type {SONG, POP, CLASSIC, MOVIE};
enum menu_list { ADD = 1, PRINT, SEARCH, END };
typedef struct music_component {
char title[100];
char singer[100];
char location[100];
enum genre_type genre;
}MUSIC;
void print_menu();
void add(MUSIC *music, int count);
void print(MUSIC* music, int count);
void search(MUSIC* music, int count);
int main() {
MUSIC music[30] = { 0 };
enum menu_list user;
int count = 0;
while (1) {
print_menu();
scanf("%d", &user);
getchar(); // scanf() 다음에 gets_s를 쓰는 경우 getchar()로 버퍼를 비워야함
switch (user) {
case ADD:
add(music,count);
count++;
break;
case PRINT:
print(music,count);
break;
case SEARCH:
search(music,count);
break;
case END:
return 0; // switch문에서는 break로 무한반복문을 빠져나갈수 없으므로 goto 혹은 return 을 사용하여 종료한다.
default:
printf("메뉴에 없는 번호입니다. 다시 입력해주세요 \n");
}
printf("\n");
}
}
void print_menu() {
printf("================== \n");
printf("1. 추가 \n");
printf("2. 출력 \n");
printf("3. 검색 \n");
printf("4. 종료 \n");
printf("================== \n");
printf("정수값을 입력하시오: ");
}
void add(MUSIC* music,int count) {
printf("제목: ");
gets_s(music[count].title, sizeof(music[0].title));
printf("가수: ");
scanf("%s", music[count].singer);
printf("위치: ");
scanf("%s", music[count].location);
printf("장르(0:가요, 1:팝, 2:클래식, 3: 영화음악)");
scanf("%d", &music[count].genre);
}
void search(MUSIC *music, int count) {
char user[100];
char* genre_list[] = { "가요","팝","클래식","영화음악" };
printf("제목을 입력하시오: ");
gets_s(user, sizeof(user));
for (int i = 0; i < count; i++) {
if (strcmp(user, music[i].title) == 0) {
printf("제목: %s \n", music[i].title);
printf("가수: %s \n", music[i].singer);
printf("위치: %s \n", music[i].location);
printf("장르: %s \n", genre_list[music[i].genre]);
return;
}
}
}
void print(MUSIC *music,int count) {
char* genre_list[] = { "가요","팝","클래식","영화음악" };
for (int i = 0; i < count; i++) {
printf("제목: %s \n", music[i].title);
printf("가수: %s \n", music[i].singer);
printf("위치: %s \n", music[i].location);
printf("장르: %s \n", genre_list[music[i].genre]);
}
}
15. 도서관에서 소장 도서들을 관리할 수 있는 프로그램을 작성해보자. 책 정보를 저장할 수 있는 구조체를 정의한다. 구조체는책 번호, 제목, 대출 여부 등의 정보를 저장할 수 있어야 한다. 많은 책을 저장하려면 구조체의 배열을 생성하여야 할 것이다. 다음과 같은 메뉴를 생성한 후에 각 메뉴 항목을 구현한다. (14번과 푸는 방식이 동일하다)

#include <stdio.h>
#include <string.h>
enum menu_list {FIND_NUM = 1, FIND_WRITER, FIND_TITLE , ADD, PRINT_NUM , END };
typedef struct {
int num;
char writer[50];
char title[50];
}LIBRARY;
void print_menu();
void find_num(LIBRARY *book,int count);
void find_writer(LIBRARY* book, int count);
void find_title(LIBRARY* book, int count);
void add(LIBRARY* book, int count);
void print_num(int count);
int main() {
LIBRARY book[50];
enum menu_list u;
int count = 0;
while (1) {
print_menu();
scanf("%d", &u);
getchar();
switch (u) {
case FIND_NUM:
find_num(book, count);
break;
case FIND_WRITER:
find_writer(book, count);
break;
case FIND_TITLE:
find_writer(book, count);
break;
case ADD:
add(book, count);
count++;
break;
case PRINT_NUM:
print_num(count);
break;
case END:
return 0;
default:
printf("메뉴를 잘못 입력하였습니다. 다시 입력해주세요 \n");
}
printf("\n");
}
}
void print_menu() {
printf("======================\n");
printf(" 1. 도서 번호로 책 찾기 \n");
printf(" 2. 저자 이름으로 책 찾기 \n");
printf(" 3. 제목으로 책 찾기 \n");
printf(" 4. 새로운 책 추가 \n");
printf(" 5. 도서관이 소장한 도서의 수 표시 \n");
printf(" 6. 종료 \n");
printf("======================\n");
printf("메뉴 중 하나를 선택하시오: ");
}
void find_num(LIBRARY* book, int count) {
int user_num;
printf("도서 번호를 입력하시오: ");
scanf("%d", &user_num);
for (int i = 0; i < count; i++) {
if (user_num == book[i].num) {
printf("도서 번호: %d \n", book[i].num);
printf("저자 이름: %d \n", book[i].writer);
printf("제목: %d \n", book[i].title);
return;
}
}
printf("해당 도서 번호의 책이 없습니다.");
}
void find_writer(LIBRARY* book, int count) {
char user_writer[50];
printf("저자 이름을 입력하시오: ");
gets_s(user_writer, sizeof(user_writer));
for (int i = 0; i < count; i++) {
if (strcmp(user_writer, book[i].writer) == 0) {
printf("도서 번호: %d \n", book[i].num);
printf("저자 이름: %d \n", book[i].writer);
printf("제목: %d \n", book[i].title);
return;
}
}
printf("해당 저자의 책이 없습니다.");
}
void find_title(LIBRARY* book, int count) {
char user_title[50];
printf("제목을 입력하시오: ");
gets_s(user_title, sizeof(user_title));
for (int i = 0; i < count; i++) {
if (strcmp(user_title, book[i].title) == 0) {
printf("도서 번호: %d \n", book[i].num);
printf("저자 이름: %d \n", book[i].writer);
printf("제목: %d \n", book[i].title);
return;
}
}
printf("해당 제목의 책이 없습니다.");
}
void add(LIBRARY* book, int count) {
printf("도서 번호를 입력하시오: ");
scanf("%d", &book[count].num);
getchar();
printf("저자 이름을 입력하시오: ");
gets_s(book[count].writer, sizeof(book[count].writer));
printf("제목을 입력하시오: ");
gets_s(book[count].title, sizeof(book[count].title));
}
void print_num(int count) {
printf("도서관이 소장한 도서의 수는 %d 입니다. \n", count);
}
16. 어느 학교나 학기가 끝나면학과 내에서 가장 평점이 높은 학생을 선발하여서 장학금을 수여한다. 가장 평점이 높은 학생을 찾아서 학생의 이름과 학번, 평점을 화면에 출력하는 프로그램을 작성하여보자. 학생에 대한 정보는 구조체를 이용하여서 표현한다. 학생들이 여러 명이므로 구조체의 배열을사용하는 것이 좋겠다. 적당한 값으로 초기화를 시키자. 평점이최대인 학생을 찾는 알고리즘은정수의 배열에서 최대값을 찾는 것과 동일하다.

(방법 1)
#include <stdio.h>
struct student {
int number;
char name[50];
double score;
};
struct student list[] = { { 20180001, "홍길동", 4.2 },
{ 20180002, "김철수", 3.2 },
{ 20180002, "김영희", 3.9 } };
int main() {
struct student list[] = {
{ 20180001, "홍길동", 4.2 },
{ 20180002, "김철수", 3.2 },
{ 20180002, "김영희", 3.9 } };
int max = 0;
for (int i = 0; i < sizeof(list) / sizeof(list[0]); i++) {
if (list[i].score > list[max].score) {
max = i;
}
}
printf("평점이 가장 높은 학생은 (이름: %s, 학번: %d, 평점: %.2f)입니다. ", list[max].name, list[max].number, list[max].score);
}
(방법 2, 문제에서 원하는 풀이법)
#include <stdio.h>
struct student {
int number;
char name[50];
double score;
};
struct student list[] = { { 20180001, "홍길동", 4.2 },
{ 20180002, "김철수", 3.2 },
{ 20180002, "김영희", 3.9 } };
int main() {
struct student list[] = {
{ 20180001, "홍길동", 4.2 },
{ 20180002, "김철수", 3.2 },
{ 20180002, "김영희", 3.9 } };
struct student max = list[0];
for (int i = 0; i < sizeof(list) / sizeof(list[0]); i++) {
if (list[i].score > max.score) {
max = list[i];
}
}
printf("평점이 가장 높은 학생은 (이름: %s, 학번: %d, 평점: %.2f)입니다. ", max.name, max.number, max.score);
}'C' 카테고리의 다른 글
| [쉽게 풀어쓴 C언어 Express 개정 4판] 15장 Programming (0) | 2024.10.15 |
|---|---|
| [쉽게 풀어쓴 C언어 Express 개정 4판] 14장 Programming (14) | 2024.10.11 |
| [쉽게 풀어쓴 C언어 Express 개정 4판] 12장 Programming (7) | 2024.10.08 |
| [쉽게 풀어쓴 C언어 Express 개정 4판] 11장 Programming (5) | 2024.10.04 |
| [쉽게 풀어쓴 C언어 Express 개정 4판] 10장 Programming (4) | 2024.10.04 |