c言語、構造体

4190 ワード


データ型は、単純データ型、構築データ型、ポインタデータ型、空型の4種類に分けられます.
構造体は構造データ型に属しstructで識別される.
構造体を宣言します:Typedef structとstruct
c
c++
typedef struct tMyStruct { int iNum; long lLength; } ST_MYSTRUCT;  
Cでは,この申明後に構造変数を申請する方法は,(1)struct tMyStruct変数名,(2)struct tMyStruct変数名,(3)struct tMyStruct(2)ST_MYSTRUCT変数名
c++には(1)struct tMyStruct変数名があり得る.(2)ST_MYSTRUCT変数名;(3)tMyStruct変数名;
typedef struct { int a; }ST_MYSTRUCT;
変数を宣言するとき:ST_MYSTRUCT  st1;
 
typedef struct { int a; }ST_MYSTRUCT,ST_MYSTRUCT_PTR;
構造体タイプST_が定義されているMYSTRUCT; および構造体ポインタタイプST_MYSTRUCT_PTR;
 
typedef struct   { int num; int age; }ST_AAA,ST_BBB,ST_CCC;
ST_AAA,ST_BBB,ST_CCCはいずれも同一構造体タイプである.変数を宣言するときはどちらでも構いませんが、c++でも同様です.
同左.
struct Student { int a ; }stu1;        
構造体タイプstruct Studioが宣言され、構造体変数stu 1も宣言されます.
 
struct { int a ; }stu1;        
構造体変数stu 1が宣言されました
 
 
  • 構造体付与:
  • struct st1 {
        int a;
        int b;
    };
    
    1      .
    1.1  {}  .
    struct st1 st1 = {1,2,3);    //           
    1.2 linux kernel  .
    struct st1 st1 = {    //           
    .a = 1;
    .b = 2;
    };
    
    2      .
    struct st1  a, b;    //       
    b = a;    //       
    
    3                    .
    struct st1 func1();
    
    struct st1 a = func1();

      
  • 構造体直接付与の不安全要因:(c言語)
  • struct A{   char v1[20];   int v2;} a,b;
    a = b;これは何の問題もない.
    ただし、struct B{char*v 1;int v 2;}c,d;c = d;このような構造体付与は,C++に含まれる注意が必要である.ポインタには、データがコピー保存されているのではなく、ポインタが1つ増えているだけで、bオブジェクトが解放されると、aのポインタは不正なゴミデータになります.
    したがって、cでは、カスタムタイプ、配列は、言語的な考慮ではなく、コードセキュリティの考慮によって、レプリケーション関数を別途定義する必要があります.
     
  • 構造体定義、宣言、付与:
  • #include <stdio.h>
    //     :
    typedef struct st1 {
        int e1;
        int e2;
    }ST_MY; //1.          ,     ,         。
    
    ST_MY func1()
    {
        ST_MY h = { 77, 88};
        return h;
    }
    
    int main()
    {
        ST_MY a = { 33, 44}; // 2.           
        ST_MY b = {
            .e1 = 55, //3.0             ,     
        }; //3.1                   
        ST_MY c;
        ST_MY d, e;
        
        c = a;//4.       (  1)
        d = func1();//5.       (  2)
        e.e2=77; //6.                .                。
        
        printf("a.e1 a.e2 is %d %d
    ", a.e1, a.e2); printf("b.e1 b.e2 is %d %d
    ", b.e1, b.e2); printf("c.e1 c.e2 is %d %d
    ", c.e1, c.e2); printf("d.e1 d.e2 is %d %d
    ", d.e1, d.e2); printf("e.e1 e.e2 is %d %d
    ", e.e1, e.e2); f1(); return 0; } /* root@oucaijun:/work/dcc# gcc *.c; ./a.out a.e1 a.e2 is 33 44 b.e1 b.e2 is 55 0 c.e1 c.e2 is 33 44 d.e1 d.e2 is 77 88 e.e1 e.e2 is -1074143256 77 //6. . 。
    */

      
  • 構造体と配列比較
  • 構造体は一等公民である.配列は二等公民である
    語条の上で解釈して2等公民と1等公民は権利の上で違いがあることを見ることができて、この語はとてもコンピュータの専門用語として面白くて、その意味も異曲同工の妙があります!同様に、ウィキペディアのコンピュータに対する用語「first-class citizen」(一等公民)の定義を見てみましょう.
  • can be stored in variables and data structures
  • can be passed as a parameter to a subroutine
  • can be returned as the result of a subroutine
  • can be constructed at run-time
  • has intrinsic identity (independent of any given name)

  • 上の定義と比較してC言語配列を見ると、
    配列が関数のパラメータとして伝達されると、ポインタに劣化する.同時に、配列は関数の戻り値として使用できません.配列をさらに不快にさせるのは、配列間で直接値を付けて操作することはできません.
    次の操作が不正である場合:int a[10];int b[10]; a = b;
    しかし配列が構造体に包装されていれば、付与できます!それに比べて、構造体は関数パラメータと戻り値として使用することができ、これは一等公民の待遇である.
    なぜ配列が二等公民でなければならないのかについては、歴史的な理由があります.C言語の発展史を参考にしてみてください.時間があれば、この内容を補充します.ソースドキュメント<http://www.cnblogs.com/hazir/p/C_struct_assignment.html>