Coding/C

[C언어] 구조체, 구조체 포인터 - 코딩도장

GunP4ng 2024. 1. 20. 23:20

[코딩도장] Unit 48 ~ 49


1. 구조체

1. 구조체 사용하기

구조체는 struct 키워드로 정의한다

구조체는 보통 main 함수 바깥에 선언한다

함수 안에 선언하게 되면 해당 함수 안에서만 구조체를 사용할 수 있다

struct Person {   // 구조체 정의
    char name[20];        // 구조체 멤버 1
    int age;              // 구조체 멤버 2
    char address[100];    // 구조체 멤버 3
};

struct 키워드 뒤에 구조체 이름을 지정해주고

{ } 안에 변수를 선언한다

구조체 안에 들어있는 변수는 멤버라고 한다

구조체를 정의할 때는 중괄호 끝에 반드시 ; 을 붙여준다

 

구조체를 사용하려면 구조체 변수를 선언해야 한다

struct Person p1;

 

일반 변수로 선언한 구조체의 멤버에 접근하려면 . (점) 을 사용한다

strcpy(p1.name, "홍길동");
p1.age = 30;
strcpy(p1.address, "서울시 용산구 한남동");

p1.age 와 같이 구조체 멤버에 접근할 수 있다

문자열 멤버는 strcpy 함수를 이용해서 할당하면 된다

 

struct Person {   // 구조체 정의
    char name[20];        // 구조체 멤버 1
    int age;              // 구조체 멤버 2
    char address[100];    // 구조체 멤버 3
} p1;

구조체를 정의하는 동시에 변수도 선언할 수 있다

닫는 중괄호와 ; (세미콜론) 사이에 변수를 지정하면 된다

 

2. typedef 사용하기

구조체 변수를 선언할 때 struct 를 생략할 수 있다

typedef 로 구조체를 정의하면서 별칭을 지정해주면 된다

typedef struct _Person {   // 구조체 이름은 _Person
    char name[20];            // 구조체 멤버 1
    int age;                  // 구조체 멤버 2
    char address[100];        // 구조체 멤버 3
} Person;

 

typedef 로 구조체를 정의하고 별칭을 지정했다면

Person p1;

struct 를 생략하고 구조체 별칭으로 변수를 선언하면 된다

 

익명 구조체를 사용하면 구조체 이름을 지정하지 않아도 된다

typedef struct {   // 구조체 이름이 없는 익명 구조체
    char name[20];        // 구조체 멤버 1
    int age;              // 구조체 멤버 2
    char address[100];    // 구조체 멤버 3
} Person;

typedef 로 구조체를 정의하면서 이름을 생략할 수 있다

※ 구조체 이름을 생략할 때는 반드시 별칭을 지정해주어야 한다

 

 

2. 구조체 포인터

1. 메모리를 할당하고 구조체 포인터 사용하기

struct Person *p1 = malloc(sizeof(struct Person));

구조체도 포인터를 선언할 수 있다

구조체를 선언할 때는 반드시 struct 키워드를 붙여줘야 한다

sizeof 로 크기를 구할 때도 struct 를 넣어줘야 한다

 

구조체의 멤버에 접근 하려면 .(점)이 아닌 → (화살표)를 사용해야 한다

strcpy(p1->name, "홍길동");
p1->age = 30;
strcpy(p1->address, "서울시 용산구 한남동");

p1->age = 30; 과 같이 값을 할당하고

문자열 멤버는 strcpy 함수를 사용하여 값을 할당한다

 

구조체 별칭을 사용하면 좀 더 간단하게 포인터를 선언할 수 있다

Person *p1 = malloc(sizeof(Person));

구조체 별칭으로 바로 포인터를 선언한뒤 메모리를 할당하면 된다

sizeof 도 마찬가지로 struct 를 생략한다

 

 

2. 구조체 포인터에 구조체 변수 주소 할당하기

메모리를 할당하지 않고도 구조체 포인터를 사용할 수 있다

struct Person p1;		// 구조체 변수 선언
struct Person *ptr;		// 구조체 포인터 선언

ptr = &p1;

 

 

구조체 변수와 구조체 포인터를 선언하고

주소 연산자 & 를 사용하여

구조체 변수의 메모리 주소를 구조체 포인터에 할당한다

 

구조체 멤버에 접근 하는것도 -> 로 동일하다

ptr->age = 30;

ptr 에 p1 의 메모리 주소를 할당했으므로

ptr 의 멤버를 수정하면 결국 p1 의 멤버도 바뀌게 된다

구조체 변수의 주소와 구조체 포인터

접근하는 방식만 차이가 있을 뿐

결국 같은 곳의 내용을 수정하게 된다


3. 심사문제

48.8 자동차 계기판 구조체 선언하기

자동차에서 속도, 연료, 주행거리, 엔진 온도, 회전수를 표현하는 계기판 구조체가 정의되어 있습니다. 다음 소스 코드를 완성하여 계기판 정보가 출력되게 만드세요.

정답에는 밑줄 친 부분에 들어갈 코드만 작성해야 합니다.

#include <stdio.h>

struct Dashboard {
    int speed;
    char fuel;
    float mileage;
    int engineTemp;
    int rpm;
};

int main()
{
    __________________

    __________________
    __________________
    __________________
    __________________
    __________________

    printf("Speed: %dkm/h\n", d1.speed);
    printf("Fuel: %c\n", d1.fuel);
    printf("Mileage: %fkm\n", d1.mileage);
    printf("Engine temp: %d℃\n", d1.engineTemp);
    printf("RPM: %d\n", d1.rpm);

    return 0;
}

 

정답

struct Dashboard d1;

d1.speed = 80;
d1.fuel = 'F';
d1.mileage = 5821.442871;
d1.engineTemp = 200;
d1.rpm = 1830;

48.9 자동차 계기판 구조체 정의하기

다음 소스 코드에서 자동차의 속도, 연료, 주행거리, 엔진 온도, 회전수를 표현하는 계기판 구조체를 정의하고, 계기판 정보가 출력되게 만드세요. 

정답에는 밑줄 친 부분에 들어갈 코드만 작성해야 합니다.

#include <stdio.h>

_____________________
_____________________
_____________________
_____________________
_____________________
_____________________
_____________________

int main()
{
    Dashboard d1;

    d1.speed = 80;
    d1.fuel = 'F';
    d1.mileage = 5821.442871f;
    d1.engineTemp = 200;
    d1.rpm = 1830;

    printf("Speed: %dkm/h\n", d1.speed);
    printf("Fuel: %c\n", d1.fuel);
    printf("Mileage: %fkm\n", d1.mileage);
    printf("Engine temp: %d℃\n", d1.engineTemp);
    printf("RPM: %d\n", d1.rpm);

    return 0;
}

 

정답

typedef struct _Dashboard {
    int speed;
    char fuel;
    float mileage;
    int engineTemp;
    int rpm;
} Dashboard;

49.8 사람과 자동차 구조체 포인터에 메모리 할당하기

사람과 자동차 구조체가 정의되어 있습니다. 다음 소스 코드를 완성하여 사람과 자동차 정보가 출력되게 만드세요.

정답에는 밑줄 친 부분에 들어갈 코드만 작성해야 합니다.

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

struct Person {
    char name[20];
    int age;
    char address[100];
};

typedef struct {
    char name[20];
    int number;
    int displacement;
} Car;
 
int main()
{
    _________________________
    _________________________

    _________________________
    _________________________
    _________________________

    _________________________
    _________________________
    _________________________

    printf("이름: %s\n", p1->name);
    printf("나이: %d\n", p1->age);
    printf("주소: %s\n", p1->address);

    printf("자동차 이름: %s\n", c1->name);
    printf("자동차 번호: %d\n", c1->number);
    printf("배기량: %dcc\n", c1->displacement);

    free(p1);
    free(c1);

    return 0;
}

 

정답

struct Person *p1 = malloc(sizeof(struct Person));
Car *c1 = malloc(sizeof(Car));

strcpy(p1->name, "고길동");
p1->age = 40;
strcpy(p1->address, "서울시 서초구 반포동");

strcpy(c1->name, "스텔라");
c1->number = 3421;
c1->displacement = 2000;

구조체 별칭으로 선언된 포인터는 struct 키워드 생략이 가능하다


49.9 구조체 포인터에 구조체 변수의 주소 할당하기

3차원 좌표 구조체 Point3D 가 정의되어 있습니다. 다음 소스 코드를 완성하여 좌표 정보가 출력되게 만드세요.

정답에는 밑줄 친 부분에 들어갈 코드만 작성해야 합니다.

#include <stdio.h>

struct Point3D {
    float x;
    float y;
    float z;
};

int main()
{
    struct Point3D p1 = { 10.0f, 20.0f, 30.0f };
    struct Point3D *ptr;

    ______________
 
    printf("%f %f %f\n", ptr->x, ptr->y, ptr->z);

    return 0;
}

 

정답

ptr = &p1;