앞서 봤던 구조체 변수를 선언할 때 항상 struct를 붙였어야 했는데, 매번 쓰기도 번거롭고 보기도 별로 좋지가 않습니다.
그래서 이를 줄이고 깔끔하게 쓸 수 있는 방법을 알아보겠습니다.
typedef
typedef 키워드는 구조체 변수 선언을 단축할 수 있는 방법입니다.
구조체 형을 선언할 때 struct앞에 typedef를 쓰고 구조체 블록이 끝날 때 struct Animal을 뭐라고 줄일지 결정합니다.
이때 결정하는 이름은 구조체 형의 이름(여기서는 Animal)과 같을 필요는 없습니다.
이렇게 하면, 기존에 struct를 쓰던 방법에서
멤버 값 초기화
구조체에서는 구조체 변수를 선언하면서 초기화를 할 수 있습니다.
콤마 순서대로 멤버에 값이 대입됩니다.
만들면서 미리 값을 정해야 할 때 유용합니다.
구조체 대입
구조체 변수에는 다른 구조체 변수를 대입할 수 있습니다.
이렇게 하면, 대입하려는 값을 하나씩 복사해서 구조체 변수의 멤버에 대입합니다.
값을 복사해서 대입하기 때문에 두 구조체 변수는 서로 영향을 끼치지 않는 독립적인 변수입니다.
구조체의 크기
구조체의 크기는 sizeof( ) 함수를 이용해 구할 수 있습니다.
구조체의 크기는 구조체 안의 멤버들의 크기를 전부 더한 값과 같거나 크게 됩니다. 구조체 포인터의 경우 주소만 저장하기 때문에 항상 4byte입니다.
하지만, 모든 멤버들의 크기를 더한 값이 항상 구조체의 크기와 같지는 않습니다.
일반적으로 구조체 포인터의 크기는 4byte이기 때문에 구조체의 크기가 포인터의 크기보다 큽니다.
비트 필드(bit field)
"비트 필드"는 비트를 지정한 멤버를 말합니다. 말 그대로 사용할 비트의 수를 정한다는 것입니다.
왜 비트를 정할까요? 컴퓨터 메모리에서 가장 작은 단위는 bit입니다. 우리가 변수를 만들기 위해 일반적으로 사용하는 기본 타입은 아무리 작아도 1byte입니다. 1byte는 8bit입니다.
이 수치는 약 256가지의 값을 저장할 수 있습니다.
하지만 1~4까지의 값만 사용한다면 나머지 메모리는 낭비입니다. 그래서 bit를 지정함으로써 메모리의 낭비를 줄이고 구조체의 크기를 줄일 수 있는 것입니다.
age와 size가 1,2비트만 필요하지는 않겠지만, 설명을 위해 비트를 줄여보았습니다.
비트를 필요한 만큼만 지정했을 때 구조체의 크기가 줄어든 것을 볼 수 있습니다.
하지만, 앞서 설명한 대로 구조체의 크기는 각 멤버의 크기를 더한 것과 똑같지는 않을 수 있기 때문에 주의하시기 바랍니다.
구조체의 멤버를 더한 것과 왜 크기가 같지 않을까요?
구조체 멤버의 크기가 다를 때는 가장 크기가 큰 타입을 기준으로 "패딩"이라는 것을 해서 정렬한다고 합니다.
그래서 정렬을 하되 크기에 딱 맞게 붙여서 정렬하는 게 아니라 4byte가 가장 큰 단위이면 그것보다 작은 타입은 나머지 크기를 비워놓고 메모리를 할당하기 때문에
구조체의 크기 = (멤버 중 가장 큰 크기 * 멤버 수)
가 됩니다.
패딩을 해서 메모리를 결정한다는 것은 알았습니다. 그러면 왜 패딩을 사용해야 할까요? 왜 C를 만든 사람은 패딩을 사용해서 구조체의 크기를 정했을까요? 배열처럼 메모리 주소를 참조할 때 일정한 크기로 만들어서 위치를 찾기 쉽게하기 위해서 일까요? 이것에 대한 해답은 당장 급한건 아니기 때문에 천천히 알아보도록 하겠습니다.
실제로 int(4바이트)와 double(8바이트)를 더하면 12바이트가 아닌 16바이트가 나오는 것을 볼 수 있었습니다.
반면 비트 필드로 만들어서 1비트와 2비트를 합 친경 우 패딩을 적용해도 4비트가 되어서 1바이트나 0바이트가 나오지 않을까 생각해 보았는데 실제로는 4바이트(32비트)가 나오고 있습니다.
이것은 왜 그럴까요?
비트의 경우는 위에서부터 차례대로 메모리에 저장이 되고 아무리 크기가 작더라도 선언한 타입의 크기만큼의 크기를 가집니다. 여기서는 int로 선언을 했으니 4바이트입니다.
비트 값으로 쪼개져 매우 작은 크기를 가진다고 해도 int형으로 지정했으므로 최소 크기는 4바이트인 것으로 생각됩니다.
그러다가 32비트를 넘어가면 8바이트로 바뀌어서 최소 단위를 넘어가면 그다음 배수만큼 공간이 할당되는 것인가 생각했지만, 63 비트라서 8바이트(64비트)를 넘지 않았음에도 12바이트로 넘어갔습니다. 다른 글에서도 비트수가 최소 단위 바이트를 넘어가면 같은 크기만큼(short형이라면 2바이트 + 2바이트) 추가된다고 하는데 왜 이 경우에는 초과되지 않았는데도 12바이트가 되었는지 궁금증이 생깁니다.
참고한 자료
dojang.io/mod/page/view.php?id=431
C 언어 코딩 도장: 51.1 구조체 크기 알아보기
구조체 정렬을 하기 전에 먼저 구조체의 크기부터 알아보겠습니다. 구조체의 전체 크기는 sizeof 연산자를 사용하면 알 수 있습니다. sizeof(struct 구조체) sizeof(구조체별칭) sizeof(구조체변수) sizeof
dojang.io
dojang.io/mod/page/view.php?id=472
C 언어 코딩 도장: 56.1 구조체 비트 필드를 만들고 사용하기
56 구조체 비트 필드 사용하기 지금까지 구조체의 멤버는 각 자료형 크기만큼 공간을 차지했습니다. 하지만 구조체 비트 필드를 사용하면 구조체 멤버를 비트 단위로 저장할 수 있습니다. 특히 C
dojang.io
27. 구조체(struct) - 비트 필드(bit field)
구조체의 기능 중에서 많이 사용하지 않지만, 정수형 데이터를 비트 단위로 나누어서 사용할 수 있는 기능을 제공합니다. 이를 구조체의 bit field라고 합니다. struct 구조체명 { unsigned 정수형 멤버
www.it-note.kr
구조체가 아닌 일반 변수는 비트를 정할 수 없을까요?
일반적으로 값을 할당할 때 사용하는 int, double 같은 변수도 비트를 지정할 수 있으면 정말 효율적일 것 같은데요. 왜 구조체에서만 비트를 지정할 수 있을까요?
1칠판에 쓰기 빠듯한 분량이었는데요. 어떻게든 욱여적어서 정리를 했습니다.ㅎㅎ
이것으로 1칠판 마치겠습니다.
'C' 카테고리의 다른 글
[11] 공용체 (0) | 2021.04.26 |
---|---|
[10] 구조체 응용 (0) | 2021.04.26 |
[8] 구조체 (0) | 2021.04.24 |
[7] 함수 포인터 (0) | 2021.04.24 |
[6] 문자열과 포인터 (0) | 2021.04.24 |