Coding/C

[C언어] 공용체, 구조체 & 공용체 활용 - 코딩도장

GunP4ng 2024. 1. 24. 23:40

[코딩도장] Unit 54 ~ 55


1. 공용체

1. 공용체 사용하기

공용체와 구조체는 정의 방법이 같지만

멤버를 저장하는 방식에서 차이가 있다

구조체

구조체는 각 멤버들이 각각 공간을 차지한다

공용체

공용체는 가장큰 자료형의 공간을 공유하여 사용한다

 

union Box {    // 공용체 정의
    short candy;     // 2바이트
    float snack;     // 4바이트
    char doll[8];    // 8바이트
};

공용체는 union 을 사용하여 선언한다

 

공용체도 정의만 해서는 사용할 수가 없기 때문에 변수로 선언해서 사용해야 한다

union Box b1;   // 공용체 변수 선언

 

Box 공용체에서 가장 큰 자료형은 char doll[8] 로 8바이트이다

따라서 공용체의 크기는 8바이트가 된다

공용체의 전체 크기

 

공용체는 가장 큰 자료형의 공간을 공유하기 때문에

한 멤버에 값을 저장하면 다른 멤버는 사용할 수 없게 된다

 

공용체도 malloc 함수를 이용하여 메모리를 할당하여 포인터로 사용할 수 있다

union Box *b1 = malloc(sizeof(union Box));    // 공용체 포인터 선언, 메모리 할당

일반 변수가 아닌 포인터 변수이기 때문에 반드시 * 을 붙여야 한다

 

구조체와 마찬가지로 공용체에 접근할 때도

-> (화살표 연산자)를 사용한다

strcpy(b1->doll, "bear");     // doll에 문자열 bear 복사

 

 

 

2. 구조체 & 공용체 활용

1. 구조체 안에서 구조체 사용하기

구조체는 구조체를 멤버로 가질 수 있다

struct Phone {    // 휴대전화 구조체
    int areacode;                 // 국가번호
    unsigned long long number;    // 휴대전화 번호
};

struct Person {    // 사람 구조체
    char name[20];         // 이름
    int age;               // 나이
    struct Phone phone;    // 휴대전화. 구조체를 멤버로 가짐
};

구조체를 멤버로 가지려면

구조체 안에서 구조체 변수를 선언하면 된다

 

C언어는 위에서부터 컴파일 하기 때문에

안에 들어가는 구조체를 먼저 선언해줘야 한다

 

구조체 멤버에 접근 할 때는 . (점)을 사용한다

p1.phone.areacode = 82;          // 변수.멤버.멤버 순으로 접근하여 값 할당
p1.phone.number = 3045671234;    // 변수.멤버.멤버 순으로 접근하여 값 할당

 

구조체를 특정 구조체 안에서만 사용한다면

구조체 안에서 구조체를 정의할 수 있다

struct Person {    // 사람 구조체
    char name[20];    // 이름
    int age;          // 나이
    struct Phone {    // 휴대전화 구조체를 사람 구조체 안에 정의
        int areacode;                 // 국가번호
        unsigned long long number;    // 휴대전화 번호
    } phone;                          // 구조체를 정의하는 동시에 변수 선언

구조체 안에서 구조체를 정의할 때는

반드시 변수를 선언해줘야 한다

 

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

구조체 포인터에 메모리를 할당하고 각 멤버에 접근하려면

 

p1->phone.areacode = 82;          // 포인터->멤버.멤버 순으로 접근하여 값 할당
p1->phone.number = 3045671234;    // 포인터->멤버.멤버 순으로 접근하여 값 할당

p1 은 포인터이므로 -> 연산자를 사용하고

phone 은 일반 변수이므로 . (점)을 사용하여 접근한다

 

 

2. 구조체 & 공용체 활용하기

struct Vector3 { // 3차원 벡터 좌표
    union {          // 익명 공용체
        struct {         // 익명 구조체
            float x;         // x 좌표
            float y;         // y 좌표
            float z;         // z 좌표
        };
        float v[3];      // 좌표를 배열로 저장
    };
};

x, y, z 좌표를 저장하는 Vector3 구조체를 정의하고

 

struct Vector3 pos;

구조체 변수를 선언한다

 

맨 안쪽 float x, y, z 는 익명 구조체이다

각각의 값을 독립적인 공간에 저장하기 위해 구조체로 정의한다

 

익명 공용체가 x, y, z  익명 구조체와 배열 v 를 감싸고 있다

pos.v 처럼 멤버에 접근하기 위해 익명 공용체로 정의한다

 

익명 구조체와 익명 공용체

공용체는 가장 큰 자료형의 공간을 공유하므로

x, y, z 구조체는 v[3] 와 같은 공간을 공유하게 된다

 

익명 공용체와 익명 구조체를 사용하면 같은 값이지만

이름과 형태를 바꿔 접근할 수 있다


3. 심사문제

54.7 정수 데이터 공용체 정의하기

다음 소스 코드를 완성하여  0x11 4 가 출력되게 만드세요.

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

#include <stdio.h>

___________ 
___________ 
___________ 
___________ 

int main()
{
    union Data d1;

    d1.num1 = 0x1111;

    printf("0x%x %d\n", d1.c1, sizeof(d1));

    return 0;
}  

 

정답

union Data {
    char c1;
    int num1;
};

54.8 공용체 포인터 사용하기

다음 소스 코드를 완성하여 0x1111 0x11111111 이 출력되게 만드세요.

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

#include <stdio.h>
#include <stdlib.h>

union Data {
    short num1;
    int num2;
};

int main()
{
    ______________________
    
    ______________________

    printf("0x%x 0x%x\n", d1->num1, d1->num2);

    free(d1);

    return 0;
}

 

정답

union Data *d1 = malloc(sizeof(union Data));

d1->num2 = 0x11111111;

55.8 게임 캐릭터 구조체 포인터 사용하기

다음 소스 코드를 완성하여 "Swain"과 463.000000이 출력되게 만드세요.

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

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

struct Stats {
    float health;
    float healthRegen;
    unsigned int mana;
    float manaRegen;
    float range;
    float attackDamage;
    float armor;
    float attackSpeed;
    float magicResist;
    unsigned int movementSpeed;
};
 
struct Champion {
    char name[20];
    struct Stats stats;
    float abilityPower;
};

int main()
{
    ______________________

    ______________________
    ______________________

    swain.stats.healthRegen = 1.48f;
    swain.stats.mana = 290;
    swain.stats.manaRegen = 1.49f;
    swain.stats.range = 500;
    swain.stats.attackDamage = 52.0f;
    swain.stats.attackSpeed = 0.625f;
    swain.stats.armor = 20.0f;
    swain.stats.magicResist = 30;
    swain.stats.movementSpeed = 335;
    swain.abilityPower = 0;

    printf("%s %f\n", swain.name, swain.stats.health);

    return 0;
}

 

정답

struct Champion swain;

strcpy(swain.name, "Swain");
swain.stats.health = 463;

55.9 게임 캐릭터 구조체 포인터 사용하기

다음 소스 코드를 완성하여 "Swain" 과 463.000000이 출력되게 만드세요.

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

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

struct Stats {
    float health;
    float healthRegen;
    unsigned int mana;
    float manaRegen;
    float range;
    float attackDamage;
    float armor;
    float attackSpeed;
    float magicResist;
    unsigned int movementSpeed;
};
 
struct Champion {
    char name[20];
    struct Stats *stats;
    float abilityPower;
};

int main()
{
    _____________________________
    _____________________________

    _____________________________
    _____________________________

    swain->stats->healthRegen = 1.48f;
    swain->stats->mana = 290;
    swain->stats->manaRegen = 1.49f;
    swain->stats->range = 500;
    swain->stats->attackDamage = 52.0f;
    swain->stats->attackSpeed = 0.625f;
    swain->stats->armor = 20.0f;
    swain->stats->magicResist = 30;
    swain->stats->movementSpeed = 335;
    swain->abilityPower = 0;

    printf("%s %f\n", swain->name, swain->stats->health);

    free(swain->stats);    
    free(swain);    

    return 0;
}

 

정답

struct Champion *swain = malloc(sizeof(struct Champion));
swain->stats = malloc(sizeof(struct Stats));

strcpy(swain->name, "Swain");
swain->stats->health = 463;

55.10 장치 옵션 구조체 만들기

다음 소스 코드를 완성하여 0x1122 가 출력되게 만드세요.

opt.boot 와 opt.interrupt의 자료형은 unsigned char입니다.

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

#include <stdio.h>

____________________________
____________________________
____________________________
____________________________
____________________________
____________________________
____________________________
____________________________
____________________________

int main()
{
    struct DeviceOption opt;

    opt.boot = 0x22;
    opt.interrupt = 0x11;

    printf("0x%x\n", opt.option);

    return 0;
}

 

정답

struct DeviceOption {
    union {
        unsigned short option;
        struct {
            unsigned char boot;
            unsigned char interrupt;
        };
    };
};