구조체와 공용체 - 2

함수와 구조체, typedef, 구조체 비트필드, 공용체.

  • 학습 목표
    1. 구조체를 이용한 매개변수사이의 자료전달 방법 이해.
    2. typedef를 이용하여 새로운 자료형 정의.
    3. 구조체 비트필드를 선언 및 사용.
    4. 공용체 사용.

주요 용어

  • typedef : 이미 존재하는 자료형에 새로운 이ㅁ을 부여하기 위한 키워드.
  • 구조체 비트필드 : 주기억장치의 기억공간을 byte 단위가 아닌 bit 단위로 사용하는 방법.
  • 공용체 : 동일한 기억장소에 여러 유형의 자료를 저장하기 위해 정의하는 자료형.

함수와 구조체

함수에서의 구조체 사용

구조체를 함수의 매개변수로 사용

  • 일반 변수를 함수의 매개변수로 사용하는 것과 동일.

  • 매개변수가 구조체인 경우 함수의 형식매개변수를 구조체로 선언.

  • 해당 구조체 전체가 복사되기 때문에 편리.

  • 구조체 전체가 복사되기 때문에 시간이 많이 걸리고, 기억공간의 낭비가 심함.

    • #include <stdio.h>
      
      //  함수의 원형 정의 -> struct -> int나 char와 같은 일종의 자료형.
      struct num calc(struct num); 
      struct num
      {
        int x, y, sum, mul;
      };
      
      void main()
      {
        // 구조체 변수 선언.
        struct num num1;
        num1.x = 10;
        num1.y = 20;
      
        //  피호출함수 calc()에 struct num형 구조체를 매개변수로 넘김.
        num1 = calc(num1);
      
        printf("x : %d, y : %d, sum : %d, mul : %d\n", num1.x, num1.y, num1.sum, num1.mul);
      }
      
      //  넘겨받은 struct num형 구조체의 멤버끼리 연산, 구조체를 리턴함
      struct num calc(struct num num)
      {
        num.sum = num.x + num.y;
        num.mul = num.x * num.y;
        return num;
      }

구조체 포인터를 함수의 매개변수로 사용

  • 일반적으로 구조체 포인터를 함수의 매개변수로 사용.

  • 구조체를 복사하지 않기 때문에 실행속도가 향상, 기억공간의 사용 효율 증가.

    • #include <stdio.h>
      
      struct num calc(struct num *);
      struct num
      {
        int x, y, sum, mul;
      };
      
      void main()
      {
        // 구조체 변수 선언.
        struct num num1;
        num1.x = 10;
        num1.y = 20;
      
        // 참조호출 & 사용.
        num1 = calc(&num1);
      
        printf("x : %d, y : %d, sum : %d, mul : %d\n", num1.x, num1.y, num1.sum, num1.mul);
      }
      
      // 구조체포인터를 매개변수로 넘겨받음.
      struct num calc(struct num *num)
      {
        num->sum = num->x + num->y;
        num->mul = num->x * num->y;
      }

typedef

이미 존재하는 자료형에 새로운 이름은 붙이기 위한 키워드.

  • 간단하거나 의미있는 이름으로 바꿀 수 있어 프로그램 이해가 쉽다.

  • 구조체 형을 선언하는데 많이 사용.

  • 형식

    • typedef 기존_자료형 새로운_자료형_이름;
    • typedef int INT;

    •   //  unsigned int 형을 BYTE라는 이름으로 정의.
        typedef unsignd int BYTE; 
        //  컴파일러가 unsigned int val로 해석
        BYTE val;
      
        //  int *를 PTR로 재정의.
        typedef int * PTR;
        //  int *p1, *p2를 의미.
        PTR p1, p2;
    •   #include <stdio.h>
      
        struct data {
          int x, y;
        };
      
        //  data형 구조체를 새로운 이름 DATA로 정의.
        typedef struct data DATA;
      
        void main() {
          //  struct data d = {1, 2}; // ->
          DATA d = {1, 2};
      
          printf("d.x : %d, d.y : %d\n", d.x, d.y);
        }

typedef를 이용한 구조체 표현의 다른 방법

  struct data {
    int x, y;
  };

  typedef struct data DATA;

  //   구조체 정의와 typedef 선언을 한번에 표현.
  typedef struct data {
    int x, y;
  } DATA;
  #include <stdio.h>
  #include <string.h>

  struct person {
    char name[20];
    char gender;
    int age;
  };

  // person 형 구조체를 MAN으로 정의.
  typedef struct person MAN;
  // unsigned char를 CHAR로 정의.
  typedef unsigned char CHAR;
  // int *를 PTR로 정의.
  typedef int *PTR;

  void main() {
    //  struct person memb; // ->
    MAN memb;
    // unsigned char data; // ->
    CHAR data;
    // int * pt; // ->
    PTR pt;

    strcpy(memb.name, "ASDF");
    memb.gender = 'F';
    memb.age = 30;

    //  unsignd char data에 100 대입.
    data = 100;
    // person형 구조체의 age값 주소를 int* pt에 대입.
    pt = &(memb.age);

    printf("*pt = %d\n", *pt);
  }

구조체 비트필드(bit field)

  • 주기억장치의 기억공간을 byte 단위가 아닌 bit 단위로 사용
    • 프로그램 시 bit 단위의 연산이 필요할 경우 int 형 변수를 사용.
    • 이때 int형은 4 byte (32 bit)이므로 1 bit를 제외한 32 bit의 기억공간 낭비가 발생함.
  • 구조체 비트필드를 사용하면
    • 기억공간 절약.
    • 융통성 있는 데이터 구조체 생성 가능.

구조체 비트필드의 정의

  struct 비트필드명 {
    자료형 비트필드변수 : 비트크기;
  };

  struct bit_filed {
    unsigned a : 1; // -> 1 bit;
    unsigned g : 2; // -> 2 bit;
  }

구조체 비트필드의 선언 예와 기억공간 구조

  struct tt {
    unsigned short a : 4;
    unsigned short b : 2;
    unsigned short c : 1;
    unsigned short d : 7;
  };
  //  구조체 비트필드 변수의 선언.
  struct tt bit;

 

구조체 비트필드의 기억공간 구조

구조체 비트필드의 참조

  • 비트필드의 자료형은 int나 unsigned로 선언.
  • 비트필드에 대한 포인터나 배열은 사용 안됨.
  • 비트필드의 전체 크기는 시스템이 제공하는 int의 크기 이내여야 함.
  struct tt
  {
    unsigned a : 4;
    unsigned b : 2;
    unsigned c : 1;
    unsigned d : 7;
  };

  struct tt bit;
  //  필드에 값 대입
  bit.a = 15;
  bit.b = 3;
  bit.c = 0;
  bit.d = 127;
  #include <stdio.h>

  void main() {
    //  구조체 비트필드의 정의.
    struct tt {
      unsigned a : 5;
      unsigned b : 6;
      unsigned c : 6;
      unsigned d : 4;
    };

    //  고조체 비트필드 변수의 선언과 초기화.
    struct tt v = {1, 2, 3, 4};

    printf("v : { a : %d, b: %d, c : %d, d : %d }\n", v.a, v.b, v.c, v.d);
    // v : { a : 1, b: 2, c : 3, d : 4 }
    printf("v's usage is %d byte.\n", sizeof(v));
    // v's usage is 4 byte.
  }

구조체 비트필드의 기억공간 구조

  struct tt {
    //  비트필드의 총 수가 int의 크기보다 클 경우 ->
    // 비트필드가 2개의 int 사이에 걸쳐 저장될 수 없다.
    unsigned short a : 5;
    unsigned short b : 6;
    unsigned short c : 6;
    unsigned short d : 4;
  };

 

구조체 비트필드의 기억공간 구조


공용체의 개념

공용체 (union)

  • 동일한 기억장소에 여러 유형의 자료를 저장하기 위해서 프로그래머가 선언한 자료형.
  • 공용체 안에 포한된 자료들이 같은 기억장소를 공유하여 사용.
  • 사용될 자료의 자료형이 유동적일 경우 기억 공간을 효율적으로 사용할 수 있는 장점.

공용체의 예

  • 공용체의 멤버들이 완전히 다른 자료형을 가질 때 기억공간을 절약하기 위해 사용.
  • ex :
    • 급여관리
      • 원화로 월급을 지급받는 사람 : 정수형으로 처리.
      • 달러로 월급을 지급받는 사람 : 실수형으로 처리.
      • 공용체를 사용하면 필요에 따라 메모리의 자료형을 선택해서 값 저장 가능.

공용체 정의

  union 공용체명 {
    field 1;
    field 2;
  }

  union var {
    char a;
    int b;
    float c;
  }

공용체 변수 선언

  • 형식 : union 공용체명 변수명;
  • 사용 예 : unioin var abc;

공용체 졍의와 변수 선언 예

  //  공용체 정의
  union var {
    //  공용체 멤버
    char a, int b, float c;
  };
  //  공용체 변수 선언
  union var abc; 

공용체 변수의 참조 방법

  union var
  {
    char a, int b, float c;
  };
  union var abc;
  // 공용체 변수의 참조
  abc.a = 'A';
  abc.b = 133;
  abc.c = 1234.5678;

공용체의 사용

  • 공용체가 사용 되면
    • 공용체의 멤버 중에서 자료크기(byte 수)가 가장 큰 멤버에 대해서만 기억공간이 할당.
    • 기억 공간의 시작 위치부터 각 부분을 다른 멤버가 공용으로 사용.

공용체 기억공간 표현의 예

  union hold {
    short int digit;
    double big;
    char letter;
  }

 

공용체 기억공간

공용체 변수의 참조 예

  union hold {
    short int digit;
    double big;
    char letter;
  };
  union hold fit; 

  fit.digit = 23;     //  2 byte 사용.
  fit.big = 1234.567; //  23이 지워지고 1234.567 저장 (8 byte 사용)
  fit.letter = 'b';   //  1234.567 삭제, 'b' 저장. (1 byte 사용)

공용체 변수의 기억공간 사용 예

 

공용체 변수의 기억공간 사용 예

 

공용체 변수의 사용 예

  #include <stdio.h>

  void main()
  {
    union tt
    {
      short int i;
      float f;
      double d;
    };
    //  공용체 변수 선언
    union tt t;

    t.i = t.f = t.d = 0;

    printf("%d byte \n", sizeof(t));

    t.i = 100;

    printf("%d %f %f\n", t.i, t.f, t.d);

    t.f = 0.5;
    printf("%d %f %f\n", t.i, t.f, t.d);

    t.d = 0.016677;
    printf("%d %f %f\n", t.i, t.f, t.d);
  }

728x90
반응형

'Language > C' 카테고리의 다른 글

[C] 파일 처리 함수 - 2  (0) 2021.01.02
[C] 파일 처리 함수 - 1  (0) 2021.01.01
[C] 구조체와 공용체 -1  (0) 2020.12.27
[C] 배열과 포인터 - 3  (0) 2020.12.27
[C] 배열과 포인터 - 2  (0) 2020.12.27

+ Recent posts