C언어에서 구조체가 왜 필요한 지 알기 위해서는 먼저 자료형이 무엇인지에 대해 알아볼 필요가 있습니다.
구조체는 미리 어떠한 형태를 모아서 새로운 자료 형태를 만들건지 컴파일러에게 미리 신고를 해줘야 합니다. 자료형에 대한 구조를 먼저 알려주고 나서 그 자료형으로 변수를 선언해줘야 기억 공간에 잡힙니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#pragma warning(disable:4996)
#include <stdio.h>
struct student
{
int num;
double grade;
};
int main(void)
{
struct student a;
scanf("%d", &a.num);
scanf("%lf", &a.grade);
printf("번호: %d 학점: %.1lf", a.num, a.grade);
return 0;
}
|
cs |
4-6::
구조체를 구성하는 하나의 멤버, 마치 변수를 선언하는 것처럼되어있지만 변수 선언은 아닙니다. 초기화 또한 불가능합니다. 멤버로 사용하겠다는 신고를 하는 것뿐이지, 변수를 선언하는 명령은 아닙니다.
11::
위의 구조체의 경우, 멤버가 double과 int 이므로 12 바이트의 크기를 가질 것으로 예상됩니다. 하지만 실제 sizeof로 크기를 출력해보면 16바이트가 나옵니다. 이는 패딩 바이트가 들어가기 때문입니다. 시스템은 cpu가 메모리에 접근할 떄 접근 효율을 높이기 위해 일정한 바이트 단위로 접근합니다. 멤버의 크기가 들쑥날쑥한 경우 멤버 사이에 패딩 바이트를 넣어 멤버들을 정렬합니다. (바이트 얼라인먼트, byte alignment )
순서만 바껴도 데이터 낭비를 아낄수 있으므로 구조체 멤버를 사용할 때 순서를 적절히 조절해주면 크기를 많이 줄일 수 있습니다. 하지만 가독성은 떨이질 수 있으므로 상황에 맞게 코딩하면 됩니다.
구조체의 멤버로는 다양한 자료형들을 쓸 수 있습니다. 멤버로 배열 선언도 가능하며 포인터도 넣을 수 있습니다. 구조체의 변수를 새로운 구조체의 멤버로도 사용가능합니다.
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
27
|
#pragma warning(disable:4996)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
char name[20];
int age;
double height;
char *intro;
};
int main(void)
{
struct student a;
strcpy(a.name, "hong gil dong");
a.age = 17;
a.height = 187.5;
a.intro = (char *)malloc(sizeof(char) * 80);
scanf("%s", a.intro);
printf("이름 : %s\n", a.name);
printf("나이 : %d\n", a.age);
printf("키 : %.1lf\n", a.height);
printf("소개 : %s\n", a.intro);
free(a.intro);
return 0;
}
|
cs |
구조체 형을 다른 구조체의 멤버로 사용.
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
27
28
29
30
31
|
#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
struct profile
{
char name[20];
int age;
double height;
};
struct student
{
struct profile pf;
int num;
double grade;
};
int main(void)
{
struct student a;
strcpy(a.pf.name, "atom");
a.pf.age = 17;
a.pf.height = 187.5;
a.num = 315;
a.grade = 3.5;
printf("이름 : %s\n", a.pf.name);
printf("나이 : %d\n", a.pf.age);
printf("키 : %.1lf\n", a.pf.height);
printf("학번 : %d\n", a.num);
printf("학점 : %.1lf\n", a.grade);
return 0;
}
|
cs |
구조체는 다음과 같이 초기화 할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>
struct student
{
int num;
char name[20];
double grade;
};
int main(void)
{
struct student a = { 315, "atom", 4.4 };
struct student b = a;
printf("이름 : %s\n", b.name);
printf("학번 : %d\n", b.num);
printf("학점 : %.1lf\n", b.grade);
return 0;
}
|
cs |
14::
포인터를 안쓰면 두 개 값을 바꾸는 함수는 불가능할까? 구조체로 묶어서 하나의 변수처럼 하나의 인수로 주면 됩니다. 함수가 오직 하나의 값을 반환한다는 조건을 만족시키면서 목적을 수행할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#pragma warning(disable:4996)
#include <stdio.h>
struct vision
{
double left;
double right;
};
struct vision swap(struct vision b)
{
double temp;
temp = b.left;
b.left = b.right;
b.right = temp;
return b;
}
int main(void)
{
struct vision a = { 1.5,2.0 };
a = swap(a);
printf("%.1lf, %.1lf\n", a.left, a.right);
}
|
cs |
'Programming > C' 카테고리의 다른 글
[C] bit 연산자를 사용하여 bit set, clear, toggle 하기 (0) | 2023.03.14 |
---|---|
[C] 소스 코드를 여러 파일로 나누기 (feat. 컴파일, 링킹) (0) | 2023.03.12 |
[C] 배열 포인터란? (0) | 2023.02.26 |
[C] 윈도우에 gcc 컴파일러 설치하는 방법 (0) | 2023.02.13 |