구조체와 공용체 - 2
함수와 구조체, typedef, 구조체 비트필드, 공용체.
- 학습 목표
- 구조체를 이용한 매개변수사이의 자료전달 방법 이해.
- typedef를 이용하여 새로운 자료형 정의.
- 구조체 비트필드를 선언 및 사용.
- 공용체 사용.
주요 용어
- 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 |