알고리즘

[알고리즘] 구조체(자료구조3) + 데이터베이스 테이블

sundori 2023. 9. 15. 19:01

목차

    # 구조체 개념

    구조체도 배열처럼 여러 데이터를 그룹으로 묶어 하나의 자료형으로 정의가 가능하며, 배열은 자료형이 같을 때만 그룹으로 묶을 수 있지만, 구조체는 서로 다른 자료형도 그룹으로 묶을 수 있어 다양한 자료형을 가지거나 복잡한 자료의 형태를 정의할 때 유용하게 사용한다.

    자료를 체계적으로 관리하려면 일정한 단위 형식으로 구성해야 하는데, 밑에 표가 이를 알려준다.

     

     

    행, ROW, RECORD, 데이터베이스(RECORDS, Tuple)

      열, Column, Field

    ROW
    RECORD
    김00 2014년 가입 3000
    하00 2015년 가입 4000
    홍00 2018년 가입 2000
    권00 2023년 가입 5000

    열, Column, Field

    명칭 열, Column, Field

    ROW
    RECORD
    김00 2014년 가입 3000
    하00 2015년 가입 4000
    홍00 2018년 가입 2000
    권00 2023년 가입 5000

    특성 Attribute
    각 열의 이름을 말함

    이름 가입일 연봉
    김00 2014년 가입 3000
    하00 2015년 가입 4000
    홍00 2018년 가입 2000
    권00 2023년 가입 5000

    테이블

    모든 행과 열을 테이블이라 함

    이름 가입일 연봉
    김00 2014년 가입 3000
    하00 2015년 가입 4000
    홍00 2018년 가입 2000
    권00 2023년 가입 5000

    이렇게 여러  형태의 튜플(레코드)들이 모여 테이블을 구성한다.

    # 구조체 선언

    구조체는 여러 자료형의 변수들을 그룹으로 묶어서 하나의 자료형으로 선언하여 사용한다.

    구조체는 구조체형 이름. 자료형, 데이터 항목으로 구성된다.

    • 구조체형 이름 : 구조체로 정의하는 새로운 자료형의 이름.
    • 데이터 항목 : 배열과 같은 느낌이지만 서로 다른 자료형을 가질 수 있다.

    구조체 정의

    // 사용할 구조체 정의의 예
    struct 구조체형 이름{
       자료형 항목1;
       자료형 항목2;
       ...
       자료형 항목n;
    };
    -------------------

    위의 구조체형 선언은 내가 사용할 구조체의 모양만 정의한 것이다. 즉 붕어빵 틀을 만든 것이다.

    구조체를 사용하기 위해서는 밑에 코드처럼 데이터를 저장할 수 있는 구조체 변수를 선언해야 한다.

    구조체 변수 선언

    // 구조체 변수 선언
    struct 구조체이름 구조체변수이름;

    구조체형 employee 선언 시 생기는 메모리 공간.


    구조체를 사용하는 단계

    1. 구조체형 선언 : 내구 구조를 정의한다.
    2. 구조체 변수 선언 : 구조체형에 따른 변수를 선언한다.
    3. 구조체 변수의 사용 : 내부 항목에 데이터를 저장하고 사용한다.
    // 구조체 사용 예제.
    #include <stdio.h>
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        struct EMPLOYEE employee = {.name = "권순욱", .year = 2000, .pay = 4000};
        
        printf("이름 : %s \n입사일 : %d \n연봉 : %d\n", employee.name, employee.year, employee.pay);
    }

    Tip.
    문자형 배열에 직접 문자열을 집어넣을 때... 오류가 난다

    예를 들어 employee.name = "권 00"; 이런 식으로 선언을 하게 되면 오류가 발생하는데... strcpy함수를 사용하면 된다.

    #include <stdio.h>
    #include<string.h>
    
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        struct EMPLOYEE employee = {.name = "권순욱", .year = 2000, .pay = 4000};
        
        strcpy(employee.name, "권00");
        printf("이름 : %s \n입사일 : %d \n연봉 : %d\n", employee.name, employee.year, employee.pay);
        
    }

    구조체 변수의 초기화

    일반 변수를 초기화하는 것처럼 구조체 변수를 초기화하려면 구조체 변수를 언언하면서 변수의 초기 값을 지정한다.

    이때 일반 변수는 하나의 값만 대입하면 되겠지만 구조체는 여러 개일 수 있으므로 순서에 맞추어 대입하자.

    // 구조체 변수의 선언과 동시에 초기화
    #include <stdio.h>
    
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        struct EMPLOYEE employee = {.name = "권순욱", .year = 2000, .pay = 4000};
        struct EMPLOYEE employee1 = {"권00", 2012, 3000};
    }

    데이터 항목의 참조

    구조체 변수에 있는 각 데이터 항목을 참조하려면 구조체 연산자를 사용해야 한다.

    점 연산자(.) 구조체 변수의 데이터 항목을 지정.
    화살표 연산자(->) 구조체형 포인터에서 포인터가 가르키는 구조체 변수의 데이터 항목을 지정.

    점 연산자(.)

    점 연산자는 구조체 변수에 있는 데이터 항목을 개별적으로 지정할 때 사용한다.

    #include <stdio.h>
    #include<string.h>
    
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        struct EMPLOYEE employee;
        ...// 문자열에 대한 접근은 안된다. 위에 Tip을 확인하자.
        employee.year = 2022;
        employee.pay = 3000;
        
        ...
        printf("연봉 : %d", employee,pay);
    }

    화살표 연산자(->)

    포인터는 모든 자료형에 사용할 수 있어서 구조체형에도 사용이 가능하다.

    구조체형 포인터에서 포인터가 가리키는 구조체 변수의 데이터 항목을 지정하려면 화살표 연산자를 사용한다.

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        // 구조체 포인터 선언
            struct EMPLOYEE *employee1;
    
            // 메모리 할당
            employee1 = (struct EMPLOYEE *)malloc(sizeof(struct EMPLOYEE));
    
            // 구조체 멤버 초기화
            if (employee1 != NULL) {
                strcpy(employee1->name, "권순욱");
                employee1->year = 2000;
                employee1->pay = 4000;
    
                // 구조체 내용 출력
                printf("Name: %s\n", employee1->name);
                printf("Year: %d\n", employee1->year);
                printf("Pay:  %d\n", employee1->pay);
    
                // 메모리 해제
                free(employee1);
            } else {
                printf("메모리 할당에 실패했습니다.\n");
            }
    
            return 0;
    }
    ----------------
    Name: 권순욱
    Year: 2000
    Pay:  4000
    #include <stdio.h>
    
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        // 구조체 포인터 선언
        struct EMPLOYEE employee = {.name = "권순욱", .year = 2000, .pay = 4000};
        // employee의 주소를 지정
        struct EMPLOYEE *employee1 = &employee;
        
        printf("Name: %s\n", employee1->name);
        printf("Year: %d\n", employee1->year);
        printf("Pay:  %d\n", employee1->pay);
    
        return 0;
    }

    화살표 연산자의 또 다른 사용 예 (. 연산자를 사용)

    #include <stdio.h>
    
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        // 구조체 포인터 선언
        struct EMPLOYEE employee = {.name = "권순욱", .year = 2000, .pay = 4000};
        struct EMPLOYEE *employee1 = &employee;
        
        printf("Name: %s\n", (*employee1).name);
        printf("Year: %d\n", (*employee1).year);
        printf("Pay:  %d\n", (*employee1).pay);
    
        return 0;
    }
    #include <stdio.h>
    #include <string.h>
    
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        // 구조체 포인터 선언
        struct EMPLOYEE employee = {.name = "권순욱", .year = 2000, .pay = 4000};
        struct EMPLOYEE *employee1 = &employee;
        
        strcpy(employee1->name, "Kwonsunuk");
        employee1->year = 1000;
        employee1->pay = 3500;
    //  포인터의 참조 연산자(*)를 사용하여 점 연산자를 사용이 가능핟.
    //  점 연산자가 참조 연산자보다 연산 우선순위가 높기 때문에 괄호를 먼저 넣는다.
    //  strcpy((*employee1).name, "Kwonsunuk");
    //  (*employee1).year = 1000;
    //  (*employee1).pay = 3500;
        
        printf("Name: %s\n", (*employee1).name);
        printf("Year: %d\n", (*employee1).year);
        printf("Pay:  %d\n", (*employee1).pay);
    
        return 0;
    }

    구조체 연산

    구조체 연산은 일반 변수와 다르다.  일반 변수 x, y는 x > y처럼 비교 연산이 가능하지만

    employee > employee1와 같이는 불가능하다.

    #include <stdio.h>
    #include <string.h>
    
    struct EMPLOYEE{
        char name[10];
        int year;
        int pay;
    };
    
    int main(int argc, char* argv[]){
        // 구조체 포인터 선언
        struct EMPLOYEE employee = {.name = "권순욱", .year = 2000, .pay = 4000};
        struct EMPLOYEE *employee1 = &employee;
        
        /*strcpy(employee1->name, "Kwonsunuk");
        employee1->year = 1000;
        employee1->pay = 3500;*/
        
    //    strcpy((*employee1).name, "Kwonsunuk");
    //    (*employee1).year = 1000;
    //    (*employee1).pay = 3500;
        
        
        if(employee.pay >= employee.pay){
            printf("Name: %s\n", employee.name);
            printf("Year: %d\n", employee.year);
            printf("Pay:  %d\n", employee.pay);
        }
    //  또는
        if(employee.pay >= (*employee1).pay){
            printf("Name: %s\n", (*employee1).name);
            printf("Year: %d\n", (*employee1).year);
            printf("Pay:  %d\n", (*employee1).pay);
        }
    
        return 0;
    }