1. 구조체의 개념
구조체란 서로 다른 자료형을 갖는 자료들의 모임을 하나의 자료형으로 정의하여 사용하는 자료형입니다.
즉 구조체란 사용자 정의 자료형이라고 할 수 있습니다.
이러한 구조체의 장점으로는 다양한 형식의 자료를 간결한 형식으로 표현가능하다는 것과 사용자가 새로운 형식을 정의하여 사용할 수 있다는 것입니다.
1) 구조체의 필요성
예컨대 10대의 차량에 대한 자료처리의 경우 기존 자료형만으로는 아래처럼 코드가 구성됩니다.
charcar1_maker[15];
longint
car1_km;
longint
car1_cost;
charcar2_maker[15];
longint
car2_km;
long int car2_cost;
…
charcar10_maker[15];
long int car10_km;
longint
car10_cost;
그런데 구조체를 사용한다면 아래처럼 코드를 작성할 수 있습니다.
structvehicle
{
charmaker[15];
longint
km;
longint
cost;
}car[10];
구조체를 사용한 방법이 훨씬 간결한 것을 확인할 수 있습니다.
2. 구조체의 정의와 변수선언
1) 구조체 정의
구조체는 아래와 같이 정의합니다.
struct 구조체명{
멤버1;
멤버2;
...
};
예시는 아래와 같습니다.
struct score{
int kor;
int eng;
...
};
2) 구조체 변수의 선언
정의된 구조체에 들어있는 자료를 사용하기 위해서 구조체 변수를 선언하는데
이 구조체 변수를 선언하는 방법은 아래와 같습니다.
struct 구조체명 변수명1, 변수명2, 변수명3;
예제는 아래와 같습니다.
struct score x,y[10],*z;
3) 구조체 정의와 변수선언 예제
3. 구조체 변수의 초기화 및 참조
1) 초기화
구조체는 아래 예제들처럼 초기화를 합니다.
예제1)
struct person{
char name[8];
int age;
char sex;
};
struct person X={"홍길동",20,'M'};
예제2)
struct person{
char name[8];
int age;
char sex;
} X={"홍길동",20,'M'};
2) 구조체 멤버의 참조
형식은 아래와 같습니다.
구조체변수명.멤버명
예컨대 구조체 변수명이 X이고 멤버가 name, age, sex가 있다면 아래처럼 참조할 수 있습니다.
X.name
X.age
X.sex
예제는 아래와 같습니다.
예제1)
예제2)
4. 구조체 배열
구조체 배열이란 동일한 구조를 갖는 구조체 변수가 여러개 사용될 때 그 구조체 변수들을 대표하는 배열명을 설정하여 일반배열과 같이 사용하는 것을 말합니다.
예를 들어서 3명의 개인 신상정보를 저장하기 위한 구조체 배열은 아래처럼 선언합니다.
struct person{
char name[8];
int age;
char sex;
} X[3];
또는
struct person{
char name[8];
int age;
char sex;
};
struct personX[3];
구조체 배열의 기억공간 표현은 아래와 같습니다.
구조체 배열의 초기화는 아래처럼 이루어집니다.
구조체 배열의 참조는 아래와 같습니다.
구조체 배열을 사용한 예제는 아래와 같습니다.
5. 구조체 포인터
포인터를 사용하여 구조체를 다룰 수 있게 하는 것이 구조체 포인터입니다.
구조체 포인터를 사용하면 구조체를 보다 쉽게 다룰 수 있습니다. 구조체 포인터에서는 구조체 변수 선언시 *을 붙여 포인터로 선언합니다. 이 구조체 포인터는 포인터와 동일하게 주소값을 갖게 되며, 자료가 있는 곳을 가리킵니다.
1) 구조체 포인터의 선언
구조체 포인터의 선언방식은 struct 구조체명 *포인터변수명; 입니다.
예컨대 아래처럼 구현할 수 있습니다.
struct person *pt;
구조체 포인터의 선언에 대한 예제는 아래와 같습니다.
struct person{
char name[8];
int age;
char sex;
};
struct person man; //구조체 변수 man 선언
struct person *pt; //구조체 포인터 변수 pt 선언
pt=&man; // 구조체 포인터 변수의 초기화
2) 구조체 포인터의 기억공간 표현
3) 구조체 포인터의 멤버 참조
구조체 포인터가 멤버를 참조할 때에는 아래처럼 사용합니다.
첫번째는 도트 연산자를 이용합니다.
(*pt).name
두번째는 포인터 연산자 ->를 이용합니다.
pt -> name
4) 구조체 포인터 사용 예제
#include<stdio.h>
struct student{
char name[10];
int kor;
int math;
};
void main()
{
struct student hs[4]={{"KIMHG",90,95},{"LEESY",85,90}, {"PARKGS",70,85},{"CHOIHJ",95,75}};
struct student *p; // 구조체 포인터 선
p = hs; // 구조체 포인터 변수에 구조체의 시작 주소를 대입
printf("%s %d %d\n",p->name,p->kor,p->math); //KIMHG 90 95 // 첫번째 구조체의 각 멤버를 참조
p+=3; // 3개 다음의 구조체로 이동
printf("%s %d %d\n",p->name,p->kor,p->math); //CHOIHJ 95 75
p--; // 하나 전의 구조체로 이동
printf("%s %d %d\n",p->name,p->kor,p->math); //PARKGS 70 85
}
위 예제에 대한 기억공간 표현은 아래와 같습니다.
6. 함수와 구조체
1) 구조체를 함수의 매개변수로 사용
일반 변수를 함수의 매개변수로 사용하는 것과 동일한 방법을 사용합니다. 그러나 매개변수가 구조체인 경우 함수의 형식 매개변수를 구조체로 선언합니다.
이러한 방법은 해당 구조체 전체가 복사되기 때문에 편리 하지만 시간이 많이 걸리고 기억공간의 낭비가 심하다는 단점이 있습니다.
예제는 아래와 같습니다.
#include<stdio.h>
struct num calc(struct num);
struct num {
int x;
int y;
int sum;
int mul;
};
void main()
{
struct num number1; // 구조체 변수 선언
number1.x=10;
number1.y=20;
number1=calc(number1); // 피호출 함수 calc()에 struct num형 구조체를 매개변수로 넘겨줌
printf("x:%d,y:%d,sum:%d,mul:%d\n", number1.x,number1.y,number1.sum,number1.mul);
// 출력 x:10,y:20,sum:30,mul:200
getchar();
}
struct num calc(struct num number2){ // 넘겨받은 struct num형 구조체의 멤버끼리 계
number2.sum=number2.x+number2.y;
number2.mul=number2.x*number2.y;
return(number2);
}
이때 함수의 원형정의에 대한 설명은 아래와 같습니다.
2) 구조체 포인터를 함수의 매개변수로 사용
이 방법은 구조체를 복사하지 않기 때문에 실행속도가 향상되고, 기억공간의 사용효율이 좋다는 장점이 있습니다.
예제는 아래와 같습니다.
#include<stdio.h>
struct num calc(struct num *);
struct num {
int x;
int y;
int sum;
int mul;
};
void main()
{
struct num number1; // 구조체 변수 선언
number1.x=10;
number1.y=20;
calc(&number1); // 참조 호출(&사용)
printf("x:%d,y:%d,sum:%d,mul:%d\n", number1.x,number1.y,number1.sum,number1.mul);
// 출력 x:10,y:20,sum:30,mul:200
getchar();
}
struct num calc(struct num *number2){ // 구조체 포인터를 매개변수로 받
number2->sum=number2->x+number2->y;
number2->mul=number2->x*number2->y;
}
7. typedef
이미 존재하는 자료형에 새로운 이름을 붙이기 위한 키워드입니다.
간단하거나 의미있는 이름으로 바꿀 수 있어서 프로그램을 쉽게 이해할 수 있도록 하며 구조체 형을 선언하는데 많이 사용합니다.
1) 기본 방법
형식은 아래와 같습니다.
typedef 기존자료형 새로운 자료형이름;
예를 들면 아래와 같습니다.
typedef int INT;
typedef unsigned int BYTE; // unsigned int형을 BYTE라는 새로운 이름으로 정의
BYTE val; // 컴파일러가 unsigned int val로 해석
typedef int* PTR; //int* 를 PTR로 재정의
PTR p1,p2; // int *p1,*p2로 해석
사용예제는 아래와 같습니다.
#include<stdio.h>
struct data{
int x;
int y;
};
typedef struct data DATA; //data형 구조체를 새로운 이름 DATA로 정
void main()
{
DATA d={1,2}; //struct data d;와 동일
printf("d.x=%d,d.y=%d\n",d.x,d.y); //d.x=1,d.y=2
}
2) 구조제 표현의 다른 방법
struct data{
int x;
int y;
};
typedef struct data DATA;
위와 같은 코드를 아래처럼 사용할 수도 있습니다.
typedef struct data{
int x;
int y;
} DATA;
위 방식은 구조체 정의와 typedef 선언을 한꺼번에 표현한 것입니다.
3) 사용예제
#include<stdio.h>
#include<string.h>
struct person{
char name[20];
char sex;
int age;
};
typedef struct person MAN; //person형 구조체를 MAN으로 정의
typedef unsigned char CHAR; //unsigned char를 CHAR로 정의
typedef int* PTR; //int*를 PTR로 정의
void main()
{
MAN member; //struct personmember와 동일한 의미
CHAR data; //unsigned char data와 동일한 의미
PTR pt; //int* pt와 동일한 의미
strcpy(member.name,"홍길동");
member.sex='M';
member.age=30;
data=100; //unsigned char data에 100을 대입
pt=&(member.age); //person형 구조체의 age값 주소를 int* pt에 대입
printf("*pt=%d\n",*pt); //*pt=30
}
8. 구조체의 비트필드
좀 더 효율적인 프로그래밍을 위하여 주기억장치의 기억공간을 byte 단위가 아닌 bit 단위로 사용하는 것을 의미합니다.
프로그램 시 bit단위의 연산이 필요할 경우 int형 변수를 사용합니다.
이때 int형은 4byte(32bit)이므로 1bit를 제외한 31bit의 기억공간이 낭비됩니다 이 때 구조체의 비트필드를 사용하면 기억공간을 절약하고 더욱 융통성 있는 데이터 구조체를 만들 수 있습니다.
1) 구조체 비트필드의 정의
구조체 비트필드의 정의는 아래와 같이 합니다.
struct 비트필드명{
자료형 비트필드변수:비트크기;
..
};
예컨대 아래와 같습니다.
struct nibble{
unsigned a:1; //a는 1bit만 사용
unsigned b:2; //b는 2bit만 사용
unsigned c:1; //c는 1bit만 사용
};
2) 구조체 비트필드의 사용예제
#include<stdio.h>
void main()
{
struct test{
unsigned short a:5;
unsigned short b:6;
unsigned short c:6;
unsigned short d:4;
};
struct test v={1,2,3,4}; //구조체 비트필드 변수의 선언과 초기화
printf("v.a=%d v.b=%d v.c=%d v.d=%d\n", v.a,v.b,v.c,v.d); //v.a=1 v.b=2 v.c=3 v.d=4
printf("v는 %dbyte를 사용한다.\n",sizeof(v)); //v는 4byte를 사용한다.
}
위 코드에서 구조체 비트필드의 기억공간의 구조는 아래와 같습니다.
'C Programming > C' 카테고리의 다른 글
[C] 공용체 (0) | 2024.05.31 |
---|---|
[C] 포인터 (0) | 2024.05.17 |
[C] 배열 (1) | 2024.05.02 |
[C] 기억 클래스 (1) | 2024.04.26 |
[C] 함수 (0) | 2024.04.26 |