2학년/C

[C]사용자 지정 타입

CS_student 2023. 7. 29. 23:20

구조체와 포인터 

 구조체 포인터는 struct 구조체이름* 구조체포인터이름; 으로 선언된다. 

 배열과 달리 구조체의 이름은 구조체를 가리키는 주소가 아니기 때문에 주소 연산자를 사용해주어야 한다.

 구조체 포인터를 이용하여 멤버변수에 접근하는 방법은 1) 참조연산자(*) 2)화살표 연산자(->)를 이용하는 방법이 있다. 

ex) (*ptr).x   || ptr -> x

  참조연산자보다 멤버연산자의 우선 순위가 높기 때문에 괄호를 쳐주어야 예상대로 작동한다. 

 

중첩된 구조체

멤버변수로 구조체를 가져 중첩되게 구현할 수 있다. 

 

typedef strcut {
    char surname[10];
    char name[20];
)name;

typedef struct {
    name student_name;
)student;

int main(void) {
    studnet irene = {{"Irene","kdy"}};
}

 

 

구조체의 크기와 바이트패딩

만약 char,int,double을 각각 멤버변수로 가지는 구조체가 있다고 했을 때, 각 자료형의 사이즈는 13 바이트이다. 그러나 실제 구조체가 메모리에 차지하는 크기는 16바이트를 갖는다. 이렇듯  구조체변수가 메모리에서 차지하는 크기는 각 멤버변수가 메모리에서 차지하는 바이트의 합보다 크거나 같다. 

위 처럼 컴파일러는 메모리 접근을 쉽게 하기 위해 크기가 가장 큰 멤버변수를 기준으로 모든 멤버변수의 메모리 크기를 맞추기 때문이다. 

 이것을 바이트 패딩이라고 하며, 이때 추가되는 바이트를 패딩 바이트라고 한다. 

    char를 위해 8byte가 할당되며 남은 7바이트에 또한 int가 할당된다. double형이 남은 3바이트에 들어갈 수 없으므로 새로은 8바이트가 할당된다. 따라서 전체 구조체 크기가 16바이트가 되는 것이다. 

 

공용체

공용체는 union 키워드를 사용하여 선언하며, 모든 멤버변수가 한 메모리 공간을 공유한다는 점만을 제외하면 구조체와 동일하다. 모든 멤버변수가 가장 큰 멤버변수로부터 할당받은 메모리를 공유하므로, 공용체는 한 번에 하나의 멤버변수밖에 사용할 수 없다. 필요할 때 적절한 크기를 점유하며 사용하는 것이다.

비트필드

C언어에서 구조체는 자료형의 최소 단위인 바이트를 넘어 1비트 단위씩 영역을 선언할 수 있다. 보통 부호 없는(unsigned) 자료형을 주로 사용한다. 단, 실수 자료형은 비트필드로 사용할 수 없다.

 비트필드의 선언

struct 구조체이름 {

      정수자료형 멤버이름 : 비트수;

};

%u를 통해 비트를 출력할 수 있으며 비트필드에는 지정한 비트 수만큼 저장되고 나머지 비트는 버려진다. 

 

열거체

 enum키워드를 사용하여 선언한다. 열거체는 새로운 타입을 선언하면서,  동시에 해당 타입이 가질 수 있는 정수형 상수값도 같이 명시하게 된다. 

 ex) enum Days {mon,tue,wed,thu,fri,sat,sun}; //초기화하지 않았으므로 순서대로 0,1,2,3,4,...로 할당

     원소에 대치될 정수값을 정의해주려면 {mon=10, ...} 처럼 작성하면 된다.