구조체
sims게임을 만들 때, 캐릭터에 대한 정보가 너무 많이 들어간다
따라서 원소의 크기가 제각각인 배열을 만들 수 있으면 ?
한사람에 대한 정보를 한개의 배열에 저장 할 수 있으면?
즉, 첫번째 원소는 int로 나이를, 두번째원소는 char[]로 이름을! 하지만 c언어에서 배열은 원소의 타입이 모두 동일해야 한다.
다행히도 c언어에서는 배열로 해결하지 못하는 문제를 구조체를 이용하여 해결할 수 있다.
#include <stdio.h>
struct Human {
int age;
int height;
int weight;
};
int main(){
struct Human Psi;
Psi.age=99;
Psi.height=185;
Psi.weight=80;
printf("Psi information\n");
printf("age : %d\n",Psi.age);
printf("height : %d\n",Psi.height);
printf("weight : %d\n",Psi.weight);
return 0;
}
구조체는 각 원소의 타입이 제각각인 배열이기 때문에 모든 원소의 타입을 명시해 주어야 한다.
Human이라는 이름의 구조체는 3개의 멤버를 가지고 있다
각각의 멤버는
int age
int height
int weight
구조체 포맷
struct 구조체명 {
멤버타입 멤버명;
};
꼭 마지막 중괄호가 끝나면 ; 를 붙인다!!
메인함수에 선언할 때는
struct 구조체이름 구조체변수명;
으로 구조체변수를 선언해준다. (구조체변수의 타입은 struct 구조체이름, 즉 Human 구조체 가된다)
배열에서는 []를 이용하여 원소에 접근했는데, 구조체에서는 .를 이용하여 멤버에 접근한다.
구조체변수명.멤버명
단, 배열과의 차이는 구조체 내부에서는 변수를 초기화 할 수 없다(당연하겠지,, 클래스 느낌!..?)
#include <stdio.h>
struct Books {
char name[30];
char auth[30];
char publ[30];
int borrowed;
};
int main(){
struct Books book_list[3];
int i;
for (i=0;i<3;i++){
printf("책 정보 입력 : \n");
scanf("%s %s %s", book_list[i].name, book_list[i].auth, book_list[i].publ);
book_list[i].borrowed =0;
}
for (i=0;i<3;i++){
printf("-----------------\n");
printf("책 %s의 정보\n",book_list[i].name);
printf("저자 : %s \n",book_list[i].auth);
printf("출판사 : %s \n",book_list[i].publ); if (book_list[i].borrowed ==0){
printf("안 빌려짐\n");
}
else {
printf("빌려짐\n");
}
}
return 0;
}
구조체포인터
구조체는 배열, 문자열 처럼 구조체 변수명에 메모리 시작주소값이 들어가있지 않다. 그냥 구조체의 변수명 일 뿐이다!
그래서 변수를 가리키듯 사용하면 된다.
int a;
int *b;
b=&a
처럼 사용!!
#include <stdio.h>
struct test{
int a,b;
};
int main(){
struct test st;
struct test *ptr;
ptr = &st;
(*ptr).a = 1;
(*ptr).b = 2;
printf("%d, %d",st.a,st.b);
return 0;
}
구조체포인터를 이용해 구조체에있는 변수에 접근하려면
*b==a이기 때문에
(*b).멤버명
과 같이 접근하면 된다.
단, 반드시 괄호로 감싸줘야 하는데 그 이유는
연산 우선순위가 다음과 같기 때문이다
. //구조체의 변수에 접근하는 연산자
* //포인터 연산자
이때
*b.멤버명
와 같이 접근한다면 우선순위에 따라 *(b.멤버명)과 같이 연산이 이루어지는데
b는 구조체도 아닌, 포인터일 뿐이기 때문에 그 어디에도 접근하는 것이 아니기 때문이다.
이 귀찮은 작업을 쉽게 할 수있도록 한 c언어! 다음을 보자.
include <stdio.h>
struct test{
int a,b;
};
int main(){
struct test st;
struct test *ptr;
ptr = &st;
ptr->a = 1;
ptr->b = 2;
printf("%d, %d",st.a,st.b);
return 0;
}
(*ptr).a를 ptr->a 로 쓸 수 있다. (사용자 편의를 위해 도입한 기호!!)
구조체 내부에 있는 구조체의 멤버에 값을 입력할 때
int main(){
struct simple c1 = {10, 10, 1.5}; // 순서대로 채워짐
struct simple c2 = {{30,30},2.4}; // 순서대로 채워짐
struct simple c3 = {1,1}; // 내부구조체에만 차례로 채워짐
struct simple c4 ={{1},1};// 내부구조체의 첫번째 멤버에 1, 구조체의 멤버에 1이 채워짐
return 0;
}
굳이 구조체 안에 구조체를 넣기보다는 포인터를 사용하면 메모리상 좋다.
- 구조체를 포함하는 구조체는 자기 자신은 포함할 수 없다. -> 에러발생
- 자기 자신을 가리키는 포인터는 사용할 수 있다.
'프로그래밍 > C언어' 카테고리의 다른 글
11. c언어 함수 (0) | 2023.03.20 |
---|---|
10. c언어 문자열, 문자열입력, 문자열배열, 리터럴 (0) | 2023.03.20 |
9. c언어 배열과 포인터 헷갈리는 부분.. (0) | 2023.03.16 |
8-3. 배열을 가리키는 포인터(배열포인터) (0) | 2023.02.16 |
8-2. c언어 포인터의 덧셈과 뺄셈 (0) | 2023.02.16 |
댓글