C언어의 구조체(struct)는 서로 다른 자료형을 하나로 묶어 새로운 형태의 복합 데이터 타입을 정의할 수 있게 해준다. 이는 데이터를 효율적으로 관리하고, 코드의 가독성과 유지 보수성을 향상시킬 수 있는 강력한 도구이다. 이번 포스팅에서는 구조체를 통해 더 깔끔하고 효율적인 코드를 작성하는 몇 가지 팁과 예제를 제공한다.전통적인 프로그래밍 언어에서는 변수를 사용하여 데이터를 저장했다. 그러나 변수만으로는 서로 관련된 여러 데이터 항목을 효율적으로 관리하기 어려웠다. 예를 들어, 학생의 정보(이름, 나이, 성적 등)를 처리하려면 각 항목을 별도의 변수로 관리해야 했고, 이러한 변수들 사이의 논리적 연관성을 코드상에서 명확히 표현하기 어려웠다.
구조체는 이러한 문제를 해결하기 위해 도입되었다. 구조체를 사용하면 서로 관련된 여러 데이터 항목을 하나의 논리적 단위로 그룹화할 수 있다. 이를 통해 데이터의 구조를 명확히 할 수 있고, 코드의 가독성과 유지 보수성이 향상된다.
⭐1. 구조체의 장점
1.1. 집계 데이터의 연속 메모리 할당: 구조체를 사용하면 서로 관련된 데이터를 메모리 상에서 연속적으로 할당할 수 있다. 이는 데이터 접근 시간을 단축시킬 수 있으며, 캐시 효율성을 높일 수 있다.
1.2. 메모리 오버헤드 감소: 복잡한 데이터 구조를 다룰 때, 개별적인 변수로 관리하는 것보다 구조체를 사용하는 편이 메모리 오버헤드를 줄일 수 있다. 예를 들어, 배열과 같이 동일한 타입의 데이터를 여러 개 저장하는 경우보다, 구조체를 사용하여 관련된 다양한 타입의 데이터를 하나의 단위로 관리하는 것이 더 효율적이다.
1.3. 포인터를 통한 효율적인 데이터 접근: 구조체 변수의 주소를 포인터에 저장하고, 이 포인터를 사용하여 구조체의 데이터에 접근할 수 있다. 이 방법은 특히 대량의 데이터를 처리하거나 구조체를 함수의 매개변수로 전달할 때 유용하다. 데이터의 복사본을 생성하는 대신, 데이터의 주소만 전달함으로써 메모리 사용량을 줄이고 성능을 향상시킬 수 있다.
⭐2. 구조체의 기본 사용법
먼저, 구조체의 선언과 초기화에 대해 간단히 살펴본다.
#include <stdio.h>
// 'person' 구조체 정의
typedef struct {
char name[50];
int age;
float salary;
} Person;
int main() {
// 구조체 변수 초기화
Person person1 = {"John Doe", 30, 50000.0};
printf("Name: %s\nAge: %d\nSalary: %.2f\n", person1.name, person1.age, person1.salary);
return 0;
}
⭐3. 구조체 활용 팁
- 타입 정의 사용하기: typedef를 사용하여 구조체에 별명을 지정함으로써 코드의 가독성을 높일 수 있다. 이는 예제에서 보듯이, 매번 struct 키워드를 사용하지 않아도 되게 해준다.
- 함수와 구조체 결합하기: 구조체를 함수의 매개변수로 전달하거나, 함수에서 구조체를 반환할 수 있다. 이를 통해 코드를 모듈화하고, 데이터 관리를 더욱 효율적으로 할 수 있다.
#include <stdio.h>
typedef struct {
char title[50];
char author[50];
int pages;
} Book;
// 함수를 통해 구조체 반환
Book createBook(char *title, char *author, int pages) {
Book newBook;
strcpy(newBook.title, title);
strcpy(newBook.author, author);
newBook.pages = pages;
return newBook;
}
void printBook(Book book) {
printf("Book: %s by %s, %d pages\n", book.title, book.author, book.pages);
}
int main() {
Book book1 = createBook("C Programming", "Dennis Ritchie", 279);
printBook(book1);
return 0;
}
3.1. 구조체 배열 사용하기: 유사한 데이터를 관리할 때 구조체 배열을 사용하면 매우 유용하다. 예를 들어, 여러 책의 정보를 저장하고 관리하는 경우 구조체 배열을 사용할 수 있다.
3.2. 포인터와 구조체: 구조체 변수의 주소를 다루는 포인터를 사용하면, 함수를 통해 원본 구조체 데이터를 변경할 수 있다. 이는 메모리 사용을 효율적으로 만들고, 큰 구조체를 다룰 때 성능을 개선할 수 있다.
⭐4. 중급#1 : 구조체와 포인터
구조체와 포인터를 함께 사용하는 것은 C언어 프로그래밍에서 매우 흔하며, 데이터를 효율적으로 관리할 수 있게 해준다. 아래 예시는 구조체와 구조체 포인터를 사용하여 간단한 정보를 저장하고 접근하는 방법을 보여준다.
이 예제에서는 Person 구조체를 정의하고, 그 구조체의 인스턴스를 만든 다음, 구조체 포인터를 사용하여 그 인스턴스의 필드에 접근한다.
#include <stdio.h>
#include <string.h>
// 구조체 정의
typedef struct {
char name[100];
int age;
} Person;
int main() {
// 구조체 인스턴스 생성
Person person1;
// 구조체 필드에 직접 접근하여 값 할당
strcpy(person1.name, "John Doe");
person1.age = 30;
// 구조체 포인터 선언 및 초기화
Person *ptr = &person1;
// 구조체 포인터를 사용하여 필드 접근 및 값 출력
printf("Name: %s\n", ptr->name);
printf("Age: %d\n", ptr->age);
return 0;
}
이 코드는 다음을 수행한다:
4.1. Person 구조체를 정의한다.
4.2. person1이라는 Person 타입의 변수를 선언하고 초기화한다.
4.3. Person 타입의 포인터 ptr을 선언하고, person1의 주소로 초기화한다.
포인터를 사용하여 person1의 name과 age 필드에 접근하고, 이들의 값을 출력한다.
이 방식을 사용하면, 함수에 구조체 인스턴스를 전달할 때 메모리를 효율적으로 사용할 수 있으며, 함수 내에서 구조체 데이터를 변경할 수 있다.
⭐5. 중급#2 : 구조체와 포인터
여기서는 구조체와 함수를 활용하여 간단한 학생 성적 관리 시스템을 구현하고, 각 학생의 정보와 성적을 저장하고 처리하는 방법을 보여준다. 이 예제는 구조체를 사용하여 학생 정보를 정의하고, 구조체 배열을 통해 여러 학생의 데이터를 저장한다. 또한, 포인터와 함수를 사용하여 배열 내의 데이터에 접근하고 처리한다.
#include <stdio.h>
#define STUDENT_COUNT 3
// 학생 정보를 위한 구조체 정의
typedef struct {
char name[50];
int id;
float grade;
} Student;
// 학생 정보를 출력하는 함수
void printStudent(Student *s) {
printf("학생 이름: %s\n", s->name);
printf("학생 ID: %d\n", s->id);
printf("성적: %.2f\n\n", s->grade);
}
int main() {
// 학생 정보를 저장할 구조체 배열 선언
Student students[STUDENT_COUNT] = {
{"홍길동", 1, 92.5},
{"김철수", 2, 85.3},
{"이영희", 3, 78.4}
};
// 모든 학생 정보 출력
printf("학생 목록:\n");
for(int i = 0; i < STUDENT_COUNT; i++) {
printStudent(&students[i]);
}
return 0;
}
5.1. Student 구조체를 정의하여 학생의 이름, ID, 성적을 저장할 수 있는 구조를 만든다.
5.2. STUDENT_COUNT를 정의하여 학생 수를 상수로 설정합니다. 이 예제에서는 3명의 학생을 가정한다.
5.3. students 배열을 선언하고 초기화하여, 3명의 학생 정보를 저장한다.
5.4. printStudent 함수는 Student 구조체 포인터를 매개변수로 받아, 해당 학생의 정보를 출력합니다. 이 함수는 포인터를 사용하여 구조체의 멤버에 접근한다.
5.5. main 함수에서는 모든 학생 정보를 순회하며 출력합니다. 이 때, printStudent 함수에 각 학생 정보의 주소를 전달하여, 해당 학생의 정보를 출력한다.
'Language > C언어' 카테고리의 다른 글
[C/C++ Tip] 6. UNION 공용체와 STRUCT 구조체로 패킷 만들기 (2) | 2024.09.04 |
---|---|
[C/C++ Tip] 5. 구조체 패딩의 필요성 (0) | 2024.09.04 |
[C/C++ Tip] 3. 코딩 규칙. 변수명 정하기 (0) | 2024.09.01 |
[C/C++ Tip] 2. #define의 목적 (0) | 2024.09.01 |
[C/C++ Tip] 1. 개발하기 전, typedef 별명 부여. (0) | 2024.09.01 |