컴퓨터 프로그래밍/C

C언어 구조체 (구조체 포인터 / typedef)

나노콛 2019. 7. 23. 10:24

구조체는 비슷하게 정리할 수 있는 변수들을 묶어서 새로운 자료형으로 만드는 것을 말합니다.

예를 들어 학생의 정보중 학번 나이 이름을 저장한다고 했을 때
한 사람이 3개의 변수를 사용하게 됩니다.
그러면 200명은 600개의 변수가 있어야겠죠
이런 불편한 점을 해결할 수 있는 게 구조체입니다.

#include <stdio.h>

//구조체 정의
struct Student
{
  int id;
  int age;
  char * name;
};  // 세미콜론 확인

int main()
{                      //구조체 변수 선언
  struct Student stu;  //자료형 Student 의 변수 stu 선언 
                       
  stu.id = 1001;   //구조체 안 멤버에 접근하려면 . 연산자(직접접근)
  stu.age = 20;
  stu.name = "nano";

  printf("id : %d\n", stu.id);
  printf("age : %d\n", stu.age);
  printf("name : %s\n", stu.name);
  
  return 0;
}

구조체를 정의합니다.
구조체는 중괄호로 구분하고 안의 변수는 멤버 혹은 필드라고 부릅니다.
이 멤버의 자료형은 다른 자료형이 있어도 상관없습니다.

struct Student stu; 이 구간에서는
정의된 구조체 Student로 구조체 변수를 선언합니다.
이 선언이 되어야 비로소 메모리가 할당됩니다.

구조체 안 멤버에게 접근하려면 . 연산자를 이용할 수 있습니다.
형태가 이러할 뿐 일반 사용은 기존대로 하면 됩니다.

 


구조체 포인터

 

#include <stdio.h>

struct Student
{
  int id;
  int age;
  char * name;
};

int main()
{
  struct Student stu;
  struct Student *Pstu;  //구조체 포인터 변수 선언

  Pstu=&stu;  //Pstu가 stu를 가리킨다.

  stu.id = 1001;   //구조체 안 멤버에 접근하려면 . 연산자(직접접근)
  stu.age = 20;
  stu.name = "nano";

  Pstu->id = 2001;   //구조체 포인터에 접근하려면 -> 연산자(간접접근)
  Pstu->age = 20;
  Pstu->name = "nano";


  printf("id : %d\n", stu.id);
  printf("age : %d\n", stu.age);
  printf("name : %s\n", stu.name);

  printf("p_id : %d\n", Pstu->id);
  printf("p_age : %d\n", Pstu->age);
  printf("p_name : %s\n", Pstu->name);

  return 0;
}

포인터는 * 연산자를 쓰며 해당 자료형의 주솟값을 저장할 수 있습니다.

struct Student *Pstu; 
형식이 구조체이기 때문에 구조체의 주소를 담을 수 있는 구조체 포인터 변수를 선언합니다.

 Pstu=&stu; 포인터 변수에 구조체의 주솟값(&주소 연산자)을 넘겨주면서
결국 Pstu는 stu를 가리키게 됩니다.

-> 연산자는 간접 접근 연산자입니다. 구조체 포인터 멤버에 접근할 때 씁니다.

 

이런 결과가 어떻게 나왔을까요
Pstu->id = 2001; 값을 Pstu->id에 넣었는데 결국 std.id도 같이 변경이 되었습니다.

이것은 포인터 때문인데요
Pstu는 stu의 주솟값을 가지고 있는데요
Pstu->id = 2001;  Pstu 안의 id에 접근하는 것처럼 보이지만
Pstu 안에는 주솟값만 가지고 있기 때문에 그 주소를 따라가서
결국 stu의 id에 접근을 하게 되어 stu.id도 똑같이 바뀌게 되는 것입니다.

 


typedef 사용자 정의

typedef는 기존의 존재하는 자료형에(구조체) 새 이름을 부여하는 것입니다.

정수 자료형 int를 int 말고 다른 이름을 부여할 수 있다는 뜻입니다.

typedef int InT;

int의 또 다른 이름 InT가 됩니다.
이제 InT로 변수 선언을 할 수 있습니다.

 

typedef int InT; 
InT num=10;

int num=20; //기존 자료형도 물론 사용가능

위와 같이 쓸 수 있습니다.

이런 typedef 선언으로 복잡한 자료형을 간결하게 만들 수 있는데요

typedef unsigned int UINT; //이런 긴 자료형 이름을 간결하게 만들 수 있다.

 

구조체에서의 typedef 선언에 대해서 알아봅시다.

구조체를 만들고 사용하기 위해서

struct 선언을 항상 붙였었는데요  ex) struct student person;
이것도 typedef로 이름을 부여하면 struct를 안 쓰고 편하게 변수를 선언할 수 있습니다.

 

#include <stdio.h>

typedef struct Data
{
  int deposit;
  int payment;
  int balance;
}Accout;  //사용자 정의 자료형 Account

int main()
{
  Accout acc;  // Account형 acc변수 생성

  acc.deposit = 10000;
  acc.payment = 5000;
  acc.balance = acc.deposit-acc.payment;

  printf("예금 : %d\n", acc.deposit);
  printf("출금 : %d\n", acc.payment);
  printf("잔액 : %d\n", acc.balance);
  
  return 0;
}