사이먼's 코딩노트
[C언어] 구조체(Struct) 본문
[구조체]
- 구조체(structure type)란 사용자가 C언어의 기본 타입을 가지고 새롭게 정의할 수 있는 사용자 정의 타입이다.
- 구조체는 기본 타입(char, int, double, float 등)으로 나타낼 수 없는 복잡한 데이터를 표현할 수 있다.
- 배열이 같은 타입의 변수 집합이라고 한다면, 구조체는 다양한 타입의 변수 집합을 하나의 타입으로 나타낸 것이다.
- 간단하게 말해 구조체는 하나의 설계도를 의미한다고 생각하면 된다.
- 아래는 구조체를 사용하기 전 통상적으로 우리가 사용하는 코드이다.
#include "stdio.h"
void introduce(int age, char* name, char* hometown, char* favorite_food, char* hobby);
void talk(int age, char* name, char* hometown, char* favorite_food, char* hobby);
int main() {
int person1_age = 20;
char* person1_name = "홍길동";
char* person1_hometown = "한양";
char* person1_favorite_food = "떡볶이";
char* person1_hobby = "음악감상";
int person2_age = 50;
char* person2_name = "임꺽정";
char* person2_hometown = "평양";
char* person2_favorite_food = "떡국";
char* person2_hobby = "영화감상";
introduce(person1_age, person1_name, person1_hometown, person1_favorite_food, person1_hobby);
talk(person1_age, person1_name, person1_hometown, person1_favorite_food, person1_hobby);
introduce(person2_age, person2_name, person2_hometown, person2_favorite_food, person2_hobby);
talk(person2_age, person2_name, person2_hometown, person2_favorite_food, person2_hobby);
return 0;
}
void introduce(int age, char* name, char* hometown, char* favorite_food, char* hobby) {
printf("== 소개 시작 ==\n");
printf("이름 : %s\n", name);
printf("나이 : %d살\n", age);
printf("고향 : %s\n", hometown);
printf("취미 : %s\n", hobby);
printf("== 소개 끝 ==\n");
}
void talk(int age, char* name, char* hometown, char* favorite_food, char* hobby) {
printf("이야기 시작 : 안녕하세요. 저는 %d살, %s 입니다. 제 고향인 %s 에서는...\n", age, name, hometown);
}
- 위 코드는 person1과 person2의 나이, 이름, 고향, 좋아하는 음식, 취미를 변수로 생성하고 introduce와 talk 함수를 통해 자기소개를 하는 코드이다.
- main 함수 위에 introduce()와 talk() 함수가 선언되었고 해당 함수의 로직은 main 함수 아래에 정의되어있다.
- 만약 main 함수 아래에 사용자 지정의 함수를 정의하고 싶다면 위 코드 처럼 main 함수 위에서도 선언을 해줘야한다.
- 그렇지 않고 main 함수 위에 사용자 지정의 함수를 정의하고 싶다면 위 코드처럼 따로 선언을 할 필요는 없다.
- 우리는 위 코드를 Person 이라는 구조체를 만들어 새로운 타입을 만들어보려고 한다.
- 아래는 같은 기능을 하는 코드지만, 구조체가 포함된 코드이다.
#include <stdio.h>
struct Person {
int age;
char* name;
char* hometown;
char* favorite_food;
char* hobby;
};
void introduce(struct Person p) {
printf("== 소개 시작 ==\n");
printf("이름 : %s\n", p.name);
printf("나이 : %d살\n", p.age);
printf("고향 : %s\n", p.hometown);
printf("취미 : %s\n", p.hobby);
printf("== 소개 끝 ==\n");
}
void talk(struct Person p) {
printf("이야기 시작 : 안녕하세요. 저는 %d살, %s 입니다. 제 고향인 %s 에서는...\n", p.age, p.name, p.hometown);
}
int main(void) {
struct Person p1;
p1.age = 20;
p1.name = "홍길동";
p1.hometown = "한양";
p1.favorite_food = "떡볶이";
p1.hobby = "음악감상";
struct Person p2;
p2.age = 50;
p2.name = "임꺽정";
p2.hometown = "평양";
p2.favorite_food = "떡국";
p2.hobby = "영화감상";
introduce(p1);
talk(p1);
introduce(p2);
talk(p2);
return 0;
}
- 구조체의 기본 구조는 "struct 구조체이름 { };" 과 같다.
- 대괄호{ } 밖에 반드시 세미콜론(;)을 붙혀줘야한다.
- 위 코드는 struct Person 이라는 구조체를 정의하고 Person 이라는 구조체는 나이, 이름, 고향, 좋아하는 음식, 취미를 가진다는 것을 표현한다.
- main 함수에서는 위에서 만든 Person의 구조체를 선언해야 한다. (struct Person p1)
- Person 설계도를 가진 p1과 p2 변수를 생성해주고 p1과 p2의 각각 정보들을 입력한다.
- p1.age, p1.name, p1.hometown, p1.favorite_food, p1.hobby 와 같이 . 을 통해 해당 구조체에서 선언한 멤버 변수를 불러온다.
- 구조체를 사용하기 전에는 introduce()와 talk() 함수의 인자와 매개변수로 각 변수들을 입력했지만 구조체를 선언했을 때는 구조체 변수만 넘겨주면 된다.
- 구조체의 기본 구조를 알았으니, 이번에는 구조체 변수의 주소를 이용해서 원본값을 변경하는 함수를 구현해보자.
#include <stdio.h>
struct School {
char* name;
int birth_date;
};
// 이 함수를 변경해야 합니다.
void change(struct School* s) {
(*s).name = "미국초등학교";
s->birth_date = 20180717;
}
int main(void) {
struct School s1;
s1.name = "한국초등학교";
s1.birth_date = 19860404;
printf("학교의 이름 : %s\n", s1.name);
// 출력 => 학교의 이름 : 한국초등학교
printf("학교의 설립일 : %d\n", s1.birth_date);
// 출력 => 학교의 설립일 : 19860404
change(&s1);
printf("학교의 이름 : %s\n", s1.name);
// 출력 => 학교의 이름 : 미국초등학교
printf("학교의 설립일 : %d\n", s1.birth_date);
// 출력 => 학교의 설립일 : 20180717
return 0;
}
- 위 코드는 구조체 변수 s1의 name과 birth_date를 change()라는 함수를 통해 값을 변경하는 코드이다.
- 먼저, 코드 상단에 struct School 이라는 구조체를 선언하였고, School이라는 구조체는 멤버변수로 학교 이름과 개교기념일을 가지고있다.
- change() 라는 함수는 인자로 그냥 s1을 넘기게 되면 값을 넘기게 되어 구조체 변수아닌 참조값이 change() 로 넘어가게된다.
- 위와 같은 상황에서는 구조체 변수의 주소를 이용하여 원하는 값을 변경해야한다.
- change(&s1) 과 같이 구조체 변수의 주소를 인자로 보내고 change() 함수에서는 s1의 주소값을 매개변수로 받아야한다.
- void change(struct School* s) 와 같이 타입은 struct School 이고 포인터 변수 s를 적어준다.
- 포인터 변수인 s의 값을 변경하기 위해서는 s의 주소로 이동해야되기 때문에 우리가 배웠던 *을 이용해서 이동할 수 있다.
- *s.name이 아닌 (*s).name와 같이 ( )을 써준 이유는 연산자 순서에 따라서 s.name이 먼저 동작하기 때문에 s의 주소로 이동한 후 name을 찾아가야되기 때문이다.
- *을 사용하지 않고 구조체 변수의 주소로 이동하는 방법이 있다.
- s->birth_date 와 같이 '->' 을 사용하면 같은 기능을 한다.
반응형
'C언어' 카테고리의 다른 글
[C언어] 구조체&동적 할당 문제풀이 (0) | 2024.02.28 |
---|---|
[C언어] 정적 및 동적 할당 (0) | 2024.02.21 |
[C언어] 포인터&배열 문제풀이(2) (0) | 2024.02.19 |
[C언어] 포인터&배열 문제풀이(1) (0) | 2024.02.19 |
[C언어] 공공재 / strcpy (0) | 2024.02.19 |