C構造
C 配列を使用すると、同じ型のデータ項目を格納できる変数を定義できます。構造 は、C プログラミングで使用できる別のユーザー定義のデータ型であり、異なるタイプのデータ項目を格納できます。
構造体はレコードを表すために使用されます。図書館内の書籍の動態を追跡するとします。場合によっては、各書籍の次のプロパティを追跡する必要があります。件名
-
書籍ID
構造を定義する
構造を定義するには、structステートメントを使用する必要があります。 struct ステートメントは、複数のメンバーを含む新しいデータ型を定義します。 struct ステートメントの形式は次のとおりです。
struct [structure tag]{ member definition; member definition; ... member definition;} [one or more structure variables];
構造タグ はオプションであり、各メンバーの定義は int i や float f などの標準変数定義です。 ; または他の有効な変数定義。構造体定義の最後、最後のセミコロンの前で、オプションで 1 つ以上の構造体変数を指定できます。 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
ビット フィールド
一部の情報は、保存時に完全なバイトを占める必要はなく、数ビットまたは 1 バイナリ ビットだけを占める必要があります。たとえば、スイッチ値を保存する場合、状態は 0 と 1 の 2 つだけなので、1 ビットのバイナリを使用できます。 C言語では、記憶容量を節約し、処理を容易にするために、「ビットフィールド」または「ビットセグメント」と呼ばれるデータ構造が提供されています。
いわゆる「ビットフィールド」は、バイト内のバイナリビットをいくつかの異なる領域に分割し、各領域のビット数を指定するものです。各ドメインにはドメイン名があり、プログラム内でドメイン名による操作が可能です。このようにして、いくつかの異なるオブジェクトを 1 バイトのバイナリ ビット フィールドで表すことができます。
典型的な例:
1 ビットのバイナリを使用してスイッチ値を保存する場合、状態は 0 と 1 の 2 つだけです。
外部ファイル形式を読み取る - 標準以外のファイル形式を読み取ることができます。例: 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 は 2 番目のバイトから始まり 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 を定義しており、3 つのビット フィールドは a、b、c です。 bs型の変数bitとbs型を指すポインタ変数pbitを記述します。これは、ビットフィールドでもポインターを使用できることを意味します。