[Layer7] C언어 5차시 과제

cette·2025년 4월 29일
0

구조체에 대해 알아보자

구조체란? : 여러 자료형을 가진 변수들을 하나로 묶어 자료형으로 사용할 수 있는 자료들의 집합

구조체를 사용하는 이유?
->여러 자료형 변수들을 하나의 정보로써 묶어 사용하기 깔끔하고 편리하다. 또 많은 데이터를 관리할 때 구조체를 쓰면 관리가 쉽고 가독성이 좋아진다.

구조체 선언 방법

struct 구조체이름{
자료형 변수명;
자료형 변수명;
}

구조체 함수 struct와 이름을 정의하고 중괄호 안에 저장 할 변수들을 입력해준다.

구조체 선언이 main함수 앞에 있을 때 (전역변수) -> 프로그램 전체에서 사용가능
함수 안에 선언했을 때 (지역변수) -> 그 함수 안에서만 사용 가능

구조체 변수의 초기화

#include <stdio>
struck student {
int id;
char name[10];
double score;
} s1, s2, s3;
int main(){
struct student s1 = {40101,"sunrin",90.3};
struct student s2 = {40102,"internet",88.5};
return 0;

초기값이 주어지지 않은 경우에는 0으로 초기화 된다.

구조체 변수의 선언 방법

struct student s1 = {10100, "김선린", 90.5};

선언과 동시에 중괄호로 초기화

.(dot) 연산자: 직접 멤버 연산자
변수명 뒤에 . 을 붙여 구조체 내의 변수에 접근한다. 이렇게 접근한 변수는 일반 변수와 똑같이 사용할 수 있다.

stu1.id= 10100;
strcpy(stu1.name, "김선린");
return 0;

typedef를 사용한 재정의

구조체를 사용할 땐 항상 struct를 사용하여 구조체라고 계속해서 정의해줘야 한다. 이때 구조체 앞에 typedef를 쓰게 되면 사용하여 '사용자 지정 타입' 으로 만들어 더이상 struct를 쓰지 않고 일반변수처럼 사용할 수 있다.

재정의를 하는 두가지 방법
1. struct 선언과 동시에 typedef로 타입 지정

typedef struct student{
int id;
double score;
} STUDENT;
int main(){
STUDENT s1 = {10113,100};

2.구조체 선언 후 typedef로 타입 지정

struct student{
int id;
double score;
}typedef struct student STUDENT;
int main(){
STUDENT s1 = {10113,100};

예외로

typedef struct{
int id;
double score;
}student;

이렇게도 선언이 가능하다.

구조체 배열

-> 같은 구조체 타입의 데이터를 여러 개 저장하는 배열

#include <stdio.h>
typedef struct {
    char name[20];
    int age;
} Person;
int main() {
    Person people[3] = {
        {"gayun", 17},
        {"kayun", 16},
        {"eayun", 18}
    };
    for (int i = 0; i < 3; i++) {
        printf("Name: %s, Age: %d\n", people[i].name, people[i].age);
    }
    return 0;
}

이렇게 배열을 선언하듯이 사용할 수 있다. 이렇게 배열로 사용하면 다양한 변수들의 동일한 데이터 형식을 가독성 있게 선언하고 사용할 수 있어 편리하다.

구조체 포인터와 연산자

#include <stdio.h>
typedef struct student
{
    int number;
    char name[20];
    int math;
    int english;
} STUDENT;
int main(void)
{
    STUDENT stu = {10100, "김선린", 90, 70};
    STUDENT *ptr = &stu;
    printf("%d %s %d %d\n", stu.number, stu.name, stu.math, stu.english);
    printf("%d %s %d %d\n", (*ptr).number, (*ptr).name, (*ptr).math, (*ptr).english);
    printf("%d %s %d %d\n", ptr->number, ptr->name, ptr->math, ptr->english);
    return 0;
}

1.(* ptr)
여기서 (* ptr) 을 사용하여 직접 대입 연산자를 사용 해 줬는데 이때의 (* ptr)은 ptr이 가리키는 주소의 변수, 즉 stu의 값 그 자체이기 때문에 (* ptr) = stu 라고 볼 수 있다.

  1. ptr ->
    -> (* ptr) 이라고 굳이 사용하지 않고 구조체 포인터 변수에 접근할 수 있게 된다.

code up 문제풀이

1805 : 입체기동장치 생산공장

입체기동장치 생산공장에서는 거인들을 물리치기 위한 기계가 생산되고 있습니다.
이 공장을 운영하는 에렌은 입체기동장치(1~100)의 식별번호(1~100)와 가스 보유량(0~10000)을 같이 관리하려고 합니다.
하지만, 식별번호를 정렬할 때 가스 보유량이 뒤죽박죽 되어 버려 골머리를 앓고 있습니다.
에렌을 남몰래 좋아하고 있던 미카사는 에렌이 스트레스성 탈모로 잔머리가 모두 빠지기 전에 이 문제를 해결해주려 합니다.
미카사가 에렌의 스트레스성 탈모를 막을 수 있도록 프로그램을 작성하세요.
식별번호가 한번 정해지면 그 입체기동장치의 가스 보유량은 정렬되더라도 변하지 않아야 합니다.

#include <stdio.h>
typedef struct {
    int a; // 식별번호
    int b; // 가스 보유량
} advence;
int main() {
    int n;
    scanf("%d", &n);
    advence ad[n];
    for (int i = 0; i < n; i++) {
        scanf("%d %d", &ad[i].a, &ad[i].b);
    }
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (ad[j].a > ad[j + 1].a) {
                advence temp = ad[j];
                ad[j] = ad[j + 1];
                ad[j + 1] = temp;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d %d\n", ad[i].a, ad[i].b);
    }
    return 0;
}

n을 입력받아 n만큼 도는 for문 안에 구조체 배열 a와 b를 입력받는다.
여기서 이중for문을 돌려서 배열의 앞과 뒤 식별번호를 비교해 앞이 더 크면 변수를 통해 값을 스왑하는 버블정렬을 만들었다. 이후에 for문을 통해 정렬된 배열 값을 출력했다.

4012 : 석차 계산

정렬되지 않은 학생들의 임의의 점수를 입력하여 석차를 계산하는 프로그램을 작성하시오. 점수는 동점이 있을 수 있으며, 이러한 경우 같은 석차로 처리한다. 예를 들어 5명의 점수 100, 90, 76, 60, 90이 입력되었다면 석차는 2등이 2명이고 3등은 없다. (단, 점수가 가장 높은 학생을 1등으로 한다.)

#include <stdio.h>
typedef struct {
    int score;
    int rank;
} Seokcha;
int main() {
    int n;
    scanf("%d", &n);
    Seokcha s[n];
    for (int i=0; i < n; i++){
        scanf("%d",&s[i].score);
    }
    for(int i = 0; i<n ; i++){
        s[i].rank= 1;
        for (int j=0 ; j<n ;j++){
            if (s[j].score > s[i].score){
               s[i].rank++;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d %d\n",s[i].score, s[i].rank);
    }
    return 0;
}

점수와 순위를 저장하는 구조체 Seokcha를 선언하고, 점수를 입력받는다. for문을 통해 n만큼 선언해준 배열에 기본 값인 rank를 1로 초기화하고, for문을 돌려 배열의 첫번째 값부터 모든 값을 비교해서 모든 값과 비교하는 값이 작으면 rank를 1씩 더해주는 방식으로 순위를 만들었다. 여기서 모든 값을 비교해야 순위를 제대로 셀 수 있기 때문에 자기 자신을 포함해 비교 해 준 것이다. for문을 통해 배열의 모든 값의 점수와 순위를 출력해줬다.

창작과제 문제: 회계 관리 시스템

문제

Layer7는 동아리 부원들의 지출 내역을 정리하고자 한다.
부원마다 여러 건의 지출 내역이 있으며, 각 지출은 항목명, 금액, 날짜로 이루어져 있다.
모든 부원은 정보를 입력받아 각 회원의 총 지출을 출력하고, 가장 지출이 많은 부원을 찾아 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 부원의 수 N 이 주어진다. (1 ≤ N ≤ 100)
이후 각 부원의 대해 다음 정보가 주어진다.

  • 첫째 줄에는 이름(공백 없음), 학번, 지출 내역의 수 M 이 주어진다. (1 ≤ M ≤ 100)
  • 다음 M 개의 줄에는 각 지출에 대한 항목명(공백 없음), 금액(0 이상 10,000 이하의 정수), 날짜(YYYY-MM-DD 형식)가 주어진다.

출력

각 부원의 대해 "이름 학번 총지출" 형식으로 한 줄씩 출력한다.
모든 부원의 정보를 출력한 뒤, 한 줄을 띄우고 지출이 가장 많은 부원의 정보를 다음 형식으로 출력한다.
지출 총액이 같은 경우, 먼저 입력된 부원의 출력한다.

예제 입/출력

  • 첨부된 사진과 같다.

제한

  • 모든 문자열의 길이는 100자 이하이다.
  • 메모리는 malloc, free를 이용하여 동적으로 할당 및 해제해야 한다.
  • 필수로 구조체, 함수, 동적할당, 포인터,배열 을 사용한다.
    이외 모든 조건은 자유롭게 한다. AI 사용금지.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 지출 내역
typedef struct {
    char item[101];
    int amount;
    char day[11];
} Expense;
// 부원 정보
typedef struct {
    char name[101];
    int number;
    int daycount;
    int total;
    Expense expenses[100]; 
} Layer7;
int Member() {
    int n;
    printf("회원 수를 입력하세요 : ");
    scanf("%d", &n);
    return n;
}
int main() {
    int n= Member();
    int max = 0;
    Layer7* layer7 = (Layer7*)malloc(sizeof(Layer7) * n);
    for (int i = 0; i < n; i++) {
        printf("\n[%d번째 회원 정보 입력]\n", i + 1);
        printf("이름 : ");
        scanf("%s", layer7[i].name);
        printf("학번: ");
        scanf("%d", &layer7[i].number);
        printf("지출 내역 수 : ");
        scanf("%d", &layer7[i].daycount);
        (layer7 + i)->total = 0;
        for (int j = 0; j < layer7[i].daycount; j++) {
            printf("[%d번째 지출 내역]\n", j + 1);
            printf("항목명 : ");
            scanf("%s", layer7[i].expenses[j].item);
            printf("금액 : ");
            scanf("%d", &layer7[i].expenses[j].amount);
            printf("날짜 (YYYY-MM-DD):\n");
            scanf("%s", layer7[i].expenses[j].day);
            (layer7 + i)->total += (layer7 + i)->expenses[j].amount;
        }
        if (layer7[i].total >= layer7[max].total) {
            max = i;
        }
    }
    for (int i = 0; i < n; i++) {
        printf("회원: %s | 학번: %d | 총 지출: %d원\n", layer7[i].name, layer7[i].number, layer7[i].total);
    }
    printf("\n[최고 지출자]\n");
    printf("이름: %s\n", layer7[max].name);
    printf("학번: %d\n", layer7[max].number);
    printf("총 지출: %d원\n", layer7[max].total);
    free(layer7);
    return 0;
}

지출 내역이랑 부원 정보를 입력받는 함수를 만든다. 회원수를 입력받는 Member함수를 사용해 main에서 Member함수를 불러주고, malloc을 사용해 부원 정보를 동적할당 받는다. for문을 통해 회원정보와 지출내역을 배열로 입력받고, Layer7 구조체 안에있는 total값에 지출 금액을 더해 총 지출금액을 total에 저장 해 준다. 이 과정에서 포인터를 사용해줬다. if문을 통해 최고 지출자를 찾기위해 0번부터 total값을 비교해 가장 큰 값을 max에 저장한다. for문을 통해 모든 부원의 정보를 출력하고, 최고지출자는 배열 max에 저장된 값을 출력한다. 마지막으로 free를 통해 동적할당 해제를 해준다.

profile
huso

0개의 댓글