English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C语言结构体(struct)

In this tutorial, you will learn about the structure type in C programming. You will learn to define and use structures with examples.

In C programming, sometimes you need to store multiple properties of entities. Entities do not have to have all information of one type. They can have different properties of different data types.

C arrays allow you to define variables that can store items of the same type.structureis another user-defined data type available in C programming, which allows you to store different types of data items.

The structure is used to represent a record, assuming you want to track the dynamics of books in a library, you may need to track the following properties of each book:

  • Title

  • Author

  • Subject

  • Book ID

Define structure

To define a structure, you must use struct keyword. The struct statement defines a new data type containing multiple members, the format of the struct statement is as follows:

struct tag { 
    member-list
    member-list 
    member-list  
    ...
}

tag is the structure tag.

member-list is a standard variable definition, such as int i; or float f, or other valid variable definitions.

variable-list Structure variables, defined at the end of the structure, before the last semicolon, you can specify one or more structure variables. Here is how to declare the Book structure:

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

In general,tag, member-list, variable-list These 3 parts must appear at least 2 times. Here is an example:

//This declaration declares a structure with 3 members, namely an integer a, a character b, and a double precision c
//And also declares a structure variable s1
//This structure does not specify its tag
struct 
{
    int a;
    char b;
    double c;
}
 
//This declaration declares a structure with 3 members, namely an integer a, a character b, and a double precision c
//结构体的标签被命名为SIMPLE,没有声明变量
struct SIMPLE
{
    int a;
    char b;
    double c;
};
//用SIMPLE标签的结构体,另外声明了变量t1、t2、t3
struct SIMPLE t1, t2[20], *t3;
 
//也可以用typedef创建新类型
typedef struct
{
    int a;
    char b;
    double c; 
} Simple2;
//现在可以用Simple2作为类型声明新的结构体变量
Simple2 u1, u2[20], *u3;

在上面的声明中,第一个和第二声明被编译器当作两个完全不同的类型,即使他们的成员列表是一样的,如果令 t3=&s1,则是非法的。

结构体的成员可以包含其他结构体,也可以包含指向自己结构体类型的指针,而通常这种指针的应用是为了实现一些更高级的数据结构如链表和树等。

//此结构体的声明包含了其他的结构体
struct COMPLEX
{
    char string[100];
    struct SIMPLE a;
};
 
//此结构体的声明包含了指向自己类型的指针
struct NODE
{
    char string[100];
    struct NODE *next_node;
};

如果两个结构体互相包含,则需要对其中一个结构体进行不完整声明,如下所示:

struct B; //对结构体B进行不完整声明
 
//结构体A中包含指向结构体B的指针
struct A
{
    struct B *partner;
    //other members;
};
 
//结构体B中包含指向结构体A的指针,在A声明完后,B也随之进行声明
struct B
{
    struct A *partner;
    //other members;
};

结构体变量的初始化

和其它类型变量一样,对结构体变量可以在定义时指定初始值。

#include <stdio.h>
 
struct Books
{
   char title[50];
   char author[50];
   char subject[100];
   int book_id;
} book = {"C 语言", "w3codebox", "编程语言", 123456};
 
int main()
{
    printf("书名: %s\n作者: %s\n主题: %s\nBookID %d\n", book.title, book.author, book.subject, book.book_id);
}

执行输出结果为:

书名: C 语言
作者: w3codebox
主题: 编程语言
BookID 123456

访问结构成员

To access the members of the structure, we usemember access operator (.). The member access operator is a period between the structure variable name and the structure member we want to access. You can use struct Keywords are used to define variables of structure types. The following example demonstrates the usage of structures:

#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,类型为 Books */
   struct Books Book2; /* 声明 Book2,类型为 Books */
 
   /* Book1 详细说明 */
   strcpy( Book1.title, "C 编程语言");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C 编程语言教程");
   Book1.book_id = 6495407;
 
   /* Book2 详细说明 */
   strcpy( Book2.title, "JAVA编程语言");
   strcpy( Book2.author, "Seagull Ali");
   strcpy( Book2.subject, "JAVA编程语言教程");
   Book2.book_id = 6495700;
 
   /* Output information of Book1 */
   printf( ". ", Book1.title);
   printf( ". ", Book1.author);
   printf( ". ", Book1.subject);
   printf( ". ", Book1.book_id);
 
   /* Output information of Book2 */
   printf( ". ", Book2.title);
   printf( ". ", Book2.author);
   printf( ". ", Book2.subject);
   printf( ". ", Book2.book_id);
 
   return 0;
}

Quando il codice sopra viene compilato ed eseguito, produrrà i seguenti risultati:

Book 1 title: C programming language
Book 1 author: Nuha Ali
Book 1 subject: C programming language tutorial
Book 1 number: 6495407
Book 2 title: JAVA programming language
Book 2 author: Seagull Ali
Book 2 subject: JAVA programming language tutorial
Book 2 number: 6495700

Structure as a function parameter

You can pass the structure as a function parameter, in the same way as other types of variables or pointers. You can use the method in the above example to access the structure variable:

#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,类型为 Books */
   struct Books Book2; /* 声明 Book2,类型为 Books */
 
   /* Book1 详细说明 */
   strcpy( Book1.title, "C 编程语言");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C 编程语言教程");
   Book1.book_id = 6495407;
 
   /* Book2 详细说明 */
   strcpy( Book2.title, "JAVA编程语言");
   strcpy( Book2.author, "Seagull Ali");
   strcpy( Book2.subject, "JAVA编程语言教程");
   Book2.book_id = 6495700;
 
   /* Output information of Book1 */
   printBook( Book1 );
 
   /* Output information of Book2 */
   printBook( Book2 );
 
   return 0;
}
void printBook( struct Books book );
{
   printf( ". ", book.title);
   printf( ". ", book.author);
   printf( ". ", book.subject);
   printf( ". ", book.book_id);
}

Quando il codice sopra viene compilato ed eseguito, produrrà i seguenti risultati:

Titolo del libro: Linguaggio di programmazione C
Autore del libro: Nuha Ali
Argomento del libro: Manuale di programmazione in C
Numero del libro: 6495407
Titolo del libro: Linguaggio di programmazione JAVA
Autore del libro: Seagull Ali
Argomento del libro: Manuale di programmazione in JAVA
Numero del libro: 6495700

Puntatore alla struttura

È possibile definire un puntatore alla struttura in modo simile a come si definisce un puntatore a variabili di altri tipi, come indicato di seguito:

struct Books *struct_pointer;

Ora, è possibile memorizzare l'indirizzo della variabile di struttura nel variabile di puntatore definita sopra. Per trovare l'indirizzo della variabile di struttura, mettete l'operatore & davanti al nome della struttura, come indicato di seguito:

struct_pointer = &Book1;

Per accedere ai membri della struttura tramite un puntatore alla struttura, è necessario utilizzare l'operatore ->, come indicato di seguito:

struct_pointer->title;

Usiamo i puntatori a struttura per riscrivere l'esempio precedente, il che aiuterà a comprendere il concetto di puntatore a struttura:

#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,类型为 Books */
   struct Books Book2; /* 声明 Book2,类型为 Books */
 
   /* Book1 详细说明 */
   strcpy( Book1.title, "C 编程语言");
   strcpy( Book1.author, "Nuha Ali"); 
   strcpy( Book1.subject, "C 编程语言教程");
   Book1.book_id = 6495407;
 
   /* Book2 详细说明 */
   strcpy( Book2.title, "JAVA编程语言");
   strcpy( Book2.author, "Seagull Ali");
   strcpy( Book2.subject, "JAVA编程语言教程");
   Book2.book_id = 6495700;
 
   /* 通过传 Book1 的地址来输出 Book1 信息 */
   printBook( &Book1 );
 
   /* 通过传 Book2 的地址来输出 Book2 信息 */
   printBook( &Book2 );
 
   return 0;
}
void printBook(struct Books *book)
{
   printf("Titolo del libro: %s\n", book->title);
   printf("Autore del libro: %s\n", book->author);
   printf("Argomento del libro: %s\n", book->subject);
   printf("Numero del libro: %d\n", book->book_id);
}

Quando il codice sopra viene compilato ed eseguito, produrrà i seguenti risultati:

Titolo del libro: Linguaggio di programmazione C
Autore del libro: Nuha Ali
Argomento del libro: Manuale di programmazione in C
Numero del libro: 6495407
Titolo del libro: Linguaggio di programmazione JAVA
Autore del libro: Seagull Ali
Argomento del libro: Manuale di programmazione in JAVA
Numero del libro: 6495700

Campo bit

Alcune informazioni, durante la memorizzazione, non richiedono di occupare un byte completo, ma solo alcuni o un bit binario. Ad esempio, quando si memorizza una variabile di commutazione, ci sono solo due stati: 0 e 1, che possono essere memorizzati con un bit binario. Per risparmiare spazio di archiviazione e semplificare il processo di elaborazione, il linguaggio C fornisce una struttura dati chiamata "campo bit" o "segmento bit".

Il cosiddetto "campo bit" è dividere i bit di un byte in diverse aree e specificare il numero di bit di ciascuna area. Ogni dominio ha un nome dominio, che consente di operare secondo il nome dominio nel programma. In questo modo, si può rappresentare diversi oggetti con un campo bit binario di un byte.

Esempio tipico:

  • Quando si utilizza un bit binario per memorizzare una variabile di commutazione, ci sono solo due stati: 0 e 1.

  • Formato di lettura del file esterno - può leggere formati di file non standard. Ad esempio: numero intero di 9 bit.

La definizione dei campi bit e la descrizione delle variabili dei campi bit

La definizione dei campi bit è simile alla definizione delle strutture, e la sua forma è:

struct Nome_struttura_bit 
{
 Lista dei campi bit
};

La forma della lista dei campi bit è la seguente:

Simbolo di tipo - Nome del campo bit: - Lunghezza del campo bit

Ad esempio:

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

L'indicazione data è per il variabile bs, che occupa due byte. Tra cui il campo a occupa 8 bit, il campo b occupa 2 bit, il campo c occupa 6 bit.

Lasciamo ora un altro esempio:

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;

In questo caso, packed_struct contiene 6 membri: quattro identificatori a 1 bit f1..f4, un tipo a 4 bit e un my_int a 9 bit.

Per la definizione dei campi bit ci sono anche alcune spiegazioni come segue:

  • Un campo bit viene memorizzato nello stesso byte, se lo spazio rimanente in un byte non è sufficiente per memorizzare un altro campo bit, il campo bit verrà memorizzato a partire dal prossimo unità. Può anche essere intenzionalmente fatto in modo che un campo bit inizi a partire dal prossimo unità. Ad esempio:

    struct bs{
        unsigned a:4;
        unsigned :4; /* Spazio vuoto */
        unsigned b:4; /* Comincia dal prossimo unità */
        unsigned c:4
    }

    In questa definizione del campo bit, a occupa i 4 bit del primo byte, i successivi 4 bit sono riempiti con 0 per indicare che non vengono utilizzati, b inizia dal secondo byte e occupa 4 bit, c occupa 4 bit.

  • Poiché i campi bit non consentono di superare due byte, la lunghezza dei campi bit non può essere superiore alla lunghezza di un byte, ossia non può superare 8 bit binari. Se la lunghezza massima è superiore alla lunghezza del numero intero del computer, alcuni compilatori potrebbero permettere l'overlapping della memoria dei campi, altri potrebbero memorizzare la parte superiore di un campo nel prossimo word.

  • I campi bit possono essere campi bit anonimi, in questo caso servono solo come riempimento o per l'adattamento della posizione. I campi bit anonimi non possono essere utilizzati. Ad esempio:

    struct k{
        int a:1;
        int :2; /* Questi 2 bit non possono essere utilizzati */
        int b:3;
        int c:2;
    };

Da quanto sopra si può vedere che i campi bit, in natura, sono un tipo di struttura, ma i suoi membri sono assegnati in modo binario.

L'uso dei campi bit

L'uso dei campi bit e l'uso dei membri della struttura sono gli stessi, e la sua forma generale è:

Nome del campo bit.Nome del campo bit
Nome del campo bit->Nome del campo bit

I campi bit consentono di essere visualizzati in vari formati.

Vediamo un esempio di seguito:

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; /* Ha inviato l'indirizzo della variabile bit al variabile puntatore pbit */
    pbit->a=0; /* Ha reimpostato il valore del campo bit a 0 tramite il metodo del puntatore */
    pbit->b&=3; /* Ha utilizzato l'operatore di bit composto "&=" che è equivalente a: pbit->b=pbit->b&3, il valore originale del campo bit b è 7, e il risultato dell'operazione bitwise AND con 3 è 3 (111&011=011, valore decimale 3) */
    pbit->c|=1; /* Ha utilizzato l'operatore di bit composto "|=" che è equivalente a: pbit->c=pbit->c|1, il risultato è 15 */
    printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c); /* Ha esportato i valori di questi tre campi con il metodo del puntatore */
}

Nel programma dell'esempio, è stato definito la struttura di bit域 bs, con tre bit域 a, b, c. Si mostra che i variabili di tipo bs e i puntatori a variabili di tipo bs possono essere utilizzati. Questo significa che i bit domain possono anche essere utilizzati con i puntatori.

parola chiave typedef

Usiamo la parola chiave typedef per creare alias per i tipi di dati. Di solito viene utilizzato con le strutture per semplificare la sintassi della dichiarazione delle variabili.

Questo codice

struct Distance{
    int feet;
    float inch;
};
int main() {
    struct Distance d1, d2;
}

ugualmente

typedef struct Distance{
    int feet;
    float inch;
} distances;
int main() {
    distances d1, d2;
}

strutture annidate

Puoi creare strutture all'interno delle strutture nel linguaggio C. Ad esempio:

struct complex
{
 int imag;
 float real;
};
struct number
{
   struct complex comp;
   int integers;
} num1, num2;

Supponiamo che tu voglia impostare il valore della variabile imag di num2 a 11, come si fa? Ecco un esempio:

num2.comp.imag = 11;

    Perché usare la struttura in C?

    Supponiamo che tu voglia memorizzare informazioni su una persona: il suo nome, il numero di identificazione e lo stipendio. Puoi creare variabili diverse come name, citNo e salary per memorizzare queste informazioni.

    Come gestire le informazioni di più persone? Ora, devi creare variabili diverse per ogni persona e ogni informazione: name1, citNo1, salary1, name2, citNo2, salary2, ecc.

    更好的方法是在单个名称Person结构下收集所有相关信息,并将其用于每个人。

    更多关于结构