logo

C 구조

C의 구조는 다양한 유형의 항목을 단일 유형으로 그룹화하는 데 사용할 수 있는 사용자 정의 데이터 유형입니다. 그만큼 구조체 키워드 C 프로그래밍 언어에서 구조를 정의하는 데 사용됩니다. 구조의 항목을 구조라고 합니다. 회원 유효한 데이터 유형이면 무엇이든 가능합니다.

C 구조

C 구조 선언

프로그램에서 구조를 사용하기 전에 C에서 구조를 선언해야 합니다. 구조 선언에서는 데이터 유형과 함께 멤버 변수를 지정합니다. struct 키워드를 사용하여 다음 구문을 사용하여 C에서 구조를 선언할 수 있습니다.



통사론

 struct structure_name { data_type member_name1;  data_type member_name1; .... .... };>

위 구문은 구조 템플릿 또는 구조 프로토타입이라고도 하며 선언의 구조에 메모리가 할당되지 않습니다.

C 구조 정의

프로그램에서 구조를 사용하려면 해당 인스턴스를 정의해야 합니다. 구조 유형의 변수를 생성하여 이를 수행할 수 있습니다. 두 가지 방법을 사용하여 구조 변수를 정의할 수 있습니다.

1. 구조 템플릿을 사용한 구조 변수 선언

 struct structure_name { data_type member_name1; data_type member_name1; .... .... }  variable1, varaible2, ...  ;>

2. 구조 템플릿 이후의 구조 변수 선언

// structure declared beforehand struct structure_name  variable1, variable2  , .......;>

액세스 구조 멤버

다음을 사용하여 구조체 멤버에 액세스할 수 있습니다. ( . ) 도트 연산자.



통사론

structure_name.member1; strcuture_name.member2;>

구조에 대한 포인터가 있는 경우 화살표 연산자를 사용하여 멤버에 액세스할 수도 있습니다.

구조체 멤버 초기화

구조 멤버 수 없습니다 선언으로 초기화되었습니다. 예를 들어, 다음 C 프로그램은 컴파일에 실패합니다.

struct Point { int x = 0; // COMPILER ERROR: cannot initialize members here int y = 0; // COMPILER ERROR: cannot initialize members here };>

위의 오류가 발생하는 이유는 간단합니다. 데이터 유형이 선언되면 이에 대한 메모리가 할당되지 않습니다. 변수가 생성될 때만 메모리가 할당됩니다.



다음과 같은 3가지 방법으로 구조체 멤버를 초기화할 수 있습니다.

  1. 할당 연산자를 사용합니다.
  2. 초기화 목록 사용.
  3. 지정된 초기화 목록 사용.

1. 할당 연산자를 사용한 초기화

 struct structure_name str; str.member1 = value1; str.member2 = value2; str.member3 = value3; . . .>

2. 초기화 리스트를 이용한 초기화

 struct structure_name str = { value1, value2, value3 };>

이 유형의 초기화에서는 값이 구조 템플릿에 선언된 순서대로 할당됩니다.

3. 지정 초기화 목록을 이용한 초기화

지정 초기화를 사용하면 구조체 멤버를 어떤 순서로든 초기화할 수 있습니다. 이 기능은 C99 표준에 추가되었습니다.

 struct structure_name str = { .member1 = value1, .member2 = value2, .member3 = value3 };>

지정된 초기화는 C에서만 지원되고 C++에서는 지원되지 않습니다.

C 구조의 예

다음 C 프로그램은 구조를 사용하는 방법을 보여줍니다.


자바 메소드 오버라이딩



// C program to illustrate the use of structures> #include> > // declaring structure with name str1> struct> str1 {> >int> i;> >char> c;> >float> f;> >char> s[30];> };> > // declaring structure with name str2> struct> str2 {> >int> ii;> >char> cc;> >float> ff;> } var;>// variable declaration with structure template> > // Driver code> int> main()> {> >// variable declaration after structure template> >// initialization with initializer list and designated> >// initializer list> >struct> str1 var1 = { 1,>'A'>, 1.00,>'techcodeview.com'> },> >var2;> >struct> str2 var3 = { .ff = 5.00, .ii = 5, .cc =>'a'> };> > >// copying structure using assignment operator> >var2 = var1;> > >printf>(>'Struct 1: i = %d, c = %c, f = %f, s = %s '>,> >var1.i, var1.c, var1.f, var1.s);> >printf>(>'Struct 2: i = %d, c = %c, f = %f, s = %s '>,> >var2.i, var2.c, var2.f, var2.s);> >printf>(>'Struct 3 i = %d, c = %c, f = %f '>, var3.ii,> >var3.cc, var3.ff);> > >return> 0;> }>

>

>

산출

Struct 1: i = 1, c = A, f = 1.000000, s = techcodeview.com Struct 2: i = 1, c = A, f = 1.000000, s = techcodeview.com Struct 3 i = 5, c = a, f = 5.000000>

구조에 대한 typedef

그만큼 형식 정의 키워드는 이미 존재하는 데이터 유형에 대한 별칭을 정의하는 데 사용됩니다. 구조에서는 변수를 정의하기 위해 구조 이름과 함께 struct 키워드를 사용해야 합니다. 때로는 이로 인해 코드의 길이와 복잡성이 증가합니다. typedef를 사용하여 구조에 대한 새로운 짧은 이름을 정의할 수 있습니다.




// C Program to illustrate the use of typedef with> // structures> #include> > // defining structure> struct> str1 {> >int> a;> };> > // defining new name for str1> typedef> struct> str1 str1;> > // another way of using typedef with structures> typedef> struct> str2 {> >int> x;> } str2;> > int> main()> {> >// creating structure variables using new names> >str1 var1 = { 20 };> >str2 var2 = { 314 };> > >printf>(>'var1.a = %d '>, var1.a);> >printf>(>'var2.x = %d'>, var2.x);> > >return> 0;> }>

>

>

산출

var1.a = 20 var2.x = 314>

중첩된 구조

C 언어를 사용하면 한 구조를 다른 구조에 멤버로 삽입할 수 있습니다. 이 프로세스를 중첩이라고 하며 이러한 구조를 중첩 구조라고 합니다. 한 구조를 다른 구조에 중첩할 수 있는 두 가지 방법이 있습니다.

1. 임베디드 구조 중첩

이 방법에서는 중첩되는 구조가 상위 구조 내부에도 선언됩니다.

자바의 인터페이스

struct parent { int member1; struct member_str member2 { int member_str1; char member_str2; ... } ... }>

2. 별도의 구조 중첩

이 방법에서는 두 개의 구조가 별도로 선언된 다음 멤버 구조가 상위 구조 내에 중첩됩니다.

struct member_str { int member_str1; char member_str2; ... } struct parent { int member1; struct member_str member2; ... }>

여기서 주목해야 할 한 가지는 구조체 선언이 구조체 멤버로 정의되기 전에 항상 존재해야 한다는 것입니다. 예를 들어, 아래 선언이 유효하지 않습니다. 구조체 mem은 상위 구조 내부에서 선언될 때 정의되지 않기 때문입니다.

struct parent { struct mem a; }; struct mem { int var; };>

중첩된 멤버에 액세스

표시된 대로 동일한( . ) 점 연산자를 두 번 사용하여 중첩된 멤버에 액세스할 수 있습니다.

 str_parent.str_child .member;>

구조 중첩의 예




// C Program to illustrate structure nesting along with> // forward declaration> #include> > // child structure declaration> struct> child {> >int> x;> >char> c;> };> > // parent structure declaration> struct> parent {> >int> a;> >struct> child b;> };> > // driver code> int> main()> {> >struct> parent var1 = { 25, 195,>'A'> };> > >// accessing and printing nested members> >printf>(>'var1.a = %d '>, var1.a);> >printf>(>'var1.b.x = %d '>, var1.b.x);> >printf>(>'var1.b.c = %c'>, var1.b.c);> > >return> 0;> }>

>

>

산출

var1.a = 25 var1.b.x = 195 var1.b.c = A>

C의 구조 포인터

다른 변수와 마찬가지로 구조를 가리키는 포인터를 정의할 수 있습니다. 이러한 포인터는 일반적으로 다음과 같이 호출됩니다. 구조 포인터 . 다음을 사용하여 구조체 포인터가 가리키는 구조체의 멤버에 액세스할 수 있습니다. ( -> ) 화살표 연산자.

구조 포인터의 예




// C program to illustrate the structure pointer> #include> > // structure declaration> struct> Point {> >int> x, y;> };> > int> main()> {> >struct> Point str = { 1, 2 };> > >// p2 is a pointer to structure p1> >struct> Point* ptr = &str;> > >// Accessing structure members using structure pointer> >printf>(>'%d %d'>, ptr->x, ptr->y);> > >return> 0;> }>

>

>

산출

버블 정렬 파이썬
1 2>

자기 참조 구조

C의 자기 참조 구조는 자신과 동일한 유형에 대한 참조를 포함하는 구조입니다. 즉, 동일한 구조 유형을 가리키는 유형 포인터의 멤버를 포함합니다.

자기 참조 구조의 예

 struct structure_name { data_type member1;  data_type member2;  struct structure_name* str;  }>




// C program to illustrate the self referential structures> #include> > // structure template> typedef> struct> str {> >int> mem1;> >int> mem2;> >struct> str* next;> }str;> > // driver code> int> main()> {> >str var1 = { 1, 2, NULL };> >str var2 = { 10, 20, NULL };> > >// assigning the address of var2 to var1.next> >var1.next = &var2;> > >// pointer to var1> >str *ptr1 = &var1;> > >// accessing var2 members using var1> >printf>(>'var2.mem1: %d var2.mem2: %d'>, ptr1->다음->mem1,> >ptr1->다음->mem2);> > >return> 0;> }>

>

>

산출

var2.mem1: 10 var2.mem2: 20>

이러한 종류의 구조는 연결된 목록, 트리 등의 노드를 정의하는 등 다양한 데이터 구조에 사용됩니다.

C 구조 패딩 및 패킹

기술적으로 C의 구조체 크기는 해당 멤버 크기의 합이어야 합니다. 그러나 대부분의 경우에는 그렇지 않을 수도 있습니다. 그 이유는 구조 패딩 때문입니다.

구조 패딩 메모리의 데이터 멤버를 자연스럽게 정렬하기 위해 구조에 여러 개의 빈 바이트를 추가하는 개념입니다. 이는 구조의 다양한 데이터 멤버를 검색하기 위해 CPU 읽기 주기를 최소화하기 위해 수행됩니다.

빈 바이트를 제거하여 구조를 단단히 묶어야 하는 상황이 있습니다. 그러한 경우에 우리는 구조 포장. C 언어는 구조 패킹을 위한 두 가지 방법을 제공합니다.

  1. #pragma 팩 사용(1)
  2. __attribute((packed))__ 사용

구조 패딩 및 패킹의 예


일러스트레이터의 위 첨자



// C program to illustrate structure padding and packing> #include> > // structure with padding> struct> str1 {> >char> c;> >int> i;> };> > struct> str2 {> >char> c;> >int> i;> } __attribute((packed)) __;>// using structure packing> > // driver code> int> main()> {> > >printf>(>'Size of str1: %d '>,>sizeof>(>struct> str1));> >printf>(>'Size of str2: %d '>,>sizeof>(>struct> str2));> >return> 0;> }>

>

>

산출

Size of str1: 8 Size of str2: 5>

보시다시피, 구조체 패킹이 수행될 때 구조체의 크기가 달라집니다.

구조 패딩 및 패킹에 대한 자세한 내용은 이 문서를 참조하세요. 비트 필드는 구조 멤버의 길이를 비트 단위로 지정하는 데 사용됩니다. 멤버의 최대 길이를 알면 비트 필드를 사용하여 크기를 지정하고 메모리 소비를 줄일 수 있습니다.

비트 필드의 구문

struct structure_name  { data_type member_name : width_of_bit-field; };>

비트 필드의 예




// C Program to illustrate bit fields in structures> #include> > // declaring structure for reference> struct> str1 {> >int> a;> >char> c;> };> > // structure with bit fields> struct> str2 {> >int> a : 24;>// size of 'a' is 3 bytes = 24 bits> >char> c;> };> > // driver code> int> main()> {> >printf>(>'Size of Str1: %d Size of Str2: %d'>,> >sizeof>(>struct> str1),>sizeof>(>struct> str2));> >return> 0;> }>

>

>

산출

Size of Str1: 8 Size of Str2: 4>

보시다시피 비트 필드를 사용하여 멤버 'a'의 최대 크기를 정의하면 구조의 크기가 줄어듭니다.

C의 구조 사용

C 구조는 다음과 같은 용도로 사용됩니다.

  1. 구조는 언어에 없는 날짜, 시간, 복소수 등과 같은 일부 복잡한 데이터 유형을 만드는 데 사용할 수 있는 사용자 정의 데이터 유형을 정의하는 데 사용할 수 있습니다.
  2. 또한, 다양한 분야에 많은 양의 데이터를 저장할 수 있는 데이터 정리에도 사용할 수 있습니다.
  3. 구조는 트리, 연결 목록 등과 같은 데이터 구조를 만드는 데 사용됩니다.
  4. 함수에서 여러 값을 반환하는 데에도 사용할 수 있습니다.

C 구조의 한계

C 언어에서 구조는 다양한 유형의 데이터를 함께 묶는 방법을 제공합니다. 구조는 논리적으로 관련된 데이터 항목 그룹을 처리하는 데 유용한 도구입니다. 그러나 C 구조에도 몇 가지 제한 사항이 있습니다.

    높은 메모리 소비: 구조 패딩으로 인해 발생합니다. 데이터 숨김 없음: C 구조는 데이터 숨김을 허용하지 않습니다. 구조체 멤버는 구조체 범위 내 어디에서나 모든 함수를 통해 액세스할 수 있습니다. 구조 내부의 기능: C 구조는 구조 내부의 기능을 허용하지 않으므로 관련 기능을 제공할 수 없습니다. 정적 멤버: C 구조는 본문 내부에 정적 멤버를 가질 수 없습니다. 구조의 생성 생성: C의 구조는 구조 내부에 생성자를 가질 수 없습니다.

관련 기사

  • C 구조와 C++ 구조