zoukankan      html  css  js  c++  java
  • 结构体和它在链表中的使用

    一.结构体

    由不同类型的数据组合成一个整体,以便引用,这些组合在一个整体中的数据是互相联系的。

    1.1如何声明结构体呢?

    struct 结构体名  //结构体名字用作结构体类型的标志

    {成员列表};    

    比如:

    1 struct student
    2 {
    3   int num;  //2
    4   char name[20];  //20
    5   char sex;  //1
    6   int age;  //2
    7   float score;  //4
    8   char addr[30];  //30
    9 };

    注意:声明只是指定了一个结构体类型,它相当于一个模型,但其中并无具体数据,系统对之也不分配实际内存单元。为了能在程序中使用结构类型的数据,应当定义结构体类型的变量....

    1.2如何定义结构体变量呢?

    方法一:可以在声明的同时定义。在第9行分号前面添加 “student1,student2” 即可表明,student1和student2就是student结构体的两个变量。在定义了结构体变量后,系统会为之自动分配内存,上述就分配了59个字节。

    一般形式为:

    struct 结构体名

    {

     成员表列

    }变量名表列;

    方法二:直接定义结构类型变量。此形式不出现结构体名!

    一般形式为:

    struct 

    {

      成员表列

    }变量名表列;

    此处特别强调:类型和变量的区别,变量能进行赋值、存取、和运算,但是类型不行。在编译时,类型是不分配空间的,只能对变量分配空间。所以,对结构体里面的各个的成员可都以单元使用,因为它是有内存的。那么怎么去用结构体里面的成员呢?接下来就告诉你!

    方法3:在已经声明/定义了结构体类型时,利用了类型名称定义结构体变量!

    struct student student1;  //student1是变量名;struct student 是变量类型名称

    1.3如何使用结构体成员变量

     1 #include <stdio.h>
     2 struct student
     3 {
     4   long int num;
     5   char name[20];
     6   char sex;
     7   char addr[30];
     8 }a = {89031, "Li Lin", 'M', "123 Beijing Road"};    //定义了结构体变量,并给予赋值
     9 void main()
    10 {
    11   printf("NO. : %d
    name: %s
    sex: %c
    address: %s
    ", a.num, a.name, a.sex, a.addr) //输出结构体成员的值
    12 }

    但是需要注意以下几点:

    (1)不能将一个结构体变量作为一个整体进行输入和输出,只能对结构体变量在的各个成员分别进行输入输出!

      引用结构体变量中成员方式:  结构体变量.成员名称

    若p是指向 结构体类型(student) 的指针,也可以这样表示成员      (*)p.age    也可以p->age

    故,以上三种表达成员的方式均是等价的!

    附:->是指向运算符

      p -> n 得到 p 指向的结构体变量中的成员 n 的值

      p -> n ++ 得到 p 指向的结构体变量中的成员 n 的值,用完值后使它加1

      ++p -> n 得到 p 指向的结构体变量中的成员 n 的值使之加 1 (先加)

    (2)如果成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级地找到最低一级的成员,只能对最低级的成员进行运算、赋值!

      结构体变量.结构体中的结构体名称.成员名称

    附:   .是优先级最高的运算符

    1.4结构体数组

    定义方法:(1)struct student stu[3];

    (2)在结构体最后,分号之前加入数组,如stu[4]  

    (3)

    -----类似定义结构体变量,只不过是变量是一个数组形式存在而已

    赋值方式:(举个例子)

     1 struct student
     2   {
     3     int mum;
     4     char name[20];
     5     char sex;
     6     int ag;
     7     float score;
     8     char addr[30];
     9   }stu[3] = {{10101,"Li Lin", 'M', 18, 87.5, "103 Beijing Road"},
    10         {10101,"Li Lin", 'M', 18, 87.5, "103 Beijing Road"},
    11        {10101,"Li Lin", 'M', 18, 87.5, "103 Beijing Road"}};

      定义数组 stu 时,元素个数可以不指定,即写成以下形式:

       stu[] = {{...},{...},{...}};

    综上,举一个例子:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stlib.h>
     4 
     5 struct person
     6 {
     7   char name[20];
     8   int count;
     9 }leader[3] = {{"Li", 0},
    10        {"Zhang", 0},
    11        {"Fun", 0}};
    12 
    13 void main()
    14 {
    15   int i, j;
    16   char leader_name[20];
    17   for(i = 1; i<= 10;i++)
    18   {
    19     scanf("%s", leader_name);
    20     for(j=0;j<3;j++)
    21       if(strcmp(leader_name, leader[j].name) == 0)
    22         leader[j].count ++;
    23   }
    24   printf("
    ");
    25   for(i=0;i<3;i++)
    26   printf("%5s: %d
    ", leader[i].name, leader[i].count);
    27   system("pause");
    28 }

    二、typedef  struct的用法

     (此部分转载自http://www.cnblogs.com/st-moon/p/5588321.html)

    typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。

    在编程中使用typedef目的一般有两个,一个是给变量一个易记且意义明确的新名字,另一个是简化一些比较复杂的类型声明。

    第一种  上面第二种用法前面直接加typedef

    typedef struct student{

      char name[20];

      int age;

      char class;

    }student_1;

    这语句实际上完成两个操作:
    1) 定义一个新的结构类型

    struct student{

      char name[20];

      int age;

      char class;

    };
    2) typedef为这个新的结构起了一个名字,叫student_1。
    typedef struct student student_1; (对比typedef int student_1来进行理解)
      因此,student_1实际上相当于struct student,这样定义一个变量的时候,既可以用struct student aaa,也可以用student_1 aaa。student_1成了一个数据类型。

    如果有逗号,比如

    typedef struct student{

      char name[20];

      int age;

      char class;

    }student_1,student_2;

    可以先理解成

    struct student{

      char name[20];

      int age;

      char class;

    }student_1;

    struct student{

      char name[20];

      int age;

      char class;

    }student_2;

    这样再加上typedef,同上分析,也就是说struct student有两个别名,分别是student_1和student_2,都可以代替struct student定义变量。也就是说有三种用法,struct student aaa;student_1 aaa;student_2 aaa都是等价的。

    第二种  上面第三种用法前面直接加typedef

    typedef struct {

      char name[20];

      int age;

      char class;

    }student_1;

    根据唯一性,即定义变量的时候只能是student_1 aaa;

    三、链表

    是一种动态的存储分配结构。

    1   struct student
    2   {
    3     int num;
    4     float score;
    5     struct student *next;
    6   };

    链表含有一个头指针变量,它存放一个地址,该地址指向一个元素,链表中每一个元素称为结点。

    结点包含两部分:用户需要用的实际数据、下个结点的地址!存放下一个地址的叫作 头指针 (head).....当然,最后表尾的地址是NULL(空地址)

     以下实现建立和输出一个简单的链表:

    #include <stdio.h>
    
    #include <stdlib.h>
    #define NULL 0
    struct student
    {
      long num;
      float score;
      struct student *next;
    };
    void main()
    {
      struct student a, b, c, *head, *p;
      a.num = 99101; a.score = 89.5;
      b.num = 99103; b.score = 90;
      c.num = 99107; c.score = 85;//对结点的 num 和 score 成员赋值
      head = &a;//将结点 a 的起始地址赋给头指针 head
      a.next = &b;//将结点 b 的起始地址赋给 a 结点的 next 成员
      b.next = &c;
      c.next = NULL;// c 结点的 next 成员不存放其他结点地址
      p = head;//使 p 指针指向 a 结点
      do
      {
        printf("%ld %5.1f
    ", p->num, p->score);// 输出 p 指向的结点的数据
        p = p->next;//使 p 指向下一结点
      }while(p != NULL);//输出完 c 结点后 p 的值为 NULL
      system("pause");
    }
    
    运行结果
    
    99101  89.5
    99103  90.0
    99107  85.0

    3.1动态链表所需的函数

     (1)malloc 函数

      void *malloc(unsigned int size);

      作用是在内存的动态存储区中分配一个长度为 size 的连接空间。些函数的值(即返回值)是一个指向分配空间起始地址的指针(基类型为 void)。如果些函数未能成功地执行(例如内存空间不足)则返回空指针 NULL。

      (2)calloc 函数

      void *calloc(unsigned n, unsigned size);

      其作用是在内存的动态区存储中分配 n 个长度为 size 的连续空间。函数返回一个指向分配空间起始地址的指针,如果分配不成功,返回 NULL。

      用 calloc 函数可以为一维数组开辟动态存储空间, n 为数组元素个数,每个元素长度为 size。  

      (3)free 函数

      void free(void *p);

      其作用是释放由 p 指向的内存区,使这部分内存区能被其它变量使用, p 是最后一次调用 calloc 或 malloc 函数时返回的值。free 函数无返回值。

      请注意:以前的C版本提供的 malloc 和 calloc 函数得到的是指向字符型数据的指针。ANSI C 提供的 malloc 和 calloc 函数规定为 void * 类型。

    例:动态表的建立

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #define NULL 0
      5 #define LEN sizeof(struct student)
      6

    7 struct student      //声明结构体 8 { 9   long num; 10   float score; 11   struct student *next; 12 }; 13 14 struct student *create()  //创建结构体,create是指向这个结构体的指针 15 { 16   struct student *p1, *p2, *head; 17   int num; 18   float score; 19   int n = 0; 20 21   head = NULL; 22 23   p1 = p2 = (struct student *)malloc(LEN); 24 25   printf("please input num and score. "); 26   scanf("%d,%f", &p1->num, &p1->score); 27 28   while(p1->num != 0) 29   { 31     n ++; 32     if(n == 1) 33       head = p1; 34     else 35       p2->next = p1; 36     p2 = p1; 37     p1 = (struct student *)malloc(sizeof(struct student)); 38     printf("please input num and score. "); 39     scanf("%d,%f", &p1->num, &p1->score); 40   } 41   p2->next = NULL; 42   return head; 43 } 44 45 void printlist(struct student *head) 46 { 47   struct student *p; 48   p = head; 49 50   if(head != NULL) 51   { 52     do 53     { 54       printf("num=%d score=%f ", p->num, p->score); 55       p = p->next; 56 57     }while(p != NULL); 58   } 59 } 60 61 void main() 62 { 63   struct student *head; 64   head = create(); 65   printlist(head); 66   system("pause"); 67 } 68 69 以下是对链表的各种操作 70 71 //打印链表 73 void printlist(struct student *head) 74 { 75 struct student *p; 76 p = head; 77 78 if(head != NULL) 79 { 80 do 81 { 82 printf("num=%d score=%5.2f ", p->num, p->score); 83 p = p->next; 84 } while (p != NULL); 85 } 86 /* while(p -> next != NULL) 87 { 88 printf("num=%d score=%f ", p->num, p->score); 89 p = p->next; 90 }*/ 91 } 92 93 //删除节点 95 struct student *delNode(struct student *head, int num) 96 { 97 printf("delNode. "); 98 struct student *p1, *p2; 99 if(head == NULL) 100 { 101 printf("The List is NULL. "); 102 } 103 else 104 { 105 p1 = head; 106 while(p1->next != NULL && p1->num != num) 107 { 108 p2 = p1; 109 p1 = p1->next; 110 } 111 if(p1->num == num) 112 { 113 if(p1 == head) 114 head = p1->next; 115 else 116 p2->next = p1->next; 117 } 118 else 119 printf("Can not find list num. "); 120 } 121 return head; 122 } 123 124 //更新节点 126 struct student *update(struct student *head, int index, int num, float score) 127 { 128 printf("update. "); 129 struct student *p; 130 if(head == NULL) 131 { 132 printf("The List is NULL. "); 133 } 134 else 135 { 136 p = head; 137 while(p->next != NULL && p->num != index) 138 { 139 p = p->next; 140 } 141 if(p->num == index) 142 { 143 p->num = num; 144 p->score = score; 145 } 146 else 147 printf("Can not find list index. "); 148 } 149 return head; 150 } 151 152 //增加节点 153 154 struct student *add(struct student *head, int index, int num, float score) 155 { 156 printf("add. "); 157 struct student *p1, *p2, *p3; 158 if(head == NULL) 159 { 160 printf("The List is NULL. "); 161 } 162 else 163 { 164 p1 = p2 = head; 165 while(p1->next != NULL && p1->num != index) 166 { 167 p1 = p1->next; 168 p2 = p1; 169 } 170 if(p1->num == index) 171 { 172 p3 = (struct student *)malloc(LEN); 173 p3->num = num; 174 p3->score = score; 175 176 if(p2->next == NULL) 177 { 178 p2->next = p3; 179 p3->next = NULL; 180 } 181 else 182 { 183 p3->next = p2->next; 184 p2->next = p3; 185 } 186 } 187 else 188 printf("Can not find list index. "); 189 } 190 return head; 191 }
  • 相关阅读:
    Elasticsearch6.x和7.x版本常用插件汇总
    阿里巴巴JAVA开发规范学习笔记
    jQuery学习和知识点总结归纳
    MySQL常用维护命令和操作
    MySQL知识点系统总结
    HTML基础知识自学教程
    最值得拥有的免费Bootstrap后台管理模板
    强烈推荐优秀的Vue UI组件库
    再次学习Git版本控制工具
    Linux下Apache虚拟主机配置
  • 原文地址:https://www.cnblogs.com/simonLiang/p/5747839.html
Copyright © 2011-2022 走看看