#include <stdio.h>
struct student // 구조체 선언
{
int num;
double grade;
};
int main(void)
{
struct student s1;
s1.num = 2;
s1.grade = 2.7;
printf("학번: %d\n", s1.num);
printf("학점: %.1lf\n", s1.grade);
return 0;
}
구조체 선언이 main 함수 앞에 있으면 프로그램 전체에서 사용할 수 있고, 함수 안에 선언하면 그 함수 안에서만 쓸 수 있다. 구조체 선언이 끝나면 그 이후부터 사용자가 정의한 새로운 자료형을 컴파일러가 인식할 수 있다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct profile
{
char name[20];
int age;
double height;
char *intro; // 자기 소개를 위한 포인터
};
int main(void)
{
struct profile yuni;
strcpy(yuni.name, "서하윤");
yuni.age = 17;
yuni.height = 164.5;
yuni.intro = (char *)malloc(80);
printf("자기소개 : ");
gets(yuni.intro);
printf("이름: %s\n", yuni.name);
printf("나이: %d\n", yuni.age);
printf("키 : %.1lf\n", yuni.height);
printf("자기소개 : %s\n", yuni.intro);
free(yuni.intro);
return 0;
}
#include <stdio.h>
struct student
{
int id;
char name[20];
double grade;
};
int main(void)
{
struct student s1 = {315, "홍길동", 2.4},
s2 = {316, "이순신", 3.7},
s3 = {317, "세종대왕", 4.4};
struct student max;
max = s1;
if (s2.grade > max.grade) max = s2; // 대입연산으로 복사
if (s3.grade > max.grade) max = s3;
printf("학번: %d\n", max.id);
printf("이름: %s\n", max.name);
printf("학점: %.1lf\n", max.grade);
return 0;
}
#include <stdio.h>
struct vision
{
double left;
double right;
};
struct vision exchange(struct vision robot);
int main(void)
{
struct vision robot; // 구조체 변수 선언
printf("시력 입력: ");
scanf("%lf%lf", &(robot.left), &(robot.right));
robot = exchange(robot);
printf("바뀐 시력: %.1lf %.1lf\n", robot.left, robot.right);
}
struct vision exchange(struct vision robot)
{
double temp;
temp = robot.left;
robot.left = robot.right;
robot.right = temp;
return robot; // 구조체 변수 반환
}
#include <stdio.h>
struct vision
{
double left;
double right;
};
void swap(struct vision *robot);
int main(void)
{
struct vision robot;
printf("시력 입력: ");
scanf("%lf%lf", &(robot.left), &(robot.right));
swap(&robot); // 포인터로 전달
printf("바뀐 시력: %.1lf %.1lf\n", robot.left, robot.right);
}
void swap(struct vision *robot)
{
double temp;
temp = robot->left;
robot->left = robot->right;
robot->right = temp;
}
그렇다면, 구조체와 포인터의 장단점
- 구조체
- 관련 데이터를 함께 묶어서 관리
- 코드의 가독성과 유지 보수성 향상
- 복잡한 데이터 구조 처리
- 캡슐화된 데이터 처리
- 단점: 메모리 복사 비용이 많이 발생한다.(메모리 사용, 시간)
- 포인터
- 데이터는 메모리에서 수정, 참조만 변경. 그래서 성능면에서 유리하다
- 구조체가 크다면 포인터 사용 추천
구조체
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct score
{
int kor;
int eng;
int math;
};
int main(void)
{
struct score yuni = { 90, 80, 70 }; // 구조체 변수 선언과 초기화
struct score *ps = &yuni; // 구조체 포인터에 주소 저장
printf("국어 : %d\n", (*ps).kor); // 구조체 포인터로 멤버 접근
printf("영어 : %d\n", ps->eng); // 연산자 -> 사용
printf("수학 : %d\n", ps->math);
return 0;
}
#include <stdio.h>
struct address
{
char name[20];
int age;
char tel[20];
char addr[80];
};
void print_list(struct address *lp);
int main(void)
{
struct address list[3] = {
{"홍길동", 23, "111-1111", "울릉도 독도"},
{"이순신", 35, "222-2222", "서울 건천동"},
{"장보고", 19, "333-3333", "완도 청해진"}
};
print_list(list);
return 0;
}
void print_list(struct address *lp)
{
int i ;
for(i = 0; i < 3; i++)
{
printf("%10s%5d%15s%20s\n",(lp+i)->name, (lp+i)->age, (lp+i)->tel, (lp+i)->addr);
}
}
#include <stdio.h>
struct list
{
int num;
struct list *next;
};
int main(void)
{
struct list a = {10, 0}, b = {20, 0}, c = {30, 0}; // 구조체 변수 초기화
struct list *head = &a, *current;
a.next = &b; // a의 포인터 멤버가 b를 가리킴
b.next = &c;
printf("head->num: %d\n", head->num);
printf("head->next->num: %d\n", head->next->num);
printf("list all: ");
current = head;
while (current != NULL)
{
printf("%d ", current->num);
current = current -> next;
}
printf("\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
// 노드 구조체 정의
struct Node {
int data; // 데이터 저장
struct Node *next; // 다음 노드를 가리키는 포인터 (자기 참조 포인터)
};
// 새로운 노드를 생성하는 함수
struct Node* createNode(int data) {
struct Node *newNode = (struct Node *)malloc(sizeof(struc
-right:10px;>t Node)); // 메모리 할당
newNode->data = data; // 데이터 저장
newNode->next = NULL; // 다음 노드를 NULL로 초기화 (리스트의 끝)
return newNode;
}
// 리스트의 모든 노드를 출력하는 함수
void printList(struct Node *head) {
struct Node *current = head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next; // 다음 노드로 이동
}
printf("NULL\n");
}
// 리스트에 노드를 추가하는 함수
void appendNode(struct Node **head, int data) {
struct Node *newNode = createNode(data);
if (*head == NULL) { // 리스트가 비어 있을 경우
*head = newNode;
return;
}
struct Node *current = *head;
while (current->next != NULL) {
current = current->next; // 마지막 노드까지 이동
}
current->next = newNode; // 마지막 노드의 next에 새 노드 연결
}
int main() {
struct Node *head = NULL; // 빈 리스트 생성
// 리스트에 노드 추가
appendNode(&head, 10);
appendNode(&head, 20);
appendNode(&head, 30);
// 리스트 출력
printList(head);
return 0;
}
#include <stdio.h>
union student
{
int num;
double grade;
};
int main(void)
{
union student s1 = { 315 };
printf("학번: %d\n", s1.num);
s1.grade = 4.4;
printf("학점: %.1lf\n", s1.grade);
printf("학번: %d\n", s1.num);
return 0;
}
#include <stdio.h>
enum season {SPRING, SUMMER, FALL, WINTER};
int main(void)
{
enum season ss;
char *pc = NULL;
ss = SPRING;
switch (ss)
{
case SPRING:
pc = "inline"; break;
case SUMMER:
pc = "swimming"; break;
case FALL:
pc = "trip"; break;
case WINTER:
pc = "skiing"; break;
}
printf("나의 레저 활동 => %s\n", pc);
return 0;
}
#include <stdio.h>
struct student
{
int num;
double grade;
};
typedef struct student Student;
void print_data(Student *ps);
int main(void)
{
Student s1 = {315, 4.2};
print_data(&s1);
return 0;
}
void print_data(Student *ps)
{
printf("학번: %d\n", ps->num);
printf("학점: %.1lf\n", ps->grade);
}
#if, #else, #elif, #ifdef, #ifndef, #endif