当前位置:   article > 正文

C语言从头学38——struct 结构体的嵌套

C语言从头学38——struct 结构体的嵌套

1、struct结构体的嵌套
       所谓struct嵌套,就是一个 struct 结构是另一个 struct 结构的成员(属性),这种嵌套可能会有多层。先说嵌套 struct 结构的声明,如果把嵌套结构体外结构称为父结构体,在内部的结构体称为子结构体的话,那声明顺序就是先声明儿子,再声明老子。给嵌套结构体变量的赋值也是同样的顺序,先给子结构体变量赋值,然后再将赋值已毕的子结构体赋给赋值给父结构体。赋值或者显示过程中,从父结构体变量到子结构体变量最后到内置类型变量靠的是一系列点 ".",如果是指针变量就是 "->" 。
      用一个小程序说明上述步骤:

  1. #include<stdio.h>
  2. int main(void)
  3. {
  4. //定义子结构体——教师
  5. typedef struct
  6. {
  7. char name[32];
  8. char course[64];
  9. } Teacher;
  10. //定义子结构体——学生
  11. typedef struct
  12. {
  13. char name[32];
  14. char class[32];
  15. } Student;
  16. //定义父结构体——学校
  17. typedef struct
  18. {
  19. Teacher teacher[20];
  20. Student student[100];
  21. } School;
  22. //声明父结构体变量
  23. School school;
  24. //声明子结构体变量并赋值
  25. Teacher t1 = { "张老师","数学" }, t2 = { "王老师","语文" };
  26. Student s1 = { "李四","一班" }, s2 = { "赵五","一班" }, s3 = { "刘七","二班"};
  27. //这里如不是使用{ }法赋值,则需使用strcpy函数。t1.name="xxx"不可以。
  28. //将已赋值子结构体变量赋值给父结构体
  29. school.teacher[0] = t1;
  30. school.teacher[1] = t2;
  31. school.student[0] = s1;
  32. school.student[1] = s2;
  33. school.student[2] = s3;
  34. //访问嵌套结构体(使用多个圆点)
  35. for (int i = 0; i < 2; i++)
  36. {
  37. printf("教师姓名:%s 负责课程:%s\n", school.teacher[i].name,school.teacher[i].course);
  38. }
  39. for (int j = 0; j < 3; j++)
  40. {
  41. printf("学生姓名:%s 所在班级:%s\n", school.student[j].name, school.student[j].class);
  42. }
  43. getchar();
  44. return 0;
  45. }

运行结果:
      教师姓名:张老师 负责课程:数学
      教师姓名:王老师 负责课程:语文
      学生姓名:李四 所在班级:一班
      学生姓名:赵五 所在班级:一班
      学生姓名:刘七 所在班级:二班
2、struct结构体的自嵌套
       “从前有个山,山上有座庙,庙里有个老和尚,老和尚正在讲故事,故事说,从前有座山,山上有座庙,庙里有个老和尚。。。”,这种结构就是自套结构。结构体也可以写成这样的形式,即结构体内部某个属性是自我引用(引用当前结构自身)。
       语言描述容易让人糊涂,还是先看一个例子,再分析这种结构的意义。

  1. #include<stdio.h>
  2. #include<stdlib.h> //malloc函数需用
  3. int main(void)
  4. {
  5. //定义自嵌套子结构体
  6. typedef struct myList
  7. {
  8. int Num; //数据
  9. struct myList* pNum; //指向下一级结构的指针
  10. } mylist;
  11. //给父结构变量赋值
  12. //内部指针赋值要指向子结构变量
  13. mylist* father = malloc(sizeof(mylist));
  14. //此处声明成指针型结构体变量的目的,是为了遍历时可以通过移动指针方式找到下一个嵌套结构体变量
  15. if (father == NULL) return 0;
  16. father->Num = 1000;//父结构变量赋值1000
  17. father->pNum = malloc(sizeof(mylist)); //父结构指针指向为子结构变量申请的内存空间
  18. if (father->pNum == NULL) return 0; //遇有malloc分派内存时,应做分派失败检查
  19. //给子结构变量赋值
  20. //父结构已经匿名为子结构申请了内存空间,可以直接使用
  21. father->pNum->Num = 2000;//子结构变量赋值2000
  22. father->pNum->pNum= malloc(sizeof(mylist)); //子结构指针指向为孙结构变量申请内存空间
  23. if (father->pNum->pNum == NULL) return 0;
  24. //给孙结构变量赋值
  25. father->pNum->pNum->Num = 3000; //为孙结构变量赋值3000
  26. father->pNum->pNum->pNum = NULL; //不再要重孙子
  27. //遍历三重自嵌套结构体变量
  28. for (mylist* p = father; p != NULL; p = p->pNum)
  29. {
  30. printf("父、子、孙结构的数据:%d\n",p->Num);
  31. }
  32. getchar();
  33. return 0;
  34. }

运行结果:
       父、子、孙结构的数据:1000
       父、子、孙结构的数据:2000
       父、子、孙结构的数据:3000
        从上面程序运行的结果可以看出,尽管1000、2000、3000分别在三个结构体变量中,在内存中的位置也不相邻,但却可以很容易的通过移动指针的方式依次找到下一个数据,与数组有了异曲同工之妙。实际上,上面程序所展示的数据结构,就是最为简单的链表形式,它为管理相对位置频繁变动的数据提供了方法。与数组牵一发而动全身相比,链表优势明显。
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/901055
推荐阅读
相关标签
  

闽ICP备14008679号