C언어, 구조체

Moon·2022년 10월 24일
2

해당 게시글은 유튜브 - 동영상 강좌 - 'Do it! C언어 입문' - 18장 구조체와 연결리스트 (1/2)
를 학습하며 정리한 글입니다.

게시글에 작성된 그림은 모두 업로드된 유튜브 영상에서 캡처해온 것입니다.


Brainstorming!
배열과 구조체는 어떻게 다를까?

  • 배열 : 동일한 데이터를 그룹(국어점수별 그룹, 영어점수별 그룹)
  • 구조체 : 서로 다른 데이터를 그룹(각 학생의 국어, 영어 점수를 그룹)

typedef 문법

typedef란?

  • type define의 줄임 표현
  • 기존 자료형 이름의 길이가 긴 경우 자료형을 재정의하여 사용하는 문법
  • #define은 비슷해 보이지만 다름(#define은 전처리기)!
  • 구조체는 사용자 정의 자료형 정의 방법 중 한 가지
#include <stdio.h>

typedef unsigned short int US;

void main(){
    unsigned short int data = 5;
    US temp; // unsigned short int temp;라고 선언해준 것과 똑같음

    temp = data;
    printf("temp = %d\n", temp);
}

typedef의 장점 1. 복잡해 보이는 문법을 쉽게 표현

  • typedef는 배열, 포인터와 같은 형식도 재정의 가능
typedef int MY_DATA[5];
MY_DATA temp; // int temp[5]라고 선언한 것과 일치함
int(*p)[5]; // 20바이트의 사용범위를 가진 포인터 변수..인데 이건 너무 보기 어려움
typedef int MY_DATA[5];
MY_DATA *p; // int(*p)[5]라고 선언한 것과 같고 보기도 편함.

typedef의 장점 2. 자료형의 크기를 쉽게 바꿀 수 있음

  • age 변수의 크기를 1바이트에서 2바이트로 변경해야 하는 경우
  • char age; 를 short int age;로 바꿔야 하는데 typedef를 쓰지 않았다면 모든 함수에 찾아다니며 char age를 수정해야함.
    -> typedef char AGE;만 typedef short int AGE;로 바꿔주면 끝!

데이터를 그룹으로 묶는 구조체

Question. 5명의 나이(int), 키(float), 몸무게(float)를 관리해야 한다면?
1. 배열을 사용하는 경우

  • 한계 : 나이, 키, 몸무게 별로 보는 것보다 특정 사람의 정보를 모아서 그룹을 만드는 것이 개인별 출력에서는 효율적이다.
  1. 구조체를 사용하는 경우
  • C언어는 크기나 형식이 다른 데이터를 그룹으로 묶어 쓸 수 있도록 구조체(Structure) 문법을 제공
  • 기본 자료형, 사용자가 정의한 자료형을 그룹으로 묶어 새로운 자료형으로 사용 가능
  • 구조체로 새로운 자료형을 만들 경우
struct People{ // 12+2+4+4 = 22바이트 구조체 생성
	char name[12]; // 12바이트
	unsigned short int age; // 2바이트
	float height; // 4바이트
	float weight; // 4바이트
};

struct People data; // People의 data라는 변수의 크기는 22바이트
struct People friend_list64; // People의 배열 변수의 크기는 22*64바이트
struct People *p; // 포인터 변수 : p변수의 크기는 4바이트(주소값저장)

구조체 변수를 선언할 때 매번 struct 키워드를 붙여야하는 불편함이 있기 때문에 이를 해결하기 위해 struct와 typedef를 조합해서 구조체 변수를 선언하는 방법이 있다.

struct People{
	...
}
typedef struct People Person; // struct People을 Person이라는 자료형으로 재정의

Person data; //struct People data;
Person friend_list[64]; //struct People friend_list64;
Person *p; // struct People *p;

구조체로 선언한 변수의 요소 사용하기

  • 구조체로 선언한 변수는 '.'과 '자신이 사용할 요소'의 이름을 함께 적어 사용
typedef struct People{ 
	char name[12]; // 12바이트
	unsigned short int age; // 2바이트
	float height; // 4바이트
	float weight; // 4바이트
}Person;

void main(){
	Person data;
    data.age = 21; // 이렇게 사용합니다
    data.height = 178.3;
}
  • 구조체를 사용해서 사람의 신체 정보를 입력 받고 출력하기
#include <stdio.h>

typedef struct People{
    char name[12];
    unsigned short int age;
    float height;
    float weight;
} Person;

void main(){
    Person data;
    printf("대상자의 정보를 입력하세요\n");
    printf("이름 :");
    scanf("%s", data.name);
    printf("나이 :");
    scanf("%hu", &data.age);
    printf("키 :");
    scanf("%f", &data.height);
    printf("몸무게 :");
    scanf("%f", &data.weight);
    printf("\n 입력한 정보는 다음과 같습니다.\n");
    printf("%s : %d세, %.1fcm, %.1fkg\n", data.name, data.age, data.height, data.weight);
}
  • 구조체로 선언한 변수의 요소(배열) 사용하기
Person friends[3]; // Person 데이터 3개를 저장할 수 있는 메모리를 할당
friends[1].age = 22; // 두 번째 요소의 age 값에 22를 대입
  • 구조체로 선언한 변수를 포인터로 사용하기
Person data;
Person *p; // Person형식으로 선언한 메모리에 접근할 수 있는 포인터 선언
p = &data; // 포인터 변수 p는 data변수의 주소 값을 저장
(*p).age = 23; // p에 저장된 주소에 가서 age 값에 23을 대입
  • 구조체 연산자 우선순위
    '*'연산자가 '.' 연산자보다 우선순위가 낮기 때문에 *p.age = 23은 오류가 발생한다
    이를 해결하기 위해 연산자 우선순위 문제를 해결하는 '->' 연산자를 사용한다
Person data;
Person *p; // Person형식으로 선언한 메모리에 접근할 수 있는 포인터 선언
p = &data; // 포인터 변수 p는 data변수의 주소 값을 저장
p -> age = 23; // (*p).age=23; 과 동일
profile
안녕하세요. Moon입니다!

0개의 댓글