[22 - 23 구조체와 사용자 정의 자료형]
// [22-1]
// 1) 구조체가 필요한 이유를 설명하라.
// 서로 다른 타입, 크기의 변수들을 하나의 의미를 가지는 이름(타입명)으로 묶어 선언하여 다루기 쉽게 하기 위해서이다.
// 2) 구조체 정의의 의미를 설명하라.
// 서로 다른 종류의 데이터 및 배열을 묶는 배열이다.
// 3) 구조체 변수 선언의 의미를 설명하라. 구조체 정의와 구조체 변수 선언의 차이를 설명하라.
// 구조체 정의는 실체가 없는 사용자 정의 타입의 설계도이고, 구조체 변수 선언이 일어나면 그 때
// 구조체의 정의에 따라 메모리에 할당된다.
// 4) 이름, 학번, 주소를 멤버로 가지는 구조체를 선언하여 입력 및 출력하는 프로그램을 작성하라.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
int num;
char name[10];
char add[20];
} student;
int main(void) {
student stu;
printf("학번을 입력하시오: ");
scanf("%d", &stu.num);
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
printf("이름을 입력하시오: ");
fgets(stu.name, 10, stdin);
printf("주소를 입력하시오: ");
fgets(stu.add, 20, stdin);
printf("1.학번: %d\n", stu.num);
printf("2.이름: %s\n", stu.name);
printf("3.주소: %s", stu.add);
}
// 5) 자동차 모델, 번호판, 주행거리를 멤버로 가지는 구조체를 선언하여 입력 및 출력하는 프로그램을 작성하라.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
char model[10];
char name[10];
int ride;
} student;
int main(void) {
student stu;
printf("모델을 입력하시오: ");
scanf("%s", stu.model);
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
printf("번호판을 입력하시오: ");
scanf("%s", stu.name);
printf("주행거리를 입력하시오: ");
scanf("%d", &stu.ride);
printf("1.모델: %s\n", stu.model);
printf("2.번호판: %s\n", stu.name);
printf("3.주행거리: %d km", stu.ride);
}
// 6) 2차원 점의 좌표를 저장하는 구조체를 정의하고 사각형의 좌상단, 우하단의 좌표를 입력받아 사각형의 폭과 높이를 계산하는 프로그램을 작성하라.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
int x;
int y;
} point;
int main(void) {
point p1, p2;
printf("좌상단 좌표입력:");
scanf("%d %d", &p1.x, &p1.y);
printf("우하단 좌표입력:");
scanf("%d %d", &p2.x, &p2.y);
printf("사각형의 폭: %d\n", p2.x - p1.x);
printf("사각형의 높이: %d", p2.y - p1.y);
}
// 7) 구조체 변수의 멤버변수의 값을 교환하는 코드를 작성하시오.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
struct point {
int x;
int y;
};
int main(void) {
struct point p1 = { 10, 10 }, p2 = { 20, 20 };
struct point temp;
printf("교환전 P1의 좌표 : (%d, %d)\n", p1.x, p1.y);
printf("교환전 P2의 좌표 : (%d, %d)\n", p2.x, p2.y);
temp = p1;
p1 = p2;
p2 = temp;
printf("교환후 P1의 좌표 : (%d, %d)\n", p1.x, p1.y);
printf("교환후 P2의 좌표 : (%d, %d)\n", p2.x, p2.y);
return 0;
}
// [22-2]
// 1) 이름, 점수를 멤버로 가지는 구조체를 정의하고 그 구조체 배열에 3명의 정보를 입, 출력하라.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
char name[10];
int score;
} student;
int main(void) {
student stu[3];
int i, greatest = 0;
for (i = 0; i < 3; i++) {
printf("이름을 입력하시오: ");
scanf(" %s", &stu[i].name);
printf("성적을 입력하시오: ");
scanf(" %d", &stu[i].score);
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
}
for (i = 1; i < 3; i++) {
if (stu[greatest].score < stu[i].score) greatest = i;
}
printf("최우수학생의 이름은 %s, 점수는 %d점", stu[greatest].name, stu[greatest].score);
}
// 2) 이름, 점수를 멤버로 가지는 구조체를 정의하고 이름이 제일 앞인 학생의 정보를 출력.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
char name[10];
int score;
} student;
int main(void) {
student stu[3];
int i, first = 0;
for (i = 0; i < 3; i++) {
printf("이름을 입력하시오: ");
scanf(" %s", stu[i].name);
printf("성적을 입력하시오: ");
scanf(" %d", &stu[i].score);
}
for (i = 1; i < 3; i++) {
if (stu[first].score > stu[i].score) first = i;
}
printf("이름은 %s, 점수는 %d점", stu[first].name, stu[first].score);
}
// 3) 예제 2번을 구조체 포인터 표현으로 바꾸어라.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
char name[10];
int score;
} student;
int main(void) {
student stu[3];
student* pt = stu;
int i, first = 0;
for (i = 0; i < 3; i++) {
printf("이름을 입력하시오: ");
scanf(" %s", (pt + i)->name);
printf("성적을 입력하시오: ");
scanf(" %d", &(pt + i)->score);
}
for (i = 1; i < 3; i++) {
if ((pt + first)->score > (pt + i)->score) first = i;
}
printf("이름은 %s, 점수는 %d점", (pt + first)->name, (pt + first)->score);
}
// 4) 구조체 점을 3개 입력받아 직각삼각형인지를 판별하라.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
int x;
int y;
} point;
int main(void) {
point p[3];
for (int i = 0; i < 3; i++) {
printf("%d번째 점(x, y) 입력:", i+1);
scanf("%d %d", &p[i].x, &p[i].y);
}
int d[3];
int a[3][2] = { {0,1}, {0,2}, {1,2} };
for (int i = 0; i < 3; i++) {
int dx = p[a[i][0]].x - p[a[i][1]].x;
int dy = p[a[i][0]].y - p[a[i][1]].y;
d[i] = dx * dx + dy * dy;
}
if (d[0] + d[1] == d[2] || d[0] + d[2] == d[1] || d[1] + d[2] == d[0])
printf("삼각형은 직각삼각형임");
else printf("삼각형은 직각삼각형 아님");
}
// 5) 구조체 배열을 선언한 뒤 순차적으로 저장 및 출력하라.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
char name[10];
int score;
} student;
int main(void) {
student stu[3];
student* pt = stu;
int i;
for (i = 0; i < 3; i++) {
printf("이름을 입력하시오: ");
scanf(" %s", (pt + i)->name);
printf("성적을 입력하시오: ");
scanf(" %d", &(pt + i)->score);
}
for (i = 0; i < 3; i++) {
printf("%d번째 학생의 이름은 %s, 성적은 %d\n",
i + 1, (pt + i)->name, (pt + i)->score);
}
}
// [23-1]
// 1) 학번, 이름, 주소를 입력, 출력하는 함수를 작성하시오.
// 2) 학생의 이름과 성적을 받아 최우수학생을 구해 출력하는 프로그램을 작성하시오.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
char name[20];
int num;
} stu;
void get_data(stu a[], int len);
int get_best(stu a[], int len);
int main(void) {
stu a[3];
int best;
get_data(a, 3);
best = get_best(a, 3);
printf("최우수학생의 이름은 %s, 점수는 %d점", a[best].name, a[best].num);
}
void get_data(stu a[], int len) {
for (int i = 0; i < len; i++) {
printf("이름을 입력하시오: ");
scanf("%s", a[i].name);
printf("성적을 입력하시오: ");
scanf("%d", &a[i].num);
}
}
int get_best(stu a[], int len) {
int best = 0;
for (int i = 1; i < len; i++) {
if (a[best].num < a[i].num) best = i;
}
return best;
}
// 3) 2번 예제에서 점수가 아닌 이름을 대상으로 적은 학생을 출력하도록 변형하시오.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
#include <string.h>
typedef struct {
char name[20];
int num;
} stu;
void get_data(stu a[], int len);
int get_best(stu a[], int len);
int main(void) {
stu a[3];
int best;
get_data(a, 3);
best = get_best(a, 3);
printf("제일 앞에 나오는 이름은 %s, 점수는 %d점", a[best].name, a[best].num);
}
void get_data(stu a[], int len) {
for (int i = 0; i < len; i++) {
printf("이름을 입력하시오: ");
scanf("%s", a[i].name);
printf("성적을 입력하시오: ");
scanf("%d", &a[i].num);
}
}
int get_best(stu a[], int len) {
int best = 0;
for (int i = 1; i < len; i++) {
if (strcmp(a[best].name, a[i].name) >= 0) best = i;
}
return best;
}
// 4) 구조체를 인자로 받아 값을 swap하는 함수를 작성하라.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct point {
int xpos;
int ypos;
} Point;
void swap(Point* a, Point* b);
int main(void) {
Point p1 = { 1, 2 };
Point p2 = { 3, 4 };
printf("pos1:[%d, %d],pos2:[%d, %d] \n",
p1.xpos, p1.ypos, p2.xpos, p2.ypos);
swap(&p1, &p2);
printf("pos1:[%d, %d],pos2:[%d, %d] \n",
p1.xpos, p1.ypos, p2.xpos, p2.ypos);
return 0;
}
void swap(Point* a, Point* b) {
Point temp = *a;
*a = *b;
*b = temp;
}
// 5) 4번 예제와 동일
// [23-2]
// 1) 구조체의 필요성을 설명하시오
// 관련있는 데이터를 하나의 타입으로 묶어 관리와 처리가 쉬워진다.
// 2) 공용체의 필요성을 설명하시오
// 하나의 메모리 공간을 여러 방식 또는 범위로 쪼개서 접근 가능하도록 해준다.
// 3) 열겨형의 필요성을 설명하시오
// 특정 자료형의 변수가 가질 수 있는 값들을 정의할 수 있어 값을 기호 또는 문자열로 정의히여
// 코드의 가독성을 높일 수 있다.
// 4) 성적을 저장하는 구조체를 정의하여 최우수 학생을 출력하는 프로그램을 작성하시오.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef struct {
char name[20];
int num, kor, eng, math;
} stu;
void get_data(stu a[], int len);
int get_best(stu a[], int len);
int main(void) {
stu a[3];
int best;
get_data(a, 3);
best = get_best(a, 3);
printf("<최우수 학생정보>\n");
printf("%s %d %d %d %d %.2lf",
a[best].name, a[best].num, a[best].kor, a[best].eng,
a[best].math, (a[best].kor + a[best].eng + a[best].math)/3.0);
}
void get_data(stu a[], int len) {
for (int i = 0; i < len; i++) {
printf("이름을 입력하시오: ");
scanf("%s", a[i].name);
printf("학번: ");
scanf("%d", &a[i].num);
printf("국어: ");
scanf("%d", &a[i].kor);
printf("영어: ");
scanf("%d", &a[i].eng);
printf("수학: ");
scanf("%d", &a[i].math);
}
}
int get_best(stu a[], int len) {
int best = 0;
for (int i = 1; i < len; i++) {
if (a[best].kor + a[best].eng + a[best].math <
a[i].kor + a[i].eng + a[i].math) best = i;
}
return best;
}
// 5) 공용체를 사용하여 정수를 16진수로 입력받고 각 바이트를 따로 출력해주는 코드를 작성하시오.
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
typedef union ubox {
char mem1[4];
int mem2;
} Ubox;
int main(void) {
Ubox x;
printf("정수를 입력하시오(16진수):");
scanf("%x", &x);
for (int i = 3; i >= 0; i--) {
printf("%d번째 바이트(16진수) : %x\n", i + 1, x.mem1[i]);
}
}
// 6) 열거형을 사용하여 가독성이 높은 코드로 변형하시오.
#include <stdio.h>
typedef enum {
top = 10, bottom = 20, left = 30, right = 40
} Dir;
int main(void) {
Dir dir = top;
switch (dir) {
case top:
printf("현재방향 : 위\n"); break;
case bottom:
printf("현재방향 : 아래\n"); break;
case left:
printf("현재방향 : 왼쪽\n"); break;
case right:
printf("현재방향 : 오른쪽\n"); break;
}
return 0;
}
// [23장 정리문제]
// 1) 구조체를 배열과 비교하여 설명하시오.
// 배열을 같은 타입의 변수 여러 개를 묶는 것이고, 구조체는 다른 타입의 변수들을 묶는 것이다.
// 2) 구조체의 필요성을 설멍하시오.
// 프로그램의 크기가 매우 크고 복잡해지거나 다루는 데이터의 양이 많아질 경우
// 같이 쓰이는 데이터들을 묶어 사용하지 않으면 입출력 데이터들을 관리하는 것이 불가능해진다.
// 3) 구조체변수의 크기는 어떻게 계산되는가, 실제 실행결과와 예상한 값이 같은가?
// 구조체변수의 크기는 각 멤버변수들의 크기를 더한 값이 된다.
// 4) 구조체변수 사이의 대입 연산의 결과는?
// 각 멤버변수별로 모두 대입변산된다.
// 5) 열거형을 사용하는 예를 설명하라
// switch~case문에서 변수의 값에 따라 실행되는 코드가 다를 때 변수를 열거형 구조체로 선언하여
// case문에 값에 대응하는 문자,혹은 기호를 작성하여 가독성을 높일 수 있다.
// 6) typedef의 용도를 설명하시오.
// 특정 코드에 다른 이름을 붙여 사용할 수 있게 하는 것으로
// 길고 자주 쓰이는 문장 또는 코드를 의미있는 단어로 대체하여 가독성을 높이고 코드 작성이 간결해진다.