본문 바로가기
c/자습

구조체(쉽게 풀어쓴 C언어 EXPRESS)

by 지트리아 2023. 1. 6.

용어정리

 

 

 

 

본문정리

구조체란 무엇인가?

구조체는 서로 다른 자료형들을 하나로 묶는 것이다.(여러 개의 같은 자료형을 묶는 것이 배열)

 

구조체의 선언, 초기화, 사용

구조체는 서로 다른 자료형의 변수들을 묶어서 새로운 자료형을 만드는 것이다.

태그란 구조체의 이름이다. 그 안에 있는 것을 구조체 맴버라고 한다. 구조체 선언은 구조체의 형태만 정의한 것이다. 즉 구조체를 이용하여 변수를 만들지 않았음을 알아야 한다.

구조체 변수의 초기화는 배열과 비슷하다.

구조체 맴버에 접근할 때는 맴버 연산자(.)를 이용하면 된다.

struct student{
	int number;
    char name[10];
    double grade;
}; // 끝에 ;이 붙는 것이 핵심이다.

struct student s1 = { 24, "Kim", 4.3 }; // 초기화 하는 방법
struct student s2;
s2 = { ...} // 불가

s1.grade = 3.8; // 맴버에 접근
strcpy(s1.name,"Park"); // 문자배열을 수정할 때

struct {
	int number;
    char name[10];
} s1, s2, s3; // 이름이 없는 구조체는 선언과 동시에 변수 생성

 

구조체의 활용

구조체를 맴버로 가질 수도 있다. 이때는 맴버 연산자를 2번 사용하게 된다. 

하나의 구조체를 다른 구조체로 대입하는 연산이 가능하다. 하지만 구조체 변수와 구조체 변수를 서로 비교하는 것은 허용되지 않는다. 맴버마다 별도로 비교해야 한다,

 

구조체의 배열

구조체 배열은 다른 배열 선언과 똑같다. 잊지 말아햐 하는 것은 인덱스가 0부터 시작한다는 것이다. 늘 잊지 말아야하는 것은 strcpy를 이용해야 한다는 것이다.

struct student{
	int number;
    char name[20];
};
struct student s[3]; // 배열로서 선언

s[3] = { {1, "park", 2.42}, {1, "Kim", 3.3}, {3, "asd", 4,3} };

s[0].numbeer = 100;
strcpy(s[0].name, "Kim");

 

구조체와 포인터

포인터가 사용되는 경우는 2가지이다. 구조체를 가리키는 경우, 포인터를 맴버로 가지는 구조체이다.

포인터를 이용하여 구조체의 맴버를 가리킬 때에는 간접 맴버 연산자 ->가 사용된다.

struct student s = { 23, "Kim", 3,4 };
struct student *p;
p = &s;

(*p).number = 23;
p->number = 23; // 위와 같은 의미이나 2번째 방법을 더 많이 사용한다.

 

구조체와 함수

구조체가 인수나 반환값으로 사용될 때는 "값에 의한 호출" 원칙이 적용된다. 따라서 구조체의 크기가 크다면 시간이 오래 걸린다. 이럴 땐 포인터를 인수로 하여 보내면 된다. 포인터는 항상 일정한 크기임을 잊어서는 안된다. 다만 이럴 경우 원본이 훼손될 수 있다. 이를 위해선 const를 이용하면 된다. 

int equal(struct student const *p1, struct student const *p2) {
if(p1->number == p2->number){
return 1;
{
else {
return 0;
}
}

 

공용체

같은 메모리 영역을 여러 개의 변수들이 공유할 수 있게 하는 기능이다. 따라서 맴버들이 같은 공간을 공유하기 때문에 동시에 모든 맴버 변수들의 값을 저장할수는 없으며 특정 순간에는 하나의 맴버만 존재할 수 있다.

공용체에서 맴버를 접근하는 방법은 맴버 연산자를 사용하면 된다. 

 

열거형

변수가 가질 수 있는 값들을 나열해놓은 자료형이다. 따라서 선언된 변수는 열거형에 정의된 상수들만을 가질 수 있다.

enum days { SUN, MON, TUE } ;

enum days d;
d = SUN; //가능, d에는 0이 할당됨
d = WEN; //불가능, 컴파일 에러 발생

 

typedef

 

본문제

Q1. 

#include <stdio.h>

struct book {
    int id;
    char title[100];
    char author[20];
};

int main(void) {
    struct book b = { 1, "바람과 함께 사라지다", "마가렛 미첼" };
    printf("{ %d, %s, %s }", b.id, b.title, b.author);

    return 0;
}

 

Q2. 

#include <stdio.h>

struct account {
    int number;
    char name[20];
    int balance;
};

int main(void) {
    struct account ac = { 1, "홍길동", 100000 };
    printf("{ %d, %s, %d }", ac.number, ac.name, ac.balance);

    return 0;
}

 

Q3. 

#include <stdio.h>

struct mail {
    char title[20];
    char recevier[20];
    char sender[20];
    char main[100];
    char day[20];
    int prior;
};

int main(void) {
    struct mail m = { "안부 메일", "chulsoo@hankuk.ac.kr", "hsh@hankuk.ac.kr", "안녕하십니까? 별일 없으신지요?",
    "2010/9/1", 1 };

    printf("제목: %s\n수신자: %s\n발신자: %s\n내용: %s\n날짜: %s\n우선순위: %d", m.title, m.recevier, m.sender, m.main, m.day, m.prior);

    return 0;
}

 

Q4. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

struct complex {
    double real;
    double imag;
};

struct complex complex_add(struct complex c1, struct complex c2) {
    struct complex result;
    result.real = c1.real + c2.real;
    result.imag = c1.imag + c2.imag;
    return result;
}

int main(void) {
    struct complex c1, c2, result;

    printf("처음 실수와 허수를 입력하라: ");
    scanf("%lf %lf", &c1.real, &c1.imag);
    printf("두번째 실수와 허수를 입력하라: ");
    scanf(" %lf %lf", &c2.real, &c2.imag);

    result = complex_add(c1, c2);

    printf("%lf %lf", result.real, result.imag);

    return 0;
}

 

Q5. 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

struct point {
    int x, y;
};

int main(void) {
    struct point p1, p2;
    printf("첫번째 점을 입력하시오: ");
    scanf("%d %d", &p1.x, &p1.y);
    printf("두번째 점을 입력하시오: ");
    scanf(" %d %d", &p2.x, &p2.y);
    if (p1.x == p2.x && p1.y == p2.y) {
        printf("(%d, %d) == (%d, %d)", p1.x, p1.y, p2.x, p2.y);
    }
    else {
        printf("(%d, %d) != (%d, %d)", p1.x, p1.y, p2.x, p2.y);
    }

    return 0;
}

 

Q6.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

struct point {
    int x, y;
};

int equal(struct point* p1, struct point * p2) {
    if (p1->x == p2->x && p1->y == p2->y) {
        return 1;
    }
    else {
        return 0;
    }
}

int main(void) {
    struct point p1, p2;
    printf("첫번째 점을 입력하시오: ");
    scanf("%d %d", &p1.x, &p1.y);
    printf("두번째 점을 입력하시오: ");
    scanf(" %d %d", &p2.x, &p2.y);

    if (equal(&p1, &p2)){
        printf("(%d, %d) == (%d, %d)", p1.x, p1.y, p2.x, p2.y);
    }
    else {
        printf("(%d, %d) != (%d, %d)", p1.x, p1.y, p2.x, p2.y);
    }

    return 0;
}

 

Q7.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

struct point {
    int x, y;
};

int quadrant(struct point p) {
    if (p.x == 0 || p.y == 0) {
        return 0;
    }
    else 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 if (p.x > 0 && p.y<0) {
        return 4;
    }
}

int main(void) {
    struct point p1;
    printf("점을 입력하시오: ");
    scanf("%d %d", &p1.x, &p1.y);
    
    switch (quadrant(p1)) {
        case 0:
            printf("축위에 있습니다.");
            break;
        case 1:
            printf("(%d, %d)의 사분면 = %d", p1.x, p1.y, quadrant(p1));
            break;
        case 2:
            printf("(%d, %d)의 사분면 = %d", p1.x, p1.y, quadrant(p1));
            break;
        case 3:
            printf("(%d, %d)의 사분면 = %d", p1.x, p1.y, quadrant(p1));
            break;
        case 4:
            printf("(%d, %d)의 사분면 = %d", p1.x, p1.y, quadrant(p1));
            break;
    }

    return 0;
}

 

Q8.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct point {
    int x, y;
}point;

typedef struct circle {
    point center;
    double radius;
}circle;

double area(circle c) {
    return  3.141592  * c.radius * c.radius;
}

double parimeter(circle c) {
    return  3.141592 * 2 * c.radius;
}

int main(void) {
    circle c;

    printf("원의 중심: ");
    scanf("%d %d", &c.center.x, &c.center.y);
    printf("원의 반지름: ");
    scanf(" %lf", &c.radius);

    printf("원의 면적=%lf, 원의 둘레=%lf", area(c), parimeter(c));

    return 0;
}

 

Q9.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

typedef struct fodd {
    char name[100];
    int cal;
}food;

int main(void) {
    food afood[10];
    int count = 0, result = 0;
    while (1) {
        printf("음식이름 : ");
        scanf(" %s", afood[count].name);
        printf("칼로리 :  ");
        scanf(" %d", &afood[count].cal);
        if (afood[count].cal == 0) {
            break;
        }
        count++;
    }
    for (int i = 0; i < count; i++) {
        result += afood[i].cal;
    }
    printf("총 칼로리 = %d", result);

    return 0;
}

 

Q10.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct employee {
    int num;
    char name[20];
    char tel[50];
    int old;
} emp;

int main(void) {
    emp e[10] = { 0 };
    int num = 0, count = 0;

    while (1) {
        printf("사번: ");
        scanf(" %d", &e[num].num);
        if (e[num].num == 0) {
            break;
        }
        printf("이름: ");
        scanf(" %s", e[num].name);
        printf("전번: ");
        scanf(" %s", e[num].tel);
        printf("나이: ");
        scanf(" %d", &e[num].old);
        num++;
        count++;
    }
    for (int i = 0; i < count; i++) {
        if (e[i].old >= 20 && e[i].old <= 30) {
            printf("이름:%s 나이%d\n", e[i].name, e[i].old);
        }
    }

    return 0;
}

 

Q11.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct tel {
    char name[50];
    char htel[100];
    char tel[100];
} tel;

int main(void) {
    tel tel[3] = { 0 };
    char fname[50];
    int result = 0;
    for (int i = 0; i < 3; i++) {
        printf("이름을 입력하시오: ");
        scanf(" %s", tel[i].name);
        printf("집전화번호를 입력하시오: ");
        scanf(" %s", tel[i].htel);
        printf("휴대번화번호를 입력하시오: ");
        scanf(" %s", tel[i].tel);
    }

    while (1) {
        result = 1;
        printf("찾을 이름을 입력하세요: ");
        scanf(" %s", fname);
        if (!(strcmp(fname, "그만"))) {
            break;
        }
        for (int i = 0; i < 3; i++) {
            if (!(strcmp(fname, tel[i].name))) {
                printf("집전화번호: %s\n", tel[i].htel);
                printf("휴대폰번호: %s\n", tel[i].tel);
                result = 0;
            }
        }
        if (result) {
            printf("해당 이름은 없습니다.\n");
        }
    }

    return 0;
}

 

Q12.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct card {
    int value;
    char suit;
} card;

int main(void) {
    card card[52] = { 0 };
    char v[4] = { 'c', 'd', 'h', 's' };

    for (int i = 0, z = 0; i < 4; i++, z += 13) {
        for (int j = 0; j < 13; j++) {
            card[j + z].suit = v[i];
            card[j + z].value = j + z + 1;
            printf("%d : %c  ", card[j + z].value, card[j + z].suit);
        }
        printf("\n");
    }

    return 0;
}

 

Q13.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

typedef struct shape {
    int type;
    union data {
        struct { int base, height; 
        } tri;
        struct { int width, height;
        } rect;
        struct { int radius;
        } circ;
    };
} shape;

int main(void) {
    shape sh;
    printf("도형의 타입을 입력하시오: ");
    scanf("%d", &sh.type);

    switch (sh.type) {
        case 0:
            printf("밑변과 높이의 길이를 입력하시오");
            scanf("%d %d", &sh.tri.base, &sh.tri.height);
            printf("면적은 %f", sh.tri.base * sh.tri.height / 2.0);
            break;
        case 1:
            printf("가로와 세로의 길이를 입력하시오");
            scanf("%d %d", &sh.rect.width, &sh.rect.height);
            printf("면적은 %d", sh.rect.width * sh.rect.height);
            break;
        case 2:
            printf("반지름을 입력하시오");
            scanf("%d", &sh.circ.radius);
            printf("면적은 %f", sh.circ.radius * sh.circ.radius * 3.14);
            break;
    }

    return 0;
}

 

Q14.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

typedef struct music {
    char title[50];
    char name[50];
    char loc[50];
    int specis;
}music;

int main(void) {
    int op = 0;
    int x = 0;
    music music[200] = { 0 };
    int num = 0;
    char nam[100] = { 0 };

    while (1) {
        printf("=======================================\n");
        printf("1. 추가 \n2. 검색\n3. 종료\n");
        printf("=======================================\n");
        printf("정수값을 입력하시오 : ");
        scanf(" %d", &op);
        getchar();
        switch (op) {
            case 1:
                printf("제목: ");
                gets_s(music[num].title, 50);
                printf("가수: ");
                gets_s(music[num].name, 50);
                printf("위치: ");
                gets_s(music[num].loc, 50);
                printf("장르(0: 가요, 1: 팝, 2: 클래식, 3: 영화음악): ");
                scanf(" %d", &music[num].specis);
                getchar();
                num++;
                break;
            case 2:
                x = 0;
                printf("제목을 입력하세요: ");
                gets_s(nam, 100);
                for (int i = 0; i < num; i++) {
                    if (!strcmp(nam, music[i].title)) {
                        printf("가수: %s\n위치: %s\n장르: %d\n", music[i].name, music[i].loc, music[i].specis);
                        x = 1;
                        break;
                    }
                }
                if (x ==0) {
                    printf("찾는 값이 없습니다.\n");
                }
                break;
            case 3:
                break;
        }
        if (op == 3) {
            break;
        }
    }

    return 0;
}

 

댓글