1. 구조체란?
구조체는 여러 개의 변수를 하나의 이름으로 묶어서 사용할 수 있게 해주는 데이터 구조이다.
서로 다른 타입의 변수들을 묶어서 하나의 높은 수준의 데이터 타입으로 다룰 수 있으며, 이는 데이터를 구조화하는 데 있어서 매우 유용하다.
2. 구조체 선언
- 구조체는 메모리상에 구조체 멤버들의 자료형의 byte합과 같다.
- 구조체 이름은 구조체와 구조체를 구별하기 위해서 붙여지는 이름이다.
- 구조체 멤버는 아직 변수가 선언된 것이 아니다.
// 기본 구조
struct 구조체명 {
자료형 멤버명;
자료형 멤버명;
...
};
// 예시
struct Student {
char name[50];
int age;
float grade;
};
3. 구조체 변수 선언 및 초기화
- 구조체를 정의한 후, 해당 구조체 타입의 변수를 선언할 수 있다.
- 구조체 변수의 크기는 구조체 멤버들의 크기를 합치면 된다.
- 구조체 멤버들의 초기값은 중괄호 안에 나열하면 된다.
// student1 이라는 이름의 구조체 변수 선언 후 초기화
struct Student student1 = {"woo", 20, 4.2};
4. 구조체 멤버 접근
구조체 멤버에 접근하기 위해서는 . 연산자를 사용한다.
#include <stdio.h>
struct Student {
char name[50];
int age;
float grade;
};
int main()
{
struct Student student1 = {"woo", 20, 4.2};
// 구조체 멤버 접근
printf("%s\\n", student1.name);
printf("%d\\n", student1.age);
printf("%f\\n", student1.grade);
return 0;
}
5. 구조체 변수의 대입과 비교
5.1 구조체 변수 대입
구조체 대입은 한 구조체 변수의 모든 멤버 값을 다른 구조체 변수에 복사한다.
= 연산자를 사용한다. (단, 같은 타입의 구조체 변수만 가능하다.)
struct Person {
char name[100];
int age;
};
int main() {
struct Person person1 = {"Alice", 30};
struct Person person2;
// person1의 데이터를 person2에 대입
person2 = person1;
return 0;
}
5.2 구조체 변수의 비교
구조체 각 멤버를 개별적으로 비교해야 한다.
#include <string.h>
struct Person {
char name[100];
int age;
};
int main() {
struct Person person1 = {"Alice", 30};
struct Person person2 = {"Alice", 30};
// 구조체 비교
if (strcmp(person1.name, person2.name) == 0 && person1.age == person2.age) {
printf("두 사람은 동일한 정보를 가지고 있습니다.\\n");
} else {
printf("두 사람은 서로 다른 정보를 가지고 있습니다.\\n");
}
return 0;
}
6. 구조체 배열
구조체 배열은 여러 구조체 변수를 연속적으로 저장할 수 있는 방법이다.
6.1 기본 구조
struct 구조체_이름 배열_이름[배열_크기];
struct Student {
char name[50];
int age;
float score;
};
// Student 구조체 타입의 배열 선언
struct Student students[10];
// 배열과 비슷한 방식으로 접근
strcpy(students[0].name, "홍길동");
students[0].age = 20;
students[0].score = 85.5;
7. 중첩 구조체
한 구조체 안에 다른 구조체를 포함시키는 것을 의미한다.
중첩된 구조체의 멤버에 접근할 때는 . 연산자 또는 → 연산자를 활용한다.
#include <stdio.h>
struct Date {
int year;
int month;
int day;
};
struct Student {
char name[50];
struct Date birthdate; // 중첩 구조체
float score;
};
int main() {
struct Student student1;
// 직접 접근
strcpy(student1.name, "John Doe");
student1.birthdate.year = 1995;
student1.birthdate.month = 5;
student1.birthdate.day = 23;
student1.score = 92.5;
// 포인터를 통한 접근
struct Student *ptr = &student1;
strcpy(ptr->name, "John Doe");
ptr->birthdate.year = 1995;
ptr->birthdate.month = 5;
ptr->birthdate.day = 23;
ptr->score = 92.5;
return 0;
}
8. 구조체 포인터
구조체 변수의 주소를 저장할 수 있는 포인터를 선언할 수 있다.
8.1 구조체 포인터 선언
// 기본 구조
struct 구조체명 *포인터변수명;
// 예시
struct Person {
char name[100];
int age;
};
int main() {
struct Person person1;
struct Person* ptr; // 구조체 포인터 선언
ptr = &person1; // person1의 주소를 ptr에 할당
strcpy(ptr->name, "홍길동");
ptr->age = 20;
ptr->score = 85.5;
}
8.2 구조체 포인터 접근
구조체 포인터를 통해 구조체 멤버에 접근할 때는 → 연산자를 사용한다.
strcpy(ptr->name, "홍길동");
ptr->age = 20;
ptr->score = 85.5;
9. 함수와 구조체 포인터
함수에 구조체를 전달하는 방법은 값 또는 포인터를 전달하는 것이다.
9.1 값으로 전달하기
구조체를 값으로 전달하면 함수가 호출될 때 구조체의 내용이 전체적으로 복사됩니다. 이렇게 하면 원본 데이터는 변경되지 않으므로 안전하다.
void printStudent(struct Student s) {
printf("이름: %s, 나이: %d\\n", s.name, s.age);
}
int main() {
struct Student student1 = {"홍길동", 20};
printStudent(student1);
return 0;
}
9.2 포인터로 전달하기
구조체를 포인터로 전달하면 원본 구조체에 대한 메모리 주소만 전달되므로, 함수 내에서 원본 데이터를 직접 변경할 수 있다.
void modifyStudent(struct Student *s) {
s->age = 21; // 포인터를 사용하여 나이 변경
}
int main() {
struct Student student1 = {"홍길동", 20};
modifyStudent(&student1);
printf("변경된 나이: %d\\n", student1.age);
return 0;
}
9.3 구조체 반환하기
함수에서 반환되는 구조체는 호출한 쪽에서 새로운 복사본으로 사용
struct Student createStudent() {
struct Student newStudent = {"이순신", 23};
return newStudent;
}
int main() {
struct Student student2 = createStudent();
printf("이름: %s, 나이: %d\\n", student2.name, student2.age);
return 0;
}
'Language > C' 카테고리의 다른 글
[ C ] 공용체 , 열거형 (0) | 2024.05.08 |
---|---|
[ C ] 동적 메모리 할당 (0) | 2024.04.30 |
[ C ] 포인터 (0) | 2024.04.30 |
[ C ] 문자열 (0) | 2024.04.29 |
[ C ] 배열 (0) | 2024.04.29 |