포인터공부7 - 구조체
1. 구조체?
= 타입이 다른 변수들의 집합 ↔ 배열 : 타입이 같은 변수들의 집합
ex) struct {
char Name[10];
int Age;
double Height;
} Friend; // Friend라는 이름을 가진 구조체
+ Member : 구조체에 속한 변수들
■ 구조체 태그
= 구조체의 타입에 대해 이름을 붙이는 것이다 ( 우리가 아는 인스타그램의 해쉬태그와 같은 느낌이라고 생각하면 된다)
struct 태그명 { 멤버 목록 };
- 태그 선언문은 컴파일러에게 구조체의 모양이 어떻다는 것을 등록할 뿐이지 태그를 위해 메모리를 할당한다거나 변수를 생성하는 것은 아니며
중복 선언해도 상관없다.
- 새로운 타입을 정의하는 typedef문을 사용하면 태그를 정의하는 것과 동일한 효과를 낼 수 있다. 다음 선언문은 FriendType이라는 새로운 타입을 정의한다.
ex) typedef struct {
char Name[10];
int Age;
double Height;
} FriendType;
- 다음 세가지 방법으로 선언되는 Friend 변수는 동일한 구조체 변수이다
struct { char Name[10]; int Age; double Height; } Friend; | struct tag_Friend { char Name[10]; int Age; double Height; }; tag_Friend Friend; | typedef struct { char Name[10]; int Age; double Height; } FriendType; FriendType Friend; |
보기에는 첫번째 방법이 간단해 보이지만 2번째 방법인 태그를 선언하는 것이나 3번째 방법인 사용자 정의 타입을 사용할 때 장점이 있다
1) 타입이 정의 되면 이 타입으로 같은 형의 변수를 여러 번 선언할 수 있다.
ex) tag_Friend A,B,C;
tag_Friend Babo;
2) 이 타입으로부터 파생되는 유도형 변수를 선언할 수 있다.
예를 들어 tag_Friend형의 구조체를 가리키는 포인터 변수를 선언하고 싶다거나 이런 구조체 여러 개를 모아 배열을 구성하고 싶다면 다음과 같이 선언한다.
ex)
tag_Friend *pFriend;
tag_Friend arFriend[100];
3) 구조체를 함수의 인수나 리턴값으로도 사용할 수 있다.
예를 들어 친구의 신상 명세를 출력하는 OutFriend라는 함수를 만들어야 한다고 해 보자.
이름, 나이, 키 등의 정보를 따로따로 넘기지 않으려면 구조체를 통째로 넘기거나 아니면 구조체 포인터를 넘겨야 한다.
OutFriend 함수는 아마도 다음과 같은 모양을 가지게 될 것이다.
void OutFriend(tag_Friend aFriend) { ... }
void OutFriend(tag_Friend *pFriend) { ... }
2. 멤버의 참조
■ 멤버연산자
= 배열에서는 참조할 때 []을 사용한다. ex) ar[5] =3;
= 그렇다면 구조체에서는? A) 구조체명.멤버명 ex) Friend구조체의 Age 멤버값을 읽고자 한다면 Friend.Age
struct tag_Friend { char Name[10]; int Age; double Height; };
void main() { tag_Friend Friend;
strcpy(Friend.Name,"아무개"); Friend.Age=30; Friend.Height=178.2;
printf("이름=%s, 나이=%d, 키=%.1f\n",Friend.Name,Friend.Age,Friend.Height); } |
- 구조체와 같은 사용자 정의 타입은 main 함수 전에 정의하자 (그래야 모든 함수에서 이 타입을 사용할 수 있다) - Age 멤버에 30을 대입하려면 Friend.Age=30; 이라는 대입문을 사용하며 Height 멤버의 값을 읽고 싶을 때는 Friend.Height라고 쓴다 Friend 구조체 어떻게 생긴지 그림으로 표현하면 |