NLP Learner in Switzerland

내가 이해하려고 쓰는 [구조체] Struct 본문

Algorithm in C/Lecture Note

내가 이해하려고 쓰는 [구조체] Struct

초코빵 2021. 5. 3. 17:00
728x90
반응형

 

 

 

* 유투버 동빈나님의 영상을 참조하여 정리한 것입니다.

 

 

 

구조체struct는

파이썬의 class와 비슷하다.

기본 개념은 여러개의 데이터를 묶어서 새로운 자료형을 만드는 것이다.

배열array은 같은 자료형data type을 묶는 거였다면,

구조체struct는 서로 다른 자료형data type을 묶으려고 사용한다는 차이가 있다.

 

뭔 소리지? 구조체의 예시를 보자

struct number {
    int img;
    float real;
    double xoxo;
}

number는 구조체의 이름이며, 구조체 내부의 변수들의 data type이 서로 다른 것을 볼 수 있다(int, float, double...)

 

구조체를 왜 쓰는걸까? 현실적인 예시를 들어보면 다음과 같다.

집(A지점)에서 학교(B지점)을 간다고 가정했을 때,

'지점'이라는 struct를 만들어서 내부에 x좌표, y좌표, 지역명, 주소 등을 차례대로 넣을 수 있는 것이다.

이렇게 해두면 나중에 활용하기가 쉽다.

struct 지점{
    int x,y
    char city[n];
    char address[m];
}

 

 

 

학생 정보 구조체 student를 만들어보자

학생의 이름, 학번, 성적 3가지 변수를 넣는다.

#include <stdio.h>

struct student {
    int number;
    char name[10];
    double grade;
};

int main(void){
    struct student s;
    scanf("%d", &s.number);
    scanf("%s", s.name);
    scanf("%lf", &s.grade);
    printf("student number: %d\n", s.number);
    printf("student name: %s\n", s.name);
    printf("studnet grade: %.1f\n", s.grade);
}

 

struct student를 s라는 이름으로 main에서 불러온 후,

이 s를 사용해서 이름, 학번, 성적을 차례대로 scanf로 입력받아 출력해주는 코드이다.

학번과 성적은 numeric type이므로 ampersand(&)를 사용해서 주소를 참조해주고,

이름은 character type이므로 자체적으로 주소라서 &연산자가 필요없다.

주의할 점은, double변수는 입력받을 때는 %lf(소문자 엘과 에프)로 입력을 받고,

출력할 때는 %.1f(점, 숫자1, 에프)로 출력을 한다는 점이다

 

그럼 아래와 같은 결과값이 출력된다. 위의 세줄은 직접 입력한 것이고 나머지 3줄이 출력값이다.

 

 

 

struct는 여러 변수가 함께 들어있는 바구니이므로

같은 struct를 여러번 불러와서 활용하는 것도 쌉가능하다.

예시를 한번 보자. 아래는 특정 좌표가 주어지면 해당 좌표로 만들어지는 사각형의 면적을 구하는 코드이다.

#include <stdio.h>

struct point {
    int x;
    int y;
};

struct rectangle {
    struct point p1;
    struct point p2;
};

int main(void){
    struct rectangle r;
    int w,h,area;
    scanf("%d %d", &r.p1.x, &r.p1.y);
    scanf("%d %d", &r.p2.x, &r.p2.y);
    w = abs(r.p2.x-r.p1.x);
    h = abs(r.p2.y-r.p1.y);
    area=w*h;
    printf("area:%d", area);
    return 0;
}

좌표point라는 구조체를 만들고 x좌표값, y좌표값을 입력받는다.

우리는 좌표가 2개 필요하기 때문에 좌표 구조체가 두개 담겨있는 구조체 rectangle을 또 만들었다.

따라서 구조체 rectangle을 소환하면 각기 다른 좌표 구조체 point가 두 번 불러와지는 것이다.

 

그럼 각각의 x좌표와 y좌표는 어떻게 참조할까?

우선 좌표값은 numeric value이므로 ampersand(&)를 쓴다는 것까지는 알고 있다.

만약 구조체 rectangle에 있는 p1좌표의 x값을 불러오고 싶다면 &r.p1.x로 period(.)를 사용해서 참조한다.

각 좌표를 전부 입력받은 후, 해당 좌표들을 이용해서 w(width)와 h(height)를 계산하여 area를 구했다.

 

그런데,

꼭 이중으로 구조체를 만들 필요는 없다. 같은 구조체를 두번 불러오기만 하면 되는 것이므로

main에서 point구조체를 그냥 p1, p2 두개 불러오면 동일한 결과가 나온다.

#include <stdio.h>

struct point {
    int x;
    int y;
};

int main(void){
    struct point p1,p2;
    int w,h,area;
    scanf("%d %d", &p1.x, &p1.y);
    scanf("%d %d", &p2.x, &p2.y);
    w = abs(p2.x-p1.x);
    h = abs(p2.y-p1.y);
    area=w*h;
    printf("area:%d", area);
    return 0;
}

그럼 위의 코드를 왜 쓰냐구? 우리는 짧은 예시니까 그렇지만,

실제로 쓸때는 여기저기 활용이 될 수 있으므로 organized되어 있는게 좋잖아.

 

 

 

구조체끼리 비교는 어떻게 할까?

위에서 사용했던 point좌표 구조체를 활용한 예시이다.

두 좌표가 같은지 보려면?

p1==p2를 하면 될것 같지만, 구조체끼리는 비교가 불가능해서 에러메시지가 나온다.

구조체 내부의 값들이 서로 같아야 하는 것이다.

#include <stdio.h>

struct point {
    int x;
    int y;
};

void comparePoint(struct point p1, struct point p2){
    if(p1.x==p2.x && p1.y==p2.y){
        printf("same");
    }
}

int main(void){
    struct point p1;
    struct point p2;
    p1.x = 30;
    p1.y = 10;
    p2.x = 30;
    p2.y = 10;
    comparePoint(p1,p2);
    return 0;
}

좌표는 서로 같으려면 x좌표, y좌표 두가지 모두 서로 같아야 한다.

따라서 p1.x와 p2.x 그리고 p1.y와 p2.y를 둘다 동시에 비교해주어야 비교가 가능하다.

(물론 한쪽(x좌표 only / y좌표 only)만 비교해도 가능하다. 여기저기 두 좌표가 아예 동일한지를 보려고 하는 것)

main에다가 곧장 비교를 할 수도 있지만,

추후에 계속 사용하기 용이하도록 comparePoint 함수를 따로 생성해주었다.

 

 

 

구조체 변수에 여러개의 데이터를 받으려면?

즉, 구조체로 array배열을 만드려면?

구조체라고해서 다를것 없다. for statement로 loop를 돌려서 입력받고, 또 loop돌려서 출력해주면 된다.

#include <stdio.h>
#include <string.h>
#define SIZE 3

struct student {
    int number;
    char name[20];
    double grade;
};

int main(){
    struct student students[SIZE];
    int i;
    for(i=0;i<SIZE;i++){
        scanf("%d", &students[i].number);
        scanf("%s", students[i].name);
        scanf("%lf", &students[i].grade);
    }
    for(i=0;i<SIZE;i++){
        printf("student number:%d name:%s grade:%.1f\n", students[i].number, students[i].name, students[i].grade);
    }
    return 0;
}

 

구조체를 main에서 선언할 때 size를 넣어 array형태로 만들어주는 것이 포인트이다.

그리고 for statement내에서도 동일하게 index를 불러와서 넣어줄 수 있도록 한다.

 

 

 

 

Comments