Skip to content

Latest commit

 

History

History
255 lines (201 loc) · 4.92 KB

211028.md

File metadata and controls

255 lines (201 loc) · 4.92 KB

Day 27

Review C

공용체

구조체와 정의 방법은 같으나 멤버를 저장하는 방식이 다름
구조체는 멤버들이 각각 공간을 차지하지만 공용체는 모든 멤버가 가장 큰 자료형의 공간을 공유

공용체 사용

union 공용체이름 {
    자료형 멤버이름;
};
/*------------------------------*/
union Box {
    short a; // 2바이트
    float b; // 4바이트
    char c[8] // 8바이트
};

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

printf("%d", sizeof(b1)); // 8 출력, 공용체의 전체 크기는 가장 큰 자료형의 크기

공용체 포인터

union Box {
    short a; // 2바이트
    float b; // 4바이트
    char c[8] // 8바이트
};

union Box *b1 = malloc(sizeof(union Box));

strcpy(b1->c, "what");

free(b1);

구조체 안에서 구조체 멤버 사용

struct Phone {
    int areacode;
    unsigned long long number;
};

struct Person {
    char name[20];
    int age;
    struct Phon phone;
}

struct Person p1;

p1.phone.areacode = 82; // 변수.멤버.멤버로 접근

구조체 안에 구조체 정의도 가능, 하지만 정의한 뒤 반드시 변수 선언을 해야함

struct Person {
    char name[20];
    int age;
    struct Phone {
        int areacode;
        unsigned long long number;
    } phone;
};

변수 선언과 동시에 초기화도 가능

struct Person p1 = { .name = "A", .age = 20, { .areacode = 82, .number = 123123} };
struct Person p2 = { "B", 20, { 82, 234234} };

메모리 할당도 가능

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

p1->phone.areacode = 82; // 포인터->멤버.멤버로 접근

free(p1);

열거형 정의

enum 열거형이름 {
    값1 = 초깃값,
    값2,
    값3
};
enum 열거형이름 변수이름;
/*--------------------------------------*/

enum Week {
    Sunday = 0,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday
};

enum Week week;

week = Tuesday;

printf("%d", week); // 2 출력

열거형도 typedef로 별칭 정의 가능

열거형을 switch에 활용

enum count {
    First = 1,
    Second,
    Third
};

enum count c1;

c1 = First;

switch (c1)
{
    case First:
        printf("First");
        break;
    case Second:
        printf("Second");
        break;
    case Third:
        printf("Third");
        break;
    default:
        break;
}

자료형 변환

(자료형)변수
(자료형)
/*----------------------*/

int n1 = 32;
int num2 = 7;
float num3;

num3 = (float)num1 / num2;

포인터 변환

(자료형 *)포인터
*(자료형 *)포인터 // 포인터를 변환하면서 역참조
/*--------------*/

int *numPtr = malloc(sizeof(int));
char *cPtr;

*numPtr = 0x12345678;

cPtr = (char *)numPtr;

printf("%x", *cPtr); // 78 출력, 낮은 자릿수 1바이트를 가져옴

free(numPtr);

void 포인터 변환

*(자료형 *)void 포인터
/*--------------------------------*/

int n1 = 10;
void *ptr;

ptr = &n1;
printf("%d", *(int *)ptr); // 10 출력, void 포인터를 int 포인터로 변환하고 역참조, void 포인터는 역참조할 수 없기 때문

구조체 포인터 변환

(struct 구조체이름 *)포인터
((struct 구조체이름 *)포인터)->멤버
/*-------------------------------------------*/

struct Data {
    char c1;
};

struct Data *d1 = malloc(sizeof(struct Data));
void *ptr;

d1->c1 = 'a';

ptr = d1;

printf("%c", ((struct Data *)ptr)->c1); // a 출력

free(d1);

포인터 연산으로 메모리 주소 조작

포인터 변수에 +, -, ++, --를 사용, *나 / 연산자와 실수는 사용 불가

포인터 + 
포이터 - 
/*-----------------------*/

int numArr[5] = {1, 2, 3, 4, 5};
int *numPtrA;

numPtrA = numArr;

printf("%p %p %p", numPtrA, numPtrA + 1, numPtrA + 2); // 메모리주소, 메모리주소 + 4, 메모리주소 + 8 출력, +1을 할 때마다 int형의 크기인 4바이트씩 증가
printf("%d %d", *numPtrA, *(numPtrA + 1)); // 1 2 출력, *(numPtrA + 1) == numArr[1]

void 포인터로 포인터 연산

void 포인터는 자료형의 크기가 정해져 있지 않아 연산을 해도 얼마나 이동할지 알 수 없어 포인터 연산을 할 수 없다.

(자료형 *)void포인터 + 
/*-------------------*/

(int *)void v1 + 1

구조체 포인터로 포인터 연산

(포인터 + )->멤버
/*-----------------------------------*/

struct Data {
    int n1;
    int n2;
};

struct Data d[3] = { { 1, 2 }, { 3, 4 }, { 5, 6 } };
struct Data *ptr;

ptr = d;

printf("%d", (ptr + 1)->n1); // 3 출력, d[1].n1과 같음
printf("%d", (ptr + 2)->n2); // 6 출력, d[2].n2와 같음

포인터 연산을 하면 구조체 크기만큼 더하고 뺌

void 포인터로도 가능

((struct 구조체이름 *)포인터 + )->멤버
/*-----------------------------------*/

void *ptr = malloc(sizeof(struct Data) * 3);
((struct Data *)ptr)->n1 = 10;
free(ptr);