구조체는 C의 데이터 타입중 가장 덩치가 크다.
정수나 실수, 또는 문자열 등의 단순한 형태로 나타낼 수 없는 복잡한 데이터를
표현할 때, 구조체가 사용된다.
구조체를 정의내리면 타입이 다른 변수들의 집합이라고 할 수 있다.
배열은 같은 타입의 변수를 여러개 가지지만, 구조체는 다른타입의 변수를 하나의 이름으로 묶은것이다.
ex)
1 2 3 4 5 6 7 | struct human { char name[10]; int age; int height; int weight; }; | cs |
Name 캐릭터형이고, Age는 정수형이고 나머지도 정수형인데, 이외에 자세한 주소
를 기억하고 싶으면 여러 정보가 더 필요할 것이다. 보다시피 각 변수들의 타입
이 서로 달라서 배열로는 묶을 수 없는데, 관련성 있는것들을 하나로 묶어서 선
언할때 구조체를 사용한다.
단 구조체 선언은 어디까지나, 구조체의 모양을 컴파일러에게 알려주는 것일 뿐, 초기
값을 줄 수는 없다.
구조체변수는 태그를 먼저 정의하고 이 태그로 구조체 변수를 선언하는 것이 일반적
이다. 형식은 다음과 같다. struct 태그명 { 멤버목록 };
키워드 struct 다음에 태그의 이름을 주고 멤버를 나열한다.
태그도 일종의 명칭이므로 규칙에만 맞다면 자유롭게 이름을 붙일 수 있다.
타입이 정의되면 이 타입으로 같은형의 변수를 선언할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | struct human { char name[10]; int age; int height; int weight; }; int main(void) { human a, b; } | cs |
또한 다음과 같은 선언도 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | struct human { char name[10]; int age; int height; int weight; }; int main(void) { human *a, b[100]; } | cs |
구조체를 인수나 리턴값으로도 사용할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | struct human { char name[10]; int age; int height; int weight; }; human(human a); int main(void) { human a, b; } | cs |
구조체의 멤버에 참조할때는 -> 또는 . 를 사용하는데, 구조체형 포인터일때 ->를 사
용한다.
포인터나 배열은 첫 번째, 몇번째, 이럴수 있으나 구조체는 각각 크기가 다르므로, 별도의 연산자와 멤버의 이름을 사용해야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <stdio.h> #include <string.h> struct human { char name[10]; int age; int height; int weight; }; int main(void) { human a; strcpy(a.name, "유한길"); a.age = 17; a.height = 180; a.weight = 54; printf("%s %d %d %d\n", a.name, a.age, a.height, a.weight); } | cs |
이런식으로 태그.멤버 를하면 접근 할 수 있다.
예전에 T라는 타입이 있을때, T형 배열과 포인터를 선언할 수 있다고 했다.
그렇다면 구조체도 배열과 포인터를 선언할 수 있다.
고로 다음과 같은 코드도 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <stdio.h> #include <string.h> struct human { char name[10]; int age; int height; int weight; }; int main(void) { human *a; human b[10]; int i = 0; a = b; strcpy((*a).name, "유한길"); (*a).age = 17; (*a).height = 180; (*a).weight = 54; printf("%s %d %d %d\n", (*a).name, (*a).age, (*a).height, (*a).weight); } | cs |
이런식으로 접근하기 어렵지 않은가?
그래서 아까말했던 다른연산자인 -> 를 사용할 수있다.
p가 구조체를 가리키는 포인터이고, m이 멤버일 때
(*p).m 은 p->m 과 같다.
구조체끼리 대입할 수도 있으며, 구조체의 멤버를 초기화 할때는 다음처럼 쓸 수도 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <stdio.h> #include <string.h> struct human { char name[10]; int age; int height; int weight; }; int main(void) { human a; a = { "유한길", 17, 180, 54 }; printf("%s %d %d %d\n", a.name, a.age, a.height, a.weight); } | cs |
구조체를 이용한 예시
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct NODE { char name[10]; int grade; int score; }node; node *find(node *arr, size_t size); int main(void) { node *arr; int i; int amount; node *max; puts("학생은 몇명인가요?"); scanf("%d%*c", &amount); if (!(arr = (node*)calloc(1, sizeof(node)*amount))) { puts("error!"); return 0; } else { for (i = 0; i < amount; i++) { puts("학생의 이름을 입력하여 주십시오."); scanf("%s", (arr + i)->name); puts("학생의 학년을 입력하여 주십시오."); scanf("%d%*c", &((arr + i)->grade)); puts("학생의 점수를 입력하여 주십시오."); scanf("%d%*c", &((arr + i)->score)); } max = find(arr, amount); printf("성적이 가장 높은 학생은 %d 학년 %s입니다!\n", max->grade, max->name); } return 0; } node *find(node *arr, size_t size) { int max=0; int i = 0; for (i = 0; i < size; i++) { if ((arr + i)->score > max) { max = (arr+i)->score; } } for (i = 0; i < size; i++) { if ((arr + i)->score == max) { return (arr + i); } } } | cs |
사용자에게 학생들수만큼 입력받아서 가장 성적이 높은 학생의 학년과 이름을 출력한다.
'C' 카테고리의 다른 글
어셈블리, 메모리 구조, 함수 생성 및 파기 과정 (2) | 2016.06.14 |
---|---|
링크드리스트, 스택, 큐 (0) | 2016.04.21 |
문자치환 (0) | 2016.04.10 |
swap! (0) | 2016.04.10 |
배열에 데이터들을 입력하여 특정값을 특정값으로 치환하기. (0) | 2016.04.07 |