구조체와 공용체 - 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

구조체와 공용체 - 1

구조체와 필요성, 정의 방법과 구조체 변수, 구조체 배열과 구조체 포인터.

  • 학습 목표
    1. 구조체의 개념과 필요성 이해.
    2. 구조체의 정의와 구조체 변수 선언.
    3. 구조체 멤버 참조.
    4. 구조체 배열 사용.
    5. 구조체 포인터 사용.

주요 용어

  • 구조체 : 서로 다른 자료형을 갖는 자료들을 하나의 자료형으로 정으하여 사용하는 사용자 정의 자료형.
  • 구조체 멤버 : 구조체를 구성하는 변수.
  • 구조체 변수 : 정의된 구조체를 다루기 위한 변수.

구조체의 개념과 필요성

구조체(structure)

서로 다른 자료형을 갖는 자료의 모임을 하나의 자료형으로 정의하여 사용하는 자료형.
구조체 => 사용자 정의 자료형.

  • 다양한 형식의 자료를 간결한 형식으로 표현 가능.
  • 사용자가 새로운 형식을 정의하여 사용할 수 있음.

필요성

  char car1_maker[15];
  long int car1_km;
  long int car1_cost;

  char car2_maker[15];
  long int car2_km;
  ...

  long int car10_cost;
  struct vehicle {
    char maker[15];
    long int km;
    long int cost;
  }

  vehicle[10];

구조체의 정의와 변수 선언

구조체 정의

  • 형식
    •   struct 구조체_명 {
          멤버 _1;
          멤버 _2;
          ...
        }
  • ex
    •   struct score {
          int kor;
          int eng;
          ...
        }

구조체 변수의 선언

  • 형식
    •   struct 구조체_명 변수1, 변수2, 변수3;
  • EX
    •   struct score x, y[10], *z;

구조체 정의와 변수 선언 예 - 1

  • 실제 자료 형태

    • 학번 : 201XXXXXXX
    • 이름 : name
    • 국어 : 80
    • 영어 : 89
    • 수학 : 79
    • 국사 : 80
  • 구조체 정의

    •   struct score {  //  구조체 정의
          char no[10];  //  구조체 멤버
          char name[8];
          int kor;
          int ent;
          ... 
        }
      
        struct score x, y;  //  구조체 변수 x, y 선언

구조체 정의와 변수 선언 예 - 2

  struct score {
    char no[10];
    int ent;
    ... 
  } x, y;  //  구조체 변수 x, y 선언

구조체 정의와 변수 선언 예 - 3

  typedef struct score {
    char no[10];
    int ent;
    ... 
  } jumsu;  //  struct score를 jumsu라는 새로운 자료형으로 정의.
  jumsu x, y; //  새로운 자료형 jumsu의 변수 x, y 선언.

구조체 변수의 초기화 및 참조

초기화

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

  struct person x = {"asdf", 20, 'M'};
  struct person {
    char name[8];
    int age;
    char gender;
  } x = {"asdf", 20, 'M'};

참조

. 연산자 사용

  • 형식
    • 구조체변수명.멤버명
    • x.name
    • x.age
  #include <stdio.h>
  #include <string.h>

  struct person //  person형 구조체 선언
  {
    char name[8];
    int age;
    char gender;
  };

  void main()
  {
    //  구조체변수 x 선언, 초기화
    struct person x = {"asdf", 20, 'M'};

    //  구조체변수 y선언
    struct person y;
    //  구조체멤버에 값 대입(문자열 처리할 경우 문자열 복사함수 strcp() 사용).
    strcpy(y.name, "qwer");
    y.age = 20;
    y.gender = 'F';

    printf("x -> %s, %d, %c\n", x.name, x.age, x.gender);
    //  x -> asdf, 20, M
    printf("y -> %s, %d, %c\n", y.name, y.age, y.gender);
    //  y -> qwer, 20, F
  }

구조체의 기억공간 구조

 

구조체의 기억공간 구조

실제로 메모리가 할당될 때는 구조체 멤버 중 가장 큰 자료형의 크기로 할당 됨.
person.gender가 char 형이지만, 멤버 중 가장 큰 int 형의 크기인 4byte가 할당 됨.

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

  struct person //  person형 구조체 선언
  {
    char name[8];
    int age;
    char gender;
  };

  void main()
  {
    struct person x = {"asdf", 20, 'M'};

    printf("sizeof(person.name)   : %d byte\n", sizeof(x.name));   //  8
    printf("sizeof(person.age)    : %d byte\n", sizeof(x.age));    //  1
    printf("sizeof(person.gender) : %d byte\n", sizeof(x.gender)); //  1
    printf("sizeof(person)        : %d byte\n", sizeof(x));        //  16
  }

구조체 배열

동일한 구조를 갖는 구조체 변수가 여러 개 사용 될 때,
그 구조체 변수들을 대표하는 배열명을 설정하여 일반 배열과 같이 사용.

  • EX : 3명의 개인 신상정보를 저장하기 위한 구조체 배열 선언.
  struct person {
    char name[8];
    int age;
    char gneder;
  } x[3];

  struct person y[3];

구조체 배열의 기억공간 표현

- char name[8] int age char gender
x[0] x[0].name x[0].age x[0].gender
x[1] x[1].name x[1].age x[1].gender
x[2] x[2].name x[2].age x[2].gender

구조체 배열의 초기화

  struct person x[3] = {
    {"qwer", 20, 'M'}
    , {"asdf", 21, 'F'}
    , {"zxcv", 22, 'M'}
  }

구조체 배열의 참조

  //  구조체배열 2번째 요소 name에 'asdf' 저장.
  strcp(x[1].name, "asdf");
  //  구조체배열 3번째 요소 gneder에 'F' 저장.
  x[2].gender = 'F';
  //  구조체배열 3번째 요소 age 값을 변수 K에 저장.
  K = x[2].age;

구조체 배열의 사용 예

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

  struct person //  person형 구조체 선언
  {
    char name[8];
    int age;
    char gender;
  };

  void main()
  {
    //  구조체 배열 초기화.
    struct person x[3] =
        {
            {"qwer", 20, 'M'},
            {"asdf", 21, 'F'},
            {"zxcv", 22, 'M'}};

    int i, sum = 0;

    for (i = 0; i < 3; i++)
    {
      //  구조체 배열의 멤버 참조.
      printf("name : %s, age : %d, gender : %c\n", x[i].name, x[i].age, x[i].gender);
      sum = sum + x[i].age;
    }

    printf("SUM OF AGE : %d\n", sum);
  }

구조체 포인터

포인터를 사용하여 구조체를 다룰 수 있게 함.

  • 구조체를 보다 쉽게 다를 수 있음.
  • 구조체 변수 선언시 * 를 붙여 포인터로 선언.
  • 구조체 포인터는 포인터와 동일하게 주소값을 갖게 되며, 자료가 있는 곳을 가르킴.

구조체 포인터 선언

  • 형식 : struct 구조체_명 *포인터변수_명;
  • 사용 예 : struct person *pt;
  //  구조체 변수 man 선언
  struct person man;
  //  구조체 포인터 변수 pt 선언
  struct person *pt;
  //  구조체 포인터 변수의 초기화
  pt = &man;

구조체 포인터의 기억공간 표현

구조체 포인터의 기억공간 표현

 

구조체 포인터의 멤버 참조

  • . 도트 연산자 사용
    • (*pt).name
  • 포인터 연산자 -> 사용
    • pt -> name

구조체 포인터의 사용 예

  #include <stdio.h>

  struct student
  {
    char name[10];
    int kor;
    int math;
  };

  void main()
  {
    struct student classmate[4] =
        {
            {"A", 90, 80},
            {"B", 80, 90},
            {"C", 85, 85},
            {"D", 70, 100}};

    //  구조체 포인터 선언
    struct student *p;
    //  구조체 포인터 변수에 구조체의 시작주소 대입
    p = classmate;

    printf("%s %d %d\n", p->name, p->kor, p->math);
    p += 3;
    printf("%s %d %d\n", p->name, p->kor, p->math);
    p--;
    printf("%s %d %d\n", p->name, p->kor, p->math);
  }

실행 과정 (기억공간 표현)

 

 


728x90
반응형

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

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

+ Recent posts