티스토리 뷰
구조체의 정의
구조체란 하나 이상의 변수를 그룹 지어서 새로운 자료형을 정의하는 것을 의미합니다. 그룹 지어진 변수는 서로 다른 자료형의 변수라도 상관없고 포인터 변수나 배열도 그룹에 속할 수 있습니다.
프로그램 내에서 만약 학생에 대한 정보 (이름, 나이, 성별)를 가지기 위해서는 3개의 변수가 필요합니다. 이 세 개의 변수는 서로 독립 된 정보를 나타내는 것이 아니라, 하나의 정보를 나타내는 변수들입니다. 즉 학생의 정보' 나타내기 위해 늘 붙어 다녀야 하는 것입니다.
1
2
3
4
5
6 |
struct Student //Student 구조체를 정의
{
char *name; //char* 타입의 구조체 멤버
int age; //int 타입의 구조체 멤버
char *major; //char* 타입의 구조체 멤버
}; |
첫 번째 줄에서 struct Student라는 선언은 Student라는 이름의 구조체를 정의한다는 의미를 지닙니다. 중괄호 안에는 이 구조체가 가지는 멤버 변수들에 대한 정의가 오게 됩니다. 이런식으로 Student라는 하나의 새로운 자료형이 완성이 되고 이를 가리켜 사용자 정의 자료형이라 부르며 구조체를 이루는 변수들을 구조체 멤버라고 부릅니다.
그러면 실제로 이 구조체를 선언하고 멤버에 접근하는 방식을 살펴 보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 |
struct Student //Student 구조체를 정의
{
char *name;// 타입의 구조체 멤버
int age; //int 타입의 구조체 멤버
char *major; //char* 타입의 구조체 멤버
};
int main()
{
Student st1 = { "Lee ki taek",27,"Computer" }; //배열 초기화 문법
Student st2;
st2.name = "Kim min ho"; //구조체 멤버 지정하여 초기화
st2.age = 27;
st2.major = "Computer";
return 0;
} |
'Student st1'와 같이 Student를 자료형으로 하는 st1 변수를 선언합니다. 그리고 각 멤버를 초기화 하는 방식으로 첫 번째는 11번 라인과 같이 배열 초기화 문법을 사용하는 방식입니다. 구조체 멤버 변수의 순서에 맞게 순서대로 초기화가 이루어집니다. 두 번째로는 .을 사용하여 각 구조체 멤버변수 이름을 지정하고 원하는 값으로 초기화를 하면 됩니다.
■ 구조체 배열과 포인터
구조체 배열을 선언하고 각 요소를 초기화 하는 코드입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
struct Student //Student 구조체를 정의
{
char name[20];
int age; //int 타입의 구조체 멤버 char major[20];
};
int main()
{
Student st[3];
for (int i = 0; i < 3; i++) //구조체 배열 요소 입력받기
{
scanf_s("%s %d %s", st[i].name,20,&st[i].age,st[i].major,20);
}
for (int i = 0; i < 3; i++) //구조체 배열 요소 출력하기
{
printf("%s %d %s \n", st[i].name, st[i].age, st[i].major);
}
return 0;
} |
위의 예제는 Student 구조체 배열을 st라는 이름을 선언하고 있습니다. 즉 이제 3명의 학생 정보를 담을 수 있는 배열이 생성 된 것입니다. 인덱스는 0에서 부터 시작하며, 배열의 첫 번쨰 구조체에 접근하기 위해서는 st[0].구조체 멤버 변수 이름 방식으로 접근이 가능합니다.
■구조체 변수와 포인터
구조체 변수를 가리킬 수 있는 구조체 포인터를 선언하고 사용하는 방법에 대해서 알아 보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 |
struct Student //Student 구조체를 정의
{
char name[20];
int age; //int 타입의 구조체 멤버
char major[20];
};
int main()
{
Student st1 = { "lee ki raek",27,"Computer" };
Student* p_st1; //구조체 포인터 선언
p_st1 = &st1; //st1 구조체 주소 값 대입
printf("%s %d %s\n", st1.name, st1.age, st1.major); //구조체 변수를 이용한 출력
printf("%s %d %s\n", (*p_st1).name, (*p_st1).age, (*p_st1).major); //구조체 포인터를 이용한 출력
printf("%s %d %s\n", p_st1->name, p_st1->age, p_st1->major); //구조체 포인터를 이용한 출력2
return 0;
} |
12번 라인에서 구조체 포인터를 선언하고 13번 라인에서 st1 구조체 변수의 주소 값을 할당하고 있습니다. 15번 라인은 일반 구조체 변수를 이용한 구조체 멤버 변수의 값을 출력하는 방식이며 16번 라인은 *연산자를 활용하여 출력을 하고 있습니다. 마지막 17번 라인에서 ->연산자(간접 멤버 접근 연산)를 통해서 출력 하는 방식을 보여줍니다. (*p_st1).age == p_st1->age는 완전히 같은 의미입니다.
또한 16번 라인에서 괄호가 들어가는 것은 *연산자가 .연산자보다 우선순위가 낮기 때문입니다.
따라서 괄호를 해주지 않으면 *p_st1.name == *(p_st1.name)과 같은 의미가 되어 전혀 다른 결과를 내놓게 됩니다.
■구조체 멤버와 포인터 변수
이번에는 구조체의 멤버로 포인터 변수가 선언되는 것에 관하여 알아 보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 |
struct Info
{
char addr[20];
char tel[20];
};
struct Student //Student 구조체를 정의
{
char name[20];
int age;
char major[20];
struct Info* info; //Info 구조체를 가르킬 수 있는 포인터를 멤버로 선언
};
int main()
{
Student st1 = { "lee ki raek",27,"Computer" };
Info info = {"Busan","010"};
st1.info = &info; //st1의 멤버변수 info가 Info 구조체를 가르키도록 함
printf("%s %d %s\n", st1.name, st1.age, st1.major);
printf("%s %s\n", st1.info->addr,st1.info->tel);
} |
Student 구조체는 Info 구조체를 가르 킬 수 있는 포인터를 멤버로 가지는 info 포인터를 가지고 있습니다.
그리고 21번 라인에서 st1.info = &info를 통해 info 멤버가 Info 구조체를 가르키도록 하고 있습니다. 24번 라인에서는 -> 연산자를 통해 실제로 Student 구조체의 멤버를 통해 Info 멤버에 접근하여 출력 하고 있습니다.
뿐만 아니라 다음과 같이 Student 구조체 멤버 변수로 Student를 가르킬 수 있는 포인터를 멤버로 선언도 가능합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
struct Student //Student 구조체를 정의
{
char name[20];
int age; //int 타입의 구조체 멤버
char major[20];
struct Student* next; //Info 구조체를 가르킬 수 있는 포인터를 멤버로 선언
};
int main()
{
Student st1 = { "lee ki raek",27,"Computer" };
Student st2 = { "Kim Min Ho",27,"Computer" };
st1.next = &st2;
}
|
'Programming > C언어' 카테고리의 다른 글
[C/C++] 파일 입출력 01 (0) | 2017.10.14 |
---|---|
[C/C++] 구조체와 사용자 정의 자료형 02 (0) | 2017.10.10 |
[C/C++] 함수 포인터에 대한 이해 (0) | 2017.10.07 |
[C/C++] 포인터의 포인터(더블 포인터)의 이해 (2) | 2017.10.07 |
[C/C++] 포인터와 함수에 대한 이해 (1) | 2017.10.06 |