주소록을 만들기 위해 학생구조체를 정의하고 사용하는 코드를 만들어보자.
#include <stdio.h>
struct student
{
char name[15];
int s_id;
int age;
char phone_number[14];
};
int main()
{
struct student goorm;
printf("이름 : ");
scanf("%s", goorm.name);
printf("학번 : ");
scanf("%d", &goorm.s_id);
printf("나이 : ");
scanf("%d", &goorm.age);
printf("번호 : ");
scanf("%s", goorm.phone_number);
printf("이름 : %s, 학번 : %d, 나이 : %d, 번호 : %s\n",
goorm.name, goorm.s_id, goorm.age, goorm.phone_number);
return 0;
}
구조체는 새로운 자료형을 만드는 것과 같다고 할 수 있기 때문에, 위와 같이 보통 main함수 전에 선언합니다. 어떤 함수 안에 선언하면 그 함수 안에서만 사용할 수 있기 때문인데, 만약 main함수 안에 선언한다면 main함수 안에서만 사용 할 수 있습니다.
#include <stdio.h>
struct student
{
int age;
char phone_number[14];
int s_id;
};
int main()
{
struct student goorm = { .age = 20, .phone_number = "010-1234-5678", 10 };
struct student codigm = { 22, "010-8765-4321"};
printf("나이 : %d, 번호 : %s, 학번 : %d\n",
goorm.age, goorm.phone_number, goorm.s_id);
printf("나이 : %d, 번호 : %s, 학번 : %d\n",
codigm.age, codigm.phone_number, codigm.s_id);
return 0;
//실행결과
//나이 : 20, 번호 : 010-1234-5678, 학번 : 10
//나이 : 22, 번호 : 010-8765-4321, 학번 : 0
}
구조체 멤버의 값을 main에서 선언을 할 때 대입해서 초기화 할 수 있습니다. 초기화 할때는 멤버 연산자 .
와 중괄호
를 사용합니다. 구조체는 배열처럼 멤버 전체를 초기화 할 수 있고, 원하는 변수만을 초기화 할 수도 있습니다.
초기화 할때는 { .멤버이름 = 값} 과 같은 형태로 초기화 할 수 있으며, 멤버이름을 적지 않고 초기화 할 수도 있습니다. 멤버 이름을 적지 않을 때는 구조체를 정의했던 순서대로 값이 들어갑니다. 또한 값을 따로 넣어주지 않은 멤버는 0으로 초기화 됩니다.
typedef
를 이용한 구조체 선언typedef
를 이용하는것. typedef
를 사용할때는 구조체 이름을 생략할 수 있는데, 먼저 구조체 이름을 생략하지 않고 사용하는 방법에 대해서 알아보겠습니다.typedef
typedef
키워드는 C언어에서 자료형을새롭게 이름을 붙일때 쓰는 키워드 입니다. typedef
를 사용하면 main함수에서 구조체를 선언할때 매번 struct
를 써줄 필요가 없습니다. 이 typedef
를 사용할 때에는 구조체 별칭이 필요한데, 구조체 별칭은 구조체를 정의할때 중괄호 뒤에 써주면 됩니다.#include <stdio.h>
typedef struct _Student {
int age;
char phone_number[14];
} Student;
int main(){
Student goorm;
printf("나이 : ");
scanf("%d", &goorm.age);
printf("번호 : ");
scanf("%s", goorm.phone_number);
printf("----\n나이 : %d\n번호 : %s\n----", goorm.age, goorm.phone_number);
return 0;
}
이렇게 구조체 이름을 굳이 적지 않아도 구조체를 선언하고 사용하는 것이 가능합니다. 이렇게 구조체 이름을 따로 지정하지 않고 별칭만 사용하는 것을 익명 구조체라고 합니다. typedef
를 이용해 구조체 별칭을 사용할 때에도 문법은 똑같으므로 멤버에 접근할 때는 똑같이 .
를 이용하면 됩니다.
#include <stdio.h>
typedef struct {
char name[30];
int age;
} Student;
int main(){
Student goorm[3] = { {.name = "해리 포터"},
{.name = "헤르미온느 그레인저"},
{.name = "론 위즐리"} };
goorm[0].age = 10;
goorm[1].age = 10;
goorm[2].age = 10;
printf("이름 : %s / 나이 : %d\n", goorm[0].name, goorm[0].age);
printf("이름 : %s / 나이 : %d\n", goorm[1].name, goorm[1].age);
printf("이름 : %s / 나이 : %d\n", goorm[2].name, goorm[2].age);
return 0;
}
#include <stdio.h>
typedef struct {
int s_id;
int age;
} Student;
int main(){
Student goorm;
Student *ptr;
ptr = &goorm;
(*ptr).s_id = 1004;
ptr->age = 20;
printf("goorm의 학번 : %d, 나이: %d\n", goorm.s_id, goorm.age);
//실행결과
//goorm의 학번 : 1004, 나이: 20
}
(*ptr).s_id
를 ptr->s_id
로 표현 할 수 있다.
#include <stdio.h>
typedef struct {
char name[15];
int age;
} Teacher;
typedef struct {
char name[15];
int age;
Teacher teacher;
} Student;
int main(){
Student Student;
Teacher Teacher;
Student.teacher.age = 30;
Teacher.age = 40;
return 0;
}
이런 식으로 다른 구조체를 멤버로 포함할 수 있는데, 이럴경우 Student만의 Teacher 구조체를 이용하고 싶으면 Student.teacher.age와 같이 연속으로 멤버를 참조해야 사용 할 수 있다.
왜 굳이 구조체를 중첩으로 넣어서 복잡하게 만들까?
이런 식으로 구조체를 중첩하게 되면 여러가지 정보를 관리하기에 용이하다. 예를 들어, 학교에는 학생마다 담임선생님이 있을 것입니다. 그 담임 선생님의 정보를 학생 정보마다 넣고 싶을 경우, 위와 같이 학생 구조체 안에 선생님 구조체를 넣어서 관리할 수 있음.
typedef struct {
char name[15];
int age;
struct Student *ptr;
} Student;
연결리스트나 트리를 만들때 사용된다고 함.
#include <stdio.h>
typedef struct
{
char name[20];
int kor; // 국어
int eng; // 영어
int math; // 수학
float avg; // 평균
} Student;
int main()
{
Student S[3];
for(int i=0;i<3;i++)
{
scanf("%s",S[i].name);
scanf("%d",&S[i].kor);
scanf("%d",&S[i].eng);
scanf("%d",&S[i].math);
S[i].avg = (S[i].kor+S[i].math+S[i].eng)/3.0;
}
for(int i=0;i<3;i++)
{
printf("%s ",S[i].name);
printf("%.1f\n",S[i].avg);
}
return 0;
}
한 눈에 끝내는 c언어 기초 를 공부하고 작성한 글입니다.