结构体 让不同类型的数据成员集合到一起并隶属于一个大的内存块,各数据成员以结构体变量名为基准,用成员名称来偏移可以找到各自的小内存块首地址并按各自的数据类型的编码方案(encoding scheme)和填充规则确定各自的内存空间。

结构体成员可以是基本数据类型、其它结构体类型变量(或指针),自身结构体指针(因为指针的内存大小都是统一的,不能是自身结构体类型变量,因为其大小会形成自身循环迭代计算)。

结构体类型就像俄罗斯套娃,包装嵌套,让数据有了更大的颗粒度。访问数据成员时就像剥洋葱,从外入内,层层深入。

1 结构体嵌其它结构体

Members of a struct can be any type.

结构的成员可以是任何类型。

Members of a struct can themselves be structs.

结构 的成员本身可以是结构。

The members are implemented as part of the block of memory.

成员作为内存块的一部分实现。

Use dot notation to access a member struct, then use dot notation again to access that member’s structs

使用点符号访问成员结构,然后再次使用点符号访问该成员的结构。

Use nested {} for initialization .

使用嵌套{}进行初始化。

 # include  <stdio.h>
 typedef  struct {
    int x; int y;
} Point;
typedef struct {
    Point start; Point end;
} Line;
int main()
{
    Line lnA = {{4, 7}, {9, 11} };
    Line lnB = {1,2,3,4};
     printf ("start vertex: %d, %d\n", 
        lnA.start.x, lnA.start.y );
    
    printf("end vertex: %d, %d\n", 
        lnB.end.x, lnB.end.y );   
    get char ();
}
  

图示:

demo code 2:

 #include <stdio.h>
struct Point{
    double x;
    double y;
};
struct  Rectangle  {
    Point corner;
    double width, height;
};
int main()
{
    Point corner = { 0.0, 0.0 };
    Rectangle box = { corner, 100.0, 200.0 };
    box.width += 50.0;
     cout  << box.height << endl;
    
    Point temp = box.corner;
    double x = temp.x;
    
    double x = box.corner.x;
    getchar();
}
  

图示:

2 Various ways a struct variable can be initialized(初始化结构变量的各种方法)
 #include <stdio.h>
typedef struct {
    int x; int y;
} Point;
typedef struct {
    Point start; Point end;
} Line;
int main()
{
    Line lnA = {{4, 7}, {9, 11} };
    
    Point s = {4,7}, e = { 9, 11 };
    Line lnB;
    lnB.start = s;  lnB.end = e;
    
    Line lnC;
    lnC.start.x = 4; lnC.start.y = 7;
    lnC.end.x = 9; lnC.y = 11;
    
    Line lnD;
    lnD = lnA;  /* copy complete value in lnA to lnD */    
    getchar();
}  
3 Struct with pointers to Structs(结构体嵌套结构体指针)

A struct member can be a pointer to a struct.

结构成员可以是指向结构的指针。

The various structs might not be contiguous in memory.

各种结构在内存中可能不连续。

Usually this is done to save memory and speed access if the structs are big.

如果结构很大,通常这样做是为了节省内存和加快访问速度。

 #include <stdio.h>
typedef struct {
    int x; int y;
} Point;
typedef struct {
    Point *start; Point *end;
} NewLine;
int main()
{
    Point s = {4,7}; 
    Point e = { 9, 11 };
    NewLine newLN;
    newLN.start = &s
    newLN.end   = &e
    printf( "start: %d, %d\n", newLN.start->x, newLN.start->y );
    
    s.x = 99; s.y = 77;
    printf( "start: %d, %d\n", newLN.start->x, newLN.start->y );
    
    getchar();
}  

图示:

4 结构体嵌套数组可以整体赋值
 #include <stdio.h>
struct str{
    char a[128];
};

int main()
{
    char ss[4];
    //ss = "123"; // left operand must be l-value, ss is const
    struct str s = {"123"};
    printf("%s",s.a);
    getchar();
}  
5 Self-referential Struct(自引用结构)

A struct member can be a pointer to the same type of struct

结构成员可以是指向相同类型结构的指针

Since the C compiler is one-pass, a TAG must be used to designate the struct being defined.

由于C编译器是一次扫描,因此必须使用标记来指定要定义的结构。

 #include <stdio.h>
typedef struct NODE
{
    struct NODE *link; /* ptr to a NODE */    int value; 
} Node;

 void  main (void)
{  
    Node a, b, c;
    a.value = 1; b.value = 2; c.value = 3;
    a.link = &b    /* node a points to node b */    b.link = &c    /* node b points to node c */    c.link = NULL;  /* c points nowhere */    printf("%d %d %d\n", a.value, a.link->value, a.link->link->value );
    
    getchar();
}  

-End-