2022. 3. 14. 17:44ㆍC
구조체를 멤버로 가지는 구조체 예제이다.
#include <stdio.h>
struct date
{
int year;
int month;
int day;
};
struct student
{
int number;
char name[10];
struct date dob;
double grade;
};
int main(void) {
struct student s1;
s1.dob.year = 1983;
s1.dob.month = 5;
s1.dob.day = 29;
printf("%d %d %d", s1.dob.year, s1.dob.month, s1.dob.day);
}
출력 결과
1983 5 29
위의 예제를 통해 구조체의 멤버로 다른 구조체가 사용이 가능하다는 사실을 확인할 수 있다.
*구조체의 배열
#include <stdio.h>
#define SIZE 3
struct student
{
int number;
char name[10];
double grade;
};
struct student list[SIZE];
int main(void) {
int i;
for ( i = 0; i < SIZE; i++)
{
printf("학번을 입력하세요 : ");
scanf("%d", &list[i].number);
printf("이름을 입력하세요 : ");
scanf("%s", &list[i].name);
printf("학점을 입력하세요 : ");
scanf("%lf", &list[i].grade);
}
for (i = 0; i < SIZE; i++) {
printf("이름: %s, 학점: %.1lf\n", list[i].name, list[i].grade);
}
}
출력 결과
학번을 입력하세요 : 1111
이름을 입력하세요 : aa
학점을 입력하세요 : 4.5
학번을 입력하세요 : 2222
이름을 입력하세요 : bb
학점을 입력하세요 : 3.3
학번을 입력하세요 : 3333
이름을 입력하세요 : cc
학점을 입력하세요 : 2.2
이름: aa, 학점: 4.5
이름: bb, 학점: 3.3
이름: cc, 학점: 2.2
*구조체를 가리키는 포인터
#include <stdio.h>
struct student
{
int number;
char name[10];
double grade;
};
int main(void) {
struct student s = { 24, "KIM", 4.3 };
struct student* p;
p = &s;
printf("학번=%d, 이름=%s. 학점=%lf", (*p).number, (*p).name, (*p).grade);
}
출력 결과
학번=24, 이름=KIM. 학점=4.300000
(*p).number를 보면 *p.number로 쓰지 않고 (*p)로 표기한 이유에 대해 알아보자
연산자의 우선 순위가 *연산자에 비해 더 높기 때문에 p.number가 먼저 계산되고 다음에 *(p.number)가 계산된다. 하지만 우리가 원하는 것은 *p를 먼저 계산하는 것이므로 반드시 괄호를 이용해야 한다.
다른 표기방법으로는
printf("학번=%d, 이름=%s. 학점=%lf", p->number, p->name, p->grade);
(*p).멤버가 아닌 p->멤버를 통해 좀 더 쉽게 표기할 수 있다.
헷갈릴 수 있는 구조체 변수와 구조체 포인터의 조합을 정리해보자
1.(*p).number : 포인터 p가 가리키는 구조체의 멤버 number을 의미
2.p->number : 1번과 동일
3.*p.number : 연산자 우선순위에 의하여*(p.number)와 같다. 구조체 p의 멤버 number가 가리키는 것이란 의미.
단 이때 number은 반드시 포인터여야 하고 아닐시 오류이다.
4.*p->number :연산자 우선순위에 의하여*(p->number)와 같다. p가 가리키는 구조체의 멤버 p가 가리키는 내용을 의미한다. 만약 number가 포인터가 아니면 오류이다.
정리하고 다시보니 더 헷갈리는거 같다
예제를 통해 다시 한번 정리해보자
#include <stdio.h>
struct student
{
int number;
char name[10];
double grade;
};
int main(void) {
struct student s = { 24, "KIM", 4.3 };
struct student* p;
//구조체 변수s를 선언하고 초기화 하였다. student 구조체를 가리킬 수 있는 포인터p를 선언
p = &s;
//구조체 변수 s의 주소값을 p에 대입하여 p가 s를 가리키도록 하였다
printf("학번=%d, 이름=%s, 학점=%lf\n", s.number, s.name, s.grade);
printf("학번=%d, 이름=%s, 학점=%lf\n", (*p).number, (*p).name, (*p).grade);
//구조체 포인터p를 이용해 구조체 변수 s의 멤버를 참조한다. (*p)=s 이기에 s.멤버와 동일하다고 볼 수 있다.
printf("학번=%d, 이름=%s, 학점=%lf\n", p->number, p->name, p->grade);
//위와 같은 내용이지만 다른 방법이다. 연산자는 간접 멤버 연산자로서 구조체 포인터에서 바로 구조체의 멤버로 접근 가능하다.
}
출력 결과
학번=24, 이름=KIM, 학점=4.300000
학번=24, 이름=KIM, 학점=4.300000
학번=24, 이름=KIM, 학점=4.300000
구조체와 구조체 포인터 반환하기
하 진짜 개어렵다 너무 어려워서 미칠거 같ㅇ
#define _CRT_SECURE_NO_WARINGS
#include <stdio.h>
#include <string.h>
struct Person {
char name[20];
int age;
char address[100];
};
struct Person getPerson() {
struct Person p;
strcpy(p.name, "홍길동");
p.age = 30;
strcpy(p.address, "서울시 용산구 한남동");
return p;
}
int main() {
struct Person p1;
p1 = getPerson();
printf("이름 : %s \n", p1.name);
printf("나이 : %d \n", p1.age);
printf("주소 : %s \n", p1.address);
return 0;
}
출력 결과
이름 : 홍길동
나이 : 30
주소 : 서울시 용산구 한남동
위 구문을 포인터를 활용한 동적 할당 구문으로 바꿔보자
#define _CRT_SECURE_NO_WARINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Person {
char name[20];
int age;
char address[100];
};
struct Person* allocPerson() {
struct Person *p = malloc(sizeof(struct Person));
strcpy(p->name, "홍길동");
p->age = 30;
strcpy(p->address, "서울시 용산구 한남동");
return p;
}
int main() {
struct Person *p1;
p1 = allocPerson();
printf("이름 : %s \n", p1->name);
printf("나이 : %d \n", p1->age);
printf("주소 : %s \n", p1->address);
free(p1);
}
하 진짜 제발 하나님 진짜 너무 어려워요 모르겠다구요 진짜
출력 결과는 똑같이 나온다.
위 구문을 자세히 분석해보자.
#define _CRT_SECURE_NO_WARINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Person {
char name[20];
int age;
char address[100];
};
struct Person* allocPerson() { //allocPerson과 같은 반환값 자료형을 구조체 포인터로 지정해준다 밑의 함수 안에서
//구조체 포인터의 메모리를 할당하고 값을 저장한 뒤 구조체 포인터를 반환한다.
struct Person *p = malloc(sizeof(struct Person)); //malloc함수로 struct Person크기의 메모리를 할당 받는 구문
strcpy(p->name, "홍길동"); //포인터 p가 가리키는 구조체의 멤버 name에 홍길동이란 값을 넣는다
p->age = 30; //포인터 p가 가리키는 구조체의 멤버 age에 30이란 값을 넣는다
strcpy(p->address, "서울시 용산구 한남동");//포인터 p가 가리키는 구조체의 멤버 address에 서울시 용산구 한남동이란 값을 넣는다
return p; //구조체 p에 저장된 값을 반환한다
}
int main() {
struct Person *p1;
p1 = allocPerson(); //이 함수를 통해 반환값을 저장한다. (allocPerson함수를 호출한 뒤에 반환된 포인터를 p1에 저장한다)
//위 구문을 통해 화살표 연산자로 멤버에 접근이 가능해진다.
printf("이름 : %s \n", p1->name);
printf("나이 : %d \n", p1->age);
printf("주소 : %s \n", p1->address);
free(p1); //할당 받은 메모리를 해제하는 구문
}
'C' 카테고리의 다른 글
C - 자료구조 기초 (0) | 2022.03.21 |
---|---|
C - 구조체 크기 알아보기 (0) | 2022.03.15 |
C - 동적 메모리 할당 (0) | 2022.03.11 |
C - 함수 포인터 (0) | 2022.03.11 |
C - 문자 입출력 라이브러리 (0) | 2022.03.10 |