앞선 포스팅에서 구조체(structures)에 대해서 알아보았습니다.
2021.03.17 - [쿤즈 Dev/C] - [C언어] 구조체(structures)란 무엇인가
구조체를 알고 나서부터는 공통된 정보를 모아서 하나의 타입으로 만들고 이 구조체 타입을 이용해서 변수를 만들어서 사용할 수 있습니다. 그래서 구조체는 실무에서는 무조건 사용해야 하는 C언어의 문법입니다.
이번 포스팅에서는 구조체의 두 번째 시간으로 지난 포스팅의 마지막에 잠깐 봤던 포인터와 연결하는 방법을 더 자세히 알아보도록 하겠습니다.
C언어 구조체 포인터 선언과 사용방법
구조체 타입은 동일한 타입으로 정의합니다.
struct Student {
char name[20];
int age;
float height;
}
int main()
{
struct Student *pstu1, stu1;
pstu1 = &stu1;
return 0;
}
구조체는 struct Student 타입으로 정의했습니다. 이를 main()함수에서 불러와 사용할 때, 위와같이 두 가지 방법을 모두 선언하였습니다. 하나는 포인터 변수, 다른 하나는 일반 변수입니다.
여기서 중요한 부분은 포인터 변수 *pstu1은 주소를 담을 공간만 할당하기 때문에 구조체 Student 타입의 멤버변수를 담을 공간은 없습니다. 따라서 이와같이 선언시에는 반드시 일반 stu1을 선언해서 메모리공간을 할당 후에 이 주소를 포인터 변수에 넘겨주어야 합니다.
그럼 다시 포인터 변수를 이용해서 멤버 변수에 접근해 보도록 하겠습니다.
#include <stdio.h>
struct Student {
char name[20];
int age;
float height;
};
void displayStudent(struct Student*);
int main() {
struct Student *pstu1, stu1;
pstu1 = &stu1;
printf("이름을 입력하세요 : ");
scanf("%s", pstu1->name);
printf("나이를 입력하세요 : ");
scanf("%d", &pstu1->age);
printf("키를 입력하세요 : ");
scanf("%f", &pstu1->height);
displayStudent(pstu1);
return 0;
}
void displayStudent(struct Student* st) {
printf("\n이름: %s\n", st->name);
printf("나이: %d\n", st->age);
printf("키: %.2f\n", st->height);
}
구조체 변수에 접근할때에는 점(.) 연산자를 이용해서 접근했다면 구조체 포인터 변수에 접근해서 멤버변수에 접근할 때에는 화살표(->) 연산자를 이용합니다. 접그하는 방법만 다를뿐 사용법은 동일합니다.
여기서 주의할 부분은 위에서 말씀드렸듯이 pstu1 = &stu1; 이라는 부분입니다.
구조체 포인터의 동적 메모리 할당
동적 메모리 할당은 원하는 만큼 메모리를 할당받고 사용 후에는 반환하는 C언어의 메모리 사용 방법입니다. 메모리 할당에 대해서는 아래 포스팅에서 확인해주세요.
2020.12.17 - [쿤즈 Dev/C] - [C언어] 포인터를 이용한 메모리 동적 할당(Memory Allocation)
메모리를 할당받기 위해서는 어떤 타입의 얼마의 크기를 할당받을지가 중요합니다. 이 사이즈를 구조체 크기로 바꿔주기만 하면 됩니다. 그럼 소스코드로 다시 한 번 알아보겠습니다.
소스코드1 struct_malloc.c
#include <stdio.h>
#include <stdlib.h>
struct Student {
char name[20];
int age;
float height;
};
void displayStudent(struct Student*, int);
int main() {
struct Student *pstu;
int i, num;
printf("학생 수 : ");
scanf("%d", &num);
pstu = (struct Student*) malloc(num * sizeof(struct Student));
for (i=0; i<num; i++) {
printf("학생정보 입력(이름 나이 키) : ");
scanf("%s %d %f", (pstu+i)->name, &(pstu+i)->age, &(pstu+i)->height);
}
displayStudent(pstu, num);
return 0;
}
void displayStudent(struct Student* st, int n) {
int i;
for(i=0; i<n; i++) {
printf("\n이름: %s\n", (st+i)->name);
printf("나이: %d\n", (st+i)->age);
printf("키: %.2f\n", (st+i)->height);
}
}
결과1
학생 수 : 2
학생정보 입력(이름 나이 키) : Ironman 36 176.3
학생정보 입력(이름 나이 키) : Hulk 50 233.2
이름: Ironman
나이: 36
키: 176.30
이름: Hulk
나이: 50
키: 233.20
앞선 소스코드에서는 main에서 정적으로 메모리를 잡은 stu1을 포인터 변수에 연결시켰습니다. 이번 소스코드에서는 동적으로 메모리를 할당받기 위해서 다음과 같은 소스코드를 작성했습니다.
pstu = (struct Student*) malloc(num * sizeof(struct Student));
구조체 포인터 변수 pstu는 학생수를 담은 num와 구조체 크기인 sizeof(sturct Student)를 곱한 크기만큼 메모리를 할당받습니다. 그리고 이 값은 구조체 변수 타입(struct Student*)으로 리턴해서 pstu에 넣습니다.
만약 정의한 구조체 크기가 10byte고 학생수가 2명이라면 20byte크기를 pstu에 동적으로 할당해준 것입니다.
다음은 접근 방법입니다. 현재 포인터에서 다음 포인터의 접근은 더하기 연산자를 이용해서 접근하면 됩니다.
- 첫 번째 주소 : pstu + 0
- 두 번째 주소 : pstu + 1
- 세 번째 주소 : pstu + 2
이와 같은 규칙으로 반복문 for를 사용해서 데이터를 입력받고 또 출력할 수 있습니다.
오늘은 C언어의 필수 사용 요소인 구조체와 포인터에 대해서 사용 방법을 알아보았습니다. 사실 방대한 프로그래밍은 모두 구조체와 포인터로 연결되어 있으며 동적으로 메모리를 할당받아서 사용하는것이 특징입니다. 그래서 메모리 사용에 대한 메모리릭을 프로그래머가 직접 컨트롤하고 제어할 수 있는 것이 C언어의 가장 큰 특징입니다. 도움이 되셨으면 합니다. 이상입니다.
'쿤즈 Dev > C' 카테고리의 다른 글
[C언어 문제] 화면에 Hello World 출력하기 (0) | 2021.04.09 |
---|---|
[C언어] 파일 (File) 다루는 함수 사용 방법 (0) | 2021.03.24 |
[C언어] 구조체(structures)란 무엇인가 (0) | 2021.03.17 |
[C언어] 문자열과 배열 사이의 관계 (0) | 2020.12.21 |
[C언어] 포인터를 이용한 메모리 동적 할당(Memory Allocation) (2) | 2020.12.17 |
댓글