C 구조


C 배열을 사용하면 동일한 유형의 데이터 항목을 저장할 수 있는 변수를 정의할 수 있습니다. 구조는 C 프로그래밍에서 사용할 수 있는 또 다른 사용자 정의 데이터 유형으로, 다양한 유형의 데이터 항목을 저장할 수 있습니다.

구조는 레코드를 나타내는 데 사용됩니다. 도서관에 있는 책의 역학을 추적하고 싶다면 각 책의 다음 속성을 추적해야 할 수도 있습니다.

  • Title

  • Author

  • 제목

  • 책 ID

구조 정의

구조를 정의하려면 struct 문을 사용해야 합니다. struct 문은 여러 멤버를 포함하는 새로운 데이터 유형을 정의합니다.

struct [structure tag]{
   member definition;
   member definition;   ...
   member definition;} [one or more structure variables];

구조 태그는 선택 사항이며 각 멤버 정의는 int i 또는 float f와 같은 표준 변수 정의입니다. ; 또는 기타 유효한 변수 정의. 구조 정의 끝에서 마지막 세미콜론 앞에 선택적으로 하나 이상의 구조 변수를 지정할 수 있습니다. Book 구조가 선언되는 방법은 다음과 같습니다.

struct Books{   char  title[50];   char  author[50];   char  subject[100];   int   book_id;} book;

구조 멤버 액세스

구조 멤버에 액세스하려면 멤버 액세스 연산자(.)를 사용합니다. 멤버 액세스 연산자는 구조 변수 이름과 액세스하려는 구조 멤버 사이의 마침표입니다. struct 키워드를 사용하여 구조 유형의 변수를 정의할 수 있습니다. 다음 예에서는 구조체의 사용을 보여줍니다.

#include <stdio.h>#include <string.h> struct Books{   char  title[50];   char  author[50];   char  subject[100];   int   book_id;}; int main( ){   struct Books Book1;        /* 声明 Book1,类型为 Book */   struct Books Book2;        /* 声明 Book2,类型为 Book */ 
   /* Book1 详述 */
   strcpy( Book1.title, "C Programming");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Tutorial");   Book1.book_id = 6495407;   /* Book2 详述 */
   strcpy( Book2.title, "Telecom Billing");
   strcpy( Book2.author, "Zara Ali");
   strcpy( Book2.subject, "Telecom Billing Tutorial");   Book2.book_id = 6495700; 
   /* 输出 Book1 信息 */
   printf( "Book 1 title : %s\n", Book1.title);
   printf( "Book 1 author : %s\n", Book1.author);
   printf( "Book 1 subject : %s\n", Book1.subject);
   printf( "Book 1 book_id : %d\n", Book1.book_id);   /* 输出 Book2 信息 */
   printf( "Book 2 title : %s\n", Book2.title);
   printf( "Book 2 author : %s\n", Book2.author);
   printf( "Book 2 subject : %s\n", Book2.subject);
   printf( "Book 2 book_id : %d\n", Book2.book_id);   return 0;}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.

Book 1 title : C ProgrammingBook 1 author : Nuha AliBook 1 subject : C Programming TutorialBook 1 book_id : 6495407Book 2 title : Telecom BillingBook 2 author : Zara AliBook 2 subject : Telecom Billing TutorialBook 2 book_id : 6495700

함수 매개변수로서의 구조체

구조체를 함수 매개변수로 사용할 수 있으며, 매개변수 전달 방법은 다른 Type 변수와 동일하거나 포인터가 유사합니다. 위 예의 방식을 사용하여 구조 변수에 액세스할 수 있습니다.

#include <stdio.h>#include <string.h> struct Books{   char  title[50];   char  author[50];   char  subject[100];   int   book_id;};/* 函数声明 */void printBook( struct Books book );int main( ){   struct Books Book1;        /* 声明 Book1,类型为 Book */   struct Books Book2;        /* 声明 Book2,类型为 Book */ 
   /* Book1 详述 */
   strcpy( Book1.title, "C Programming");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Tutorial");   Book1.book_id = 6495407;   /* Book2 详述 */
   strcpy( Book2.title, "Telecom Billing");
   strcpy( Book2.author, "Zara Ali");
   strcpy( Book2.subject, "Telecom Billing Tutorial");   Book2.book_id = 6495700; 
   /* 输出 Book1 信息 */
   printBook( Book1 );   /* 输出 Book2 信息 */
   printBook( Book2 );   return 0;}void printBook( struct Books book ){
   printf( "Book title : %s\n", book.title);
   printf( "Book author : %s\n", book.author);
   printf( "Book subject : %s\n", book.subject);
   printf( "Book book_id : %d\n", book.book_id);}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다.

Book title : C ProgrammingBook author : Nuha AliBook subject : C Programming TutorialBook book_id : 6495407Book title : Telecom BillingBook author : Zara AliBook subject : Telecom Billing TutorialBook book_id : 6495700

구조에 대한 포인터

구조에 대한 포인터를 정의할 수 있습니다. 아래와 같이 다른 유형의 변수에 대한 포인터를 정의합니다.

struct Books *struct_pointer;

이제 위에서 정의한 포인터 변수에 구조 변수의 주소를 저장할 수 있습니다. 구조체 변수의 주소를 찾으려면 아래와 같이 구조체 이름 앞에 & 연산자를 넣으세요.

struct_pointer = &Book1;

구조체에 대한 포인터를 사용하여 구조체 멤버에 액세스하려면 -를 사용해야 합니다. > 연산자, 아래와 같이 :

struct_pointer->title;

구조 포인터를 사용하여 위의 예를 다시 작성해 보겠습니다. 이는 구조 포인터의 개념을 이해하는 데 도움이 됩니다.

#include <stdio.h>#include <string.h> struct Books{   char  title[50];   char  author[50];   char  subject[100];   int   book_id;};/* 函数声明 */void printBook( struct Books *book );int main( ){   struct Books Book1;        /* 声明 Book1,类型为 Book */   struct Books Book2;        /* 声明 Book2,类型为 Book */ 
   /* Book1 详述 */
   strcpy( Book1.title, "C Programming");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C Programming Tutorial");   Book1.book_id = 6495407;   /* Book2 详述 */
   strcpy( Book2.title, "Telecom Billing");
   strcpy( Book2.author, "Zara Ali");
   strcpy( Book2.subject, "Telecom Billing Tutorial");   Book2.book_id = 6495700; 
   /* 通过传 Book1 的地址来输出 Book1 信息 */
   printBook( &Book1 );   /* 通过传 Book2 的地址来输出 Book2 信息 */
   printBook( &Book2 );   return 0;}void printBook( struct Books *book ){
   printf( "Book title : %s\n", book->title);
   printf( "Book author : %s\n", book->author);
   printf( "Book subject : %s\n", book->subject);
   printf( "Book book_id : %d\n", book->book_id);}

위 코드를 컴파일하고 실행하면 다음과 같은 결과가 생성됩니다. :

Book title : C ProgrammingBook author : Nuha AliBook subject : C Programming TutorialBook book_id : 6495407Book title : Telecom BillingBook author : Zara AliBook subject : Telecom Billing TutorialBook book_id : 6495700

비트 필드

일부 정보는 저장 시 전체 바이트를 차지할 필요가 없지만 몇 개 또는 한 개의 바이너리 비트만 차지하면 됩니다. 예를 들어 스위치 값을 저장할 때 0과 1의 두 가지 상태만 있으므로 1비트 바이너리를 사용할 수 있습니다. 저장 공간을 절약하고 처리를 쉽게 하기 위해 C 언어는 "비트 필드" 또는 "비트 세그먼트"라는 데이터 구조를 제공합니다.

소위 "비트 필드"는 바이트의 이진 비트를 여러 영역으로 나누고 각 영역의 비트 수를 지정하는 것입니다. 각 도메인에는 프로그램에서 도메인 이름으로 작업할 수 있는 도메인 이름이 있습니다. 이러한 방식으로 여러 다른 객체를 1바이트의 이진 비트 필드로 표현할 수 있습니다.

전형적인 예:

  • 1비트 바이너리를 사용하여 스위치 값을 저장하는 경우 0과 1의 두 가지 상태만 있습니다.

  • 외부 파일 형식 읽기 - 비표준 파일 형식을 읽을 수 있습니다. 예: 9자리 정수.

비트 필드 정의 및 비트 필드 변수 설명

비트 필드 정의는 구조 정의와 유사하며 형식은 다음과 같습니다.

    struct 位域结构名        { 位域列表 };

비트 필드 목록 형식은 다음과 같습니다.

    类型说明符 位域名: 位域长度

예:

struct bs{    int a:8;    int b:2;    int c:6;};

Bit 필드변수 설명은 구조체 변수의 설명과 동일합니다. 먼저 정의한 후 설명할 수도 있고, 정의하고 동시에 설명할 수도 있고, 직접 설명할 수도 있습니다. 예:

struct bs{    int a:8;    int b:2;    int c:6;}data;

설명 데이터는 bs 변수로, 총 2바이트를 차지합니다. 비트 필드 a는 8비트, 비트 필드 b는 2비트, 비트 필드 c는 6비트를 차지합니다.

또 다른 예를 살펴보겠습니다.

struct packed_struct {  unsigned int f1:1;  unsigned int f2:1;  unsigned int f3:1;  unsigned int f4:1;  unsigned int type:4;  unsigned int my_int:9;} pack;

여기에서 Packed_struct에는 6개의 멤버가 포함되어 있습니다. 즉, 4개의 1비트 식별자 f1..f4, 4비트 유형 및 9비트 my_int입니다.

비트 필드 정의에는 여러 가지 설명이 있습니다.

  • 비트 필드는 동일한 바이트에 저장되어야 하며 2바이트에 걸쳐 있을 수 없습니다. 1바이트의 남은 공간이 다른 비트 필드를 저장할 만큼 충분하지 않으면 다음 단위부터 비트 필드를 저장해야 합니다. 의도적으로 다음 장치에서 비트 필드를 시작할 수도 있습니다. 예:

    struct bs{    unsigned a:4;    unsigned  :4;    /* 空域 */    unsigned b:4;    /* 从下一单元开始存放 */    unsigned c:4}

    이 비트 필드 정의에서 a는 첫 번째 바이트의 4비트를 차지하고, 마지막 4비트는 0으로 채워져 사용되지 않음을 나타내며, b는 두 번째 바이트부터 시작하여 4비트를 차지하고, c는 4비트를 차지합니다. .

  • 비트 필드는 2바이트에 걸쳐 있을 수 없으므로 비트 필드의 길이는 1바이트 길이보다 클 수 없습니다. 즉, 8바이너리 비트를 초과할 수 없습니다. 일부 컴파일러는 최대 길이가 컴퓨터의 정수 길이보다 큰 경우 필드가 겹치도록 메모리를 허용할 수 있으며, 다른 컴파일러는 다음 단어에 필드의 더 큰 부분을 저장할 수 있습니다.

  • 비트 필드는 이름이 지정되지 않은 비트 필드일 수 있으며, 이 경우 채우기 또는 위치 조정에만 사용됩니다. 이름이 없는 비트 필드는 사용할 수 없습니다. 예:

    struct k{    int a:1;    int  :2;    /* 该 2 位不能使用 */    int b:3;    int c:2;};

위의 분석에서 볼 수 있듯이 비트 필드는 본질적으로 구조 유형이지만 해당 멤버는 이진 용어로 할당됩니다.

비트 필드 사용

비트 필드 사용은 구조체 멤버 사용과 동일합니다. 일반적인 형식은 다음과 같습니다.

    位域变量名·位域名

비트 필드를 사용하면 다양한 형식으로 출력할 수 있습니다.

다음 예를 참조하세요.

main(){    struct bs{        unsigned a:1;        unsigned b:3;        unsigned c:4;    } bit,*pbit;
    bit.a=1;/* 给位域赋值(应注意赋值不能超过该位域的允许范围) */
    bit.b=7;/* 给位域赋值(应注意赋值不能超过该位域的允许范围) */
    bit.c=15;/* 给位域赋值(应注意赋值不能超过该位域的允许范围) */
    printf("%d,%d,%d\n",bit.a,bit.b,bit.c);/* 以整型量格式输出三个域的内容 */
    pbit=&bit;/* 把位域变量 bit 的地址送给指针变量 pbit */
    pbit->a=0;/* 用指针方式给位域 a 重新赋值,赋为 0 */
    pbit->b&=3;/* 使用了复合的位运算符 "&=",相当于:pbit->b=pbit->b&3,位域 b 中原有值为 7,与 3 作按位与运算的结果为 3(111&011=011,十进制值为 3) */
    pbit->c|=1;/* 使用了复合位运算符"|=",相当于:pbit->c=pbit->c|1,其结果为 15 */
    printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);/* 用指针方式输出了这三个域的值 */}

위의 예 프로그램은 비트 필드 구조 bs를 정의하고 세 개의 비트 필드는 a, b, c입니다. bs 유형의 변수 bit와 bs 유형을 가리키는 포인터 변수 pbit에 대해 설명합니다. 즉, 비트필드도 포인터를 사용할 수 있습니다.