구조체

2023. 2. 9. 17:52C언어/기본 개념

728x90

구조체 형 선언

struct student                     // int 4바이트, double 8바이트로 총 16(12 X)바이트 공간 확보
{
      int num;
     double grad;

};

 

구조체 형으로 사용하겠다는 일종의 신고일 뿐, 변수 선언은 아니다.

보통 main함수 위에서 선언 한다.

 

패딩바이트

구조체를 선언시 위 코드 같은 경우에는 12바이트 공간이 나와야 한다고 생각하지만 사실은 아니다.

16바이트가 나오게 된다. 아래 그림처럼 한번에 8바이트를 읽을 수 있는데 int형이 4바이트를 차지하고 다음에 남은 자리는 4바이트이므로 다음 double(8바이트)를 넣기 위해서는 새로 만들어서 넣어야 한다. 결국 빈 공간은 패딩 바이트로 남게 되며 총 16바이트 공간이 확보 된다. 

int " " " pad pad pad pad
double " " " " " " "
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>
struct student
{
    char name[20];
    int age;
    double height;
    char* intro; //크기가 입력 받은 길이에 맞게끔 동적 할당
 
};
int main(void
{
    struct student a;
    strcpy(a.name, "Lee");
    a.age = 24;
   a.height = 171.3;
    a.intro = "Hello my name is Lee"//"Hello~"문장 주소의 시작 값을 저장
    a.intro = (char*)malloc(80); // 공간 자체를 확보
    scanf("%s", a.intro);
 
    return 0;
    
}
cs

14행 캐릭터 배열의 배열명을 대입연산자 왼쪽에 작성 불가능하기 때문에 strcpy로 저장


구조체 형을 다른 구조체의 멤버로 사용하기 (구조체 안에 구조체)

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
#include <stdio.h>
#include <stdlib.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, "Lee");
    a.pf.age = 24;
    a.pf.height = 171.5;
    a.num = 243029;
    a.grade = 4.5;
 
    return 0;
}
 
cs

14구조체 안에 구조체 값을 선언하고싶을 때

변수명.(안에 있는)구조체.멤버

방식으로 사용한다.


구조체 변수의 초기화

struct student a = {{"lee", 24, 171.5}, 234029, 4.5};

하나씩 하지 않고 위처럼 한 번에 초기화가 가능하다.

만약 구조체 b를 선언해서 복사 해주고 싶은 경우에는  b=a로 간단하게 복사가 가능하다.

물론 b.num = a.num 처럼도 가능은하지만 구조체는 보통 양이 많기 때문에 복잡하다.


구조체 변수를 함수의 인수로 주고 반환 받기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>
struct vision swap(struct vision b);
struct vision
{
    double left;
    double right;
};
int main(void
{
    struct vision a = { 1.52.0 };
    a = swap(a);
    printf("%.1lf, %.1lf", a.left, a.right);
 
    return 0;
}
struct vision swap(struct vision b)
{
    double temp;
    temp = b.left;
    b.left = b.right;
    b.right = temp;
    return b;
}
cs

17행에 swap함수를 만들었다. 반환값을 구조체로 해주고 두 시력의 값을 서로 바꿔준다.


구조체를 선언 할 때 멤버들을 비트 단위로 선언

자료형 변수명: 비트수

struct bit_field
{
unsigned int son : 2;
unsigned int da : 2;
unsigned int pet : 3;
};

비트필드 구조체에서는 그냥 int도 가능하지만 대체적으로 unsigned를 붙여서 사용한다. 위처럼 선언 하면 7비트만 차지하지만 실제로는 기준 단위가 int이기 때문에 32비트(4바이트)가 선언된다.

struct bit_field
{
unsigned char a : 1;
unsigned char    : 2;
unsigned char c : 3;
unsigned char d : 4;
};

위 코드처럼 공백으로 두고 선언 할 경우 패딩비트가 생성 된다.

 

만약 공백으로 둔 상태에서 비트수를 'unsigned char    : 0;'으로 선언하게 되면 첫 번째 선언 된 a값을 한 바이트 안에 채우고 남은 공간(7비트)는 다 패딩바이트로 두겠다는 의미이다.

이렇게되면 struct bit_field s; 선언 후

a값의 주소(&s.a)를 사용할 수 없게 된다. 메모리에는 바이트단위 주소 값이기 때문에 1비트만 가지고 있는 a는 사용 할 수 없다. 만약 사용하고 싶다면 변수를 따로 선언후에 대입해주는 방법 밖에 없다.

int temp;

scanf("%d", &temp)

s.a=temp;

 

728x90

'C언어 > 기본 개념' 카테고리의 다른 글

파일 개방 및 입출력  (0) 2023.02.14
구조체 활용, 공동체, 열거형  (0) 2023.02.10
동적 할당 저장 공간의 활용  (0) 2023.02.09
동적 할당 함수  (0) 2023.02.08
함수 포인터와 void 포인터  (0) 2023.02.07