프로그래밍/C

C언어 13주차 과제

yooongs 2020. 12. 26. 01:43

# 기본과제 및 제출 양식

1. 구조체에 대해 조사하여 다음 문항에 답하시오. (1시간 소요)

  가. 구조체가 무엇인지 설명하고 쓰임새에 대해 50자 이내로 정리해 보시오.

자료형이 다른 여러 변수들을 하나로 묶어 사용할 수 있게 만든 도구

  나. 구조체의 선언은 다음과 같다.

 

    struct 구조체이름
    {

      구조체에 들어있는 변수들의 선언

    };

 

    이를 암기하시오. 또, 점의 좌표를 저장하기 위한 데이터형으로써, 구조체이름은 Point로 하고, 내용은 int x, int y를 가지는 구조체를 선언해 보시오.

 

  다. '나'에서 선언한 구조체의 형태로 만들어지는 변수를 사용하기 위해 main 함수에서  

 

    struct 구조체이름 *사용할 변수명 = malloc(sizeof(struct 구조체이름));

 

    과 같이 포인터 변수를 만드시오. 한편, 이를 암기하시오.

 

  라. (1,2)의 좌표를 가지는 A라는 점이 있다. 이를 위해 사용할 변수명을 A로 하고,

    A에 들어있는 x,y에 1,2를 넣어보시오.

    예를들어 A->x = 10, A->y = 20 처럼 하면 됨

    https://dojang.io/mod/page/view.php?id=419

    https://dojang.io/mod/page/view.php?id=446  를 참조하시오.

 

  마. (3,4)의 좌표를 가지는 B라는 점이 있다. 이를 위해 사용할 변수명을 B로 하고,

    변수 선언과 동시에 값이 들어가도록 해 보시오.

    예를들어 struct 구조체이름 *사용할변수명 = {10,20} 처럼 하면 됨.

 

#pragma warning (disable:4996)
#include<stdio.h>
#include<stdlib.h>
struct Point
{
int x = 0;
int y = 0;
};
int main()
{
struct Point* A = (struct Point *)malloc(sizeof(struct Point));
A->x = 1;
A->y = 2;
printf("A = (%d, %d)\n", A->x, A->y);

struct Point* B = { 3,4 };
printf("B = (%d, %d)\n", B->x, B->y);
free(A);

return 0;

}

 

실행 결과

 

: struct Point *A = malloc(sizeof(struct Point)); 라고 선언했었는데

"void *" 형식의 값을 사용하여 "Point *" 형식의 엔터티를 초기화 할 수 없습니다. 라는 오류가 나옴.

구글링 해본 결과 malloc 의 리턴타입은 (void *) 형태이기 때문에 타입 변환을 해줘야 한다고 함.

(struct Point*) 를 malloc 앞에 써주니 잘 작동하는 것을 확인하였음.

 

2. 구조체는 배열로 만들수도 있다. 다음 문항에 답하시오.  (2시간 소요)

  가. 삼각형의 세 점의 좌표를 받기 위해 1번 문항에서 만들었던 Point라는 이름의 구조체로 3개의 배열을 만들어 보시오. https://dojang.io/mod/page/view.php?id=446 를 참조하시오.

  세 점은 (Point[0]->x,   Point[0]->y)   (Point[1]->x,   Point[1]->y)   (Point[2]->x,   CPoint[2]->y) 처럼 접근할 수 있도록 만드시오.

 

  나. 세 점의 좌표 Point[0]->x   Point[0]->y   Point[1]->x  Point[1]->y   Point[2]->x   Point[2]->y 를 임의로 입력하시오.

 

  다. 두 점 (x1,y1)  (x2,y2) 를 입력받아 두 점사이의 거리를 구하는 함수를 만드시오.

    https://dojang.io/mod/page/view.php?id=427 를 참조하시오

 

  라. '다'를 이용하여 (Point[0]->x,   Point[0]->y)   (Point[1]->x,  Point[1]->y) 사이의 거리를 구하고 이를 a라 하시오.
   (Point[1]->x,  Point[1]->y)  (Point[2]->x,  Point[2]->y) 사이의 거리를 구하고 이를 b라 하시오.

   (Point[2]->x,  Point[2]->y) (Point[0]->x,  Point[0]->y) 사이의 거리를 구하고 이를 c라 하시오.

 

  마. '라'를 이용하여, 헤론의 공식에 a,b,c를 대입하시오. 그리고 이 삼각형의 넓이를 구하시오.

   https://mathbang.net/541 의 하단의 노란색 박스를 참조하시오.

 

  바. '마'에서 0,0   0,1   1,0을 넣어 0.5가 나오는지 확인하시오.

 

#pragma warning (disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

struct Point
{
int x;
int y;
};
double distance(struct Point* A, struct Point* B)
{
return sqrt(pow(A->x - B->x, 2) + pow(A->y - B->y, 2));
}
double surface(double a, double b, double c)
{
double k = (a + b + c) / 2;
return sqrt(k * (k - a) * (k - b) * (k - c));
}
int main()
{
struct Point* A[3];
double a, b, c;
for (int i = 0; i < 3; i++)
{
A[i] = (struct Point*)malloc(sizeof(struct Point));
}

A[0]->x = 0;
A[0]->y = 0;
A[1]->x = 0;
A[1]->y = 1;
A[2]->x = 1;
A[2]->y = 0;

a = distance(A[0], A[1]);
b = distance(A[1], A[2]);
c = distance(A[2], A[0]);


printf("세변의 길이는 %f, %f, %f 입니다.\n", a, b, c);
double s;
if (((A[2]->y) - (A[1]->y)) * ((A[1]->x) - (A[0]->x)) - ((A[1]->y) - (A[0]->y)) * ((A[2]->x) - (A[1]->x)) == 0)
printf("세 점이 한 직선위에 있습니다.\n");
else
{
s = surface(a, b, c);
printf("삼각형의 넓이는 %f\n", s);
}

for (int i = 0; i < 3; i++)
{
free(A[i]);
}

return 0;

}

 

실행 결과

  사. '바'에서 1,1   2,2  3,3을 넣으면 세 점이 일직선 위에 있기 때문에 넓이가 0이 되는데 이를 출력할수 있도록 해보시오.

 

#pragma warning (disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>

struct Point
{
int x;
int y;
};
double distance(struct Point* A, struct Point* B)
{
return sqrt(pow(A->x - B->x, 2) + pow(A->y - B->y, 2));
}
double surface(double a, double b, double c)
{
double k = (a + b + c) / 2;
return sqrt(k * (k - a) * (k - b) * (k - c));
}
int main()
{
struct Point* A[3];
double a, b, c;
for (int i = 0; i < 3; i++)
{
A[i] = (struct Point*)malloc(sizeof(struct Point));
}

A[0]->x = 1;
A[0]->y = 1;
A[1]->x = 2;
A[1]->y = 2;
A[2]->x = 3;
A[2]->y = 3;

a = distance(A[0], A[1]);
b = distance(A[1], A[2]);
c = distance(A[2], A[0]);


printf("세변의 길이는 %f, %f, %f 입니다.\n", a, b, c);
double s;
if (((A[2]->y) - (A[1]->y)) * ((A[1]->x) - (A[0]->x)) - ((A[1]->y) - (A[0]->y)) * ((A[2]->x) - (A[1]->x)) == 0)
printf("세 점이 한 직선위에 있습니다.\n");
else
{
s = surface(a, b, c);
printf("삼각형의 넓이는 %f\n", s);
}

for (int i = 0; i < 3; i++)
{
free(A[i]);
}

return 0;

}

 

실행 결과

 

3. 다음과 같은 원시자료가 있다.

 

 학번  닉네임    무게      용돈    학점

  1      오리        60       5000      D

  2      돼지       100       3000     C

  3      토끼        90        7000     B

  4      새           80        1000     A

  5      비둘기     50        2000     A

  6      두꺼비     70        4000     B

 

  이를 저장하기 위한 구조체를 구성하여 보시오. (1시간 소요)

  가. char NickName[100], int Weight, int Money, char Point 를 가지는 구조체를 만들고 구조체의 이름을 정해보시오.

 

  나. '가'에서 만든 구조체에 위 6마리 동물들의 데이터를 넣으시오. 단, -> 를 이용하여 일일이 넣으시오.

 

  다. '나'의 방법으로는 닉네임을 넣을 수 없음을 확인하고, strcpy를 이용하시오. https://dojang.io/mod/page/view.php?id=419 를 참조하시오.

 

  라. 데이터가 제대로 들어갔는지 출력하는 함수를 만드시오. 학번을 넣으면 그 학번을 가진 동물의 모든 데이터값(닉네임, 무게, 용돈, 학점)이 출력되도록 해보시오.

 

#pragma warning (disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct Animal
{
int Number;
char NickName[100];
int Weight;
int Money;
char Point;
};

int main()
{
struct Animal* A[6];
for (int i = 0; i < 6; i++)
A[i] = (struct Animal*)malloc(sizeof(struct Animal));

    A[0]->Number = 1;
    A[1]->Number = 2;
    A[2]->Number = 3;
    A[3]->Number = 4;
    A[4]->Number = 5;
    A[5]->Number = 6;

    strcpy(A[0]->NickName, "오리");
    strcpy(A[1]->NickName, "돼지");
    strcpy(A[2]->NickName, "토끼");
    strcpy(A[3]->NickName, "새");
    strcpy(A[4]->NickName, "비둘기");
    strcpy(A[5]->NickName, "두꺼비");

    A[0]->Weight = 60;
    A[1]->Weight = 100;
    A[2]->Weight = 90;
    A[3]->Weight = 80;
    A[4]->Weight = 50;
    A[5]->Weight = 70;

    A[0]->Money = 5000;
    A[1]->Money = 3000;
    A[2]->Money = 7000;
    A[3]->Money = 1000;
    A[4]->Money = 2000;
    A[5]->Money = 4000;

    A[0]->Point = 'D';
    A[1]->Point = 'C';
    A[2]->Point = 'B';
    A[3]->Point = 'A';
    A[4]->Point = 'A';
    A[5]->Point = 'B';

    int num;
    printf("학번을 입력하세요 :   ");
    scanf_s("%d", &num);
    printf("학번\t이름\t몸무게\t용돈\t학점\n");
    printf("%d\t%s\t%d\t%d\t%c\n", A[num - 1]->Number, A[num - 1]->NickName, A[num - 1]->Weight, A[num - 1]->Money, A[num - 1]->Point);
    
    
    for (int i = 0; i < 6; i++)
        free(A[i]);

return 0;

}

 

실행 결과

 

 

# 심화과제 제출 양식( 안해도 됨 )

1. 다음과 같은 환율 데이터가 있다.

 

날짜  USD  JPY

1일  1234  1100

2일  1243  1111

3일  1230  1120

4일  1240  1110

5일  1250  1100

6/7 : 주말

8일  1240  1100

9일  1230  1110

10일 1220 1120

11일 1210 1130

12일 1200 1140

13/14 : 주말

15일 1210 1150

16일 1220 1140

17일 1230 1130

18일 1240 1120

19일 1250 1110

20/21 : 주말

22일 1200 1100

23일 1150 1110

24일 1100 1100

25일 1110 1120

26일 1120 1100

27/28 : 주말

29일 1130 1080

30일 1140 1100

 

가. 날짜를 배열의 매개변수로 가지는 구조체를 선언해 보시오.

  예를들어, 1일의 달러화는  Money[1]->USD로 접근되어야하고 Money[2]->JPY는 1111이어야 함

 

나. 선언한 구조체에 대해 변수를 만들고 위의 모든 데이터를 넣으시오.

  단, bool IsWeekEnd라는 주말 판단 인자를 구조체 안 또는 밖 중 편한곳에 넣어 Money[6], Money[7] 등 주말일때의 값에는 0을 넣으시오. 주말판단인자는 날짜를 7로 나누어 나머지가 6,0일때 주말임을 이용하면됨.

 

다. 제 x일에 y원을 이용하여 달러를 산 후 a일에 매도한경우 총 이익을 계산하시오. 단, 달러는 int값으로 하고 소수점 이하는 거스름돈으로 계산하시오. 단, 선택한 날짜의 IsWeekEnd값이 존재하면 '주말로 환전불가합니다'를 출력하시오.

 

라. 제 x일에 y원을 이용하여 엔화를 산 후 a일에 매도한경우 총 이익을 계산하시오. 단, 엔화는 1000엔 단위로 하고 이하는 거스름돈으로 계산하시오. 단, 선택한 날짜의 IsWeekEnd값이 존재하면 '주말로 환전불가합니다'를 출력하시오.

 

마. 제 x일에 달러는 a원, 엔화는 b원이었다. 이를 이용하여 한달간의 엔달러 환율을 모두 구해보시오. 단, 소수점 이하를 버리지 마시오.

 

#pragma warning (disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<stdbool.h>
#include<string.h>
#define DAY 31

struct data {
int USD;
int JPY;
bool IsWeekEnd;
};
int dollarEx(int korWon, int buyDollarRate, int sellDollarRate) {
    int dollar; // 매수 시 얻는 달러 변수 
    int profitDollar; // 총 이익
    dollar = korWon / buyDollarRate; // 원화를 달러로 바꾸었을 때
    profitDollar = (sellDollarRate - buyDollarRate) * dollar; // (매수환율 - 매도환율) * 환전한 달러 = 이익
    printf("\n");
    printf("원화 : %d, 매수 환율 : %d, 달러 : %d, 매도 환율 : %d\n", korWon, buyDollarRate, dollar, sellDollarRate);
    return profitDollar;
}
int yenEx(int korWon, int buyYenRate, int sellYenRate) {
    int yen; // 매수 시 얻는 엔 변수 
    int profitYen; // 총 이익
    yen = korWon / buyYenRate; // 원화를 엔으로 바꾸었을 때
    profitYen = (sellYenRate - buyYenRate) * yen; // (매수환율 - 매도환율) * 환전한 엔 = 이익
    printf("\n");
    printf("원화 : %d, 매수 환율 : %d, 엔 : %d, 매도 환율 : %d\n", korWon, buyYenRate, yen * 100, sellYenRate);
    return profitYen;
}

int main()
{
    struct data* month[DAY];
    for (int i = 1; i < 31; i++)
    {
        month[i] = (struct data*)malloc(sizeof(struct data));
        if (i % 7 == 0 || i % 7 == 6)
            month[i]->IsWeekEnd = 1;
        else
            month[i]->IsWeekEnd = 0;
    }
    month[1]->USD = 1234;
    month[1]->JPY = 1100;
    month[2]->USD = 1243;
    month[2]->JPY = 1111;
    month[3]->USD = 1230;
    month[3]->JPY = 1120;
    month[4]->USD = 1240;
    month[4]->JPY = 1110;
    month[5]->USD = 1250;
    month[5]->JPY = 1110;
       
    month[8]->USD = 1240;
    month[8]->JPY = 1100;
    month[9]->USD = 1230;
    month[9]->JPY = 1110;
    month[10]->USD = 1220;
    month[10]->JPY = 1120;
    month[11]->USD = 1210;
    month[11]->JPY = 1130;
    month[12]->USD = 1200;
    month[12]->JPY = 1140;

    month[15]->USD = 1210;
    month[15]->JPY = 1150;
    month[16]->USD = 1220;
    month[16]->JPY = 1140;
    month[17]->USD = 1230;
    month[17]->JPY = 1130;
    month[18]->USD = 1240;
    month[18]->JPY = 1120;
    month[19]->USD = 1250;
    month[19]->JPY = 1110;

    month[22]->USD = 1200;
    month[22]->JPY = 1100;
    month[23]->USD = 1150;
    month[23]->JPY = 1110;
    month[24]->USD = 1100;
    month[24]->JPY = 1100;
    month[25]->USD = 1110;
    month[25]->JPY = 1120;
    month[26]->USD = 1120;
    month[26]->JPY = 1100;

    month[29]->USD = 1130;
    month[29]->JPY = 1080;
    month[30]->USD = 1140;
    month[30]->JPY = 1100;

    int choice, buyDay, sellDay, Won, result;
    printf("단위 선택 : 1. USD(달러), 2. JPY(엔)\n");
    scanf("%d", &choice);
    if (choice == 1) {
        printf("달러 매수 날짜, 금액, 매도 날짜 입력 : ");
        scanf("%d %d %d", &buyDay, &Won, &sellDay);
        if (month[buyDay]->IsWeekEnd == 1 || month[sellDay]->IsWeekEnd == 1) {
            printf("주말 환전 불가\n");
        }
        printf("<< %d 일 %d 원치 달러 매수, %d일 매도 >>\n", buyDay, Won, sellDay);
        result = dollarEx(Won, month[buyDay]->USD, month[sellDay]->USD);
        printf("%d원의 이익 발생\n", result);
    }
    else if (choice == 2) {
        printf("엔 매수 날짜, 금액, 매도 날짜 입력 : ");
        scanf("%d %d %d", &buyDay, &Won, &sellDay);
        if (month[buyDay]->IsWeekEnd == 1 || month[sellDay]->IsWeekEnd == 1) {
            printf("주말 환전 불가\n");
        }
        printf("<< %d 일 %d 원치 엔 매수, %d일 매도 >>\n", buyDay, Won, sellDay);
        result = yenEx(Won, month[buyDay]->JPY, month[sellDay]->JPY);
        printf("%d원의 이익 발생\n", result);
    }

    for (int i = 1; i < 31; i++) {
        free(month[i]);
    }

return 0;
}

 

실행 결과

2. 다음과 같은 재태크 상품이 있다

  A상품 : 매달 100만원을 연금리3%로 x개월간 단리로 정기적금. 달이율은 연금리/12로 함.

  B상품 : 매달 100만원을 연금리2%로 x개월간 복리로 정기적금. 달이율은 연금리/12로 함.

  C상품 : 1억원을 가진 사람이 연금리 1.5%짜리 복리로 예금

  https://bhsmath.tistory.com/29 를 참조하시오.

 

 가. A,B,C상품에 대해 n년후의 원리합계를 저장하기 위한 구조체를 만드시오.

  예를들어, 구조체 Money에 대해 int A, int B, int C를 갖도록 하고 이를 배열로 만드시오.

 

  나. 매 n년마다의 원리합계를 n번째 구조체 배열에 넣으시오. 단, A상품과 C상품은 이율을 단순히 쉽게 구할 수 있으나, B상품은 월마다 넣은것이 연마다는 몇퍼센트의 이득인지 먼저 계산해야함. https://mathbang.net/621 를 참조하시오.

 

  다. A,B,C상품중 두 상품의 원리합계 순서가 달라지는 때를 구하고, 제 n년까지 각각 어떤 상품이 가장 유리한지 구하시오. 100년까지 계산해 보시오.

 

#pragma warning (disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<stdbool.h>
#include<string.h>
#define M 101

struct data {
double financeA;
double financeB;
double financeC;
};

int main()
{
struct data* savings[M];
for (int i = 0; i < M; i++) {
savings[i] = (struct data*)malloc(sizeof(struct data));
}
    for (int i = 1; i <= 100; i++) { // 100년 계산
        double a;
        double temp = 0;
        double sum;
        double b = 0;
        double c = 100000000;


        for (int j = 1; j <= 12 * i; j++) {
            a = 1000000 * j;
            temp = temp + a * (0.03 / 12);
            sum = a + temp; // 단리법 
        }
        for (int j = 1; j <= 12 * i; j++) {
            b = (b + 1000000) * (1 + 0.02 / 12); // 복리법 
        }

        for (int j = 1; j <= i; j++) {
            c *= (1 + 0.015); 
        }

        savings[i]->financeA = sum;
        savings[i]->financeB = b;
        savings[i]->financeC = c;
        printf("%d년 A = %f, B= %f C = %f\n", i, savings[i]->financeA, savings[i]->financeB, savings[i]->financeC);
    }
    for (int i = 0; i < M; i++)
        free(savings[i]);
return 0;

}

 

실행 결과

2번은 솔직히 그냥 답지를 베끼고 외우려고 노력했는데 아직 잘 이해가 안된다.

  A상품 : 매달 100만원을 연금리3%로 x개월간 단리로 정기적금. 달이율은 연금리/12로 함.

-> 1개월 : 100만원 + 100만원 * (0.03/12) = 1,002,500 원 , 2개월 : (1,002,500만원 + 100만원) + (1,002,500만원 + 100만원 ) * (0.03/12)

  B상품 : 매달 100만원을 연금리2%로 x개월간 복리로 정기적금. 달이율은 연금리/12로 함.

-> 1개월 : 100만원 * (1+0.02/12) = 1,001,666 원 , 2개월 : (100만원 + 1,001,666 원) * (1+0.02/12)^2 원

  C상품 : 1억원을 가진 사람이 연금리 1.5%짜리 복리로 예금

-> n년 : 100,000,000*(1+0.015)^n

 

이렇게 생각했는데 맞는건지 모르겠음;;

'프로그래밍 > C' 카테고리의 다른 글

C언어 15주차 과제  (0) 2021.01.12
C언어 14주차 과제  (0) 2021.01.07
C언어 12주차 과제  (0) 2020.12.16
C언어 11주차 과제  (1) 2020.12.12
C언어 10주차 과제  (0) 2020.12.06