精华内容
下载资源
问答
  • 结构体指针赋值

    万次阅读 2017-02-17 15:10:02
    //方法1:可以给p分配一段内存空间,并使其指向此空间: #include main() { struct abc{ int a;}; struct abc *p; p=(struct abc *)malloc(sizeof(struct abc)...//方法2:可以让p指向一个已存在的内存空间:#i

    //方法1:可以给p分配一段内存空间,并使其指向此空间:

    #include<stdio.h>

    main()
    {
    struct abc{
    int a;};
    struct abc *p;

    p=(struct abc *)malloc(sizeof(struct abc));
    p->a = 1;
    printf("%d\n",p->a);
    }
    
    

    //方法2:可以让p指向一个已存在的内存空间:

    #include<stdio.h>

    main()
    {
    struct abc{
    int a;};
    struct abc *p;

    struct abc temp;
    p=&temp;
    p->a = 1;
    printf("%d\n",p->a);
    }

    展开全文
  • 指向结构体的指针 在C语言中几乎可以创建指向任何类型的指针包括用户自定义的类型创建结构体指针是极常见的下面是一个例子 r是一个指向结构体的指针请注意因为r是一个指针所以像其他指针一样占用4个字节的内存而...
  • 但是遇到了无法给结构体指针赋值的问题。 <code class="language-cpp">#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #define MAXVEX 100 struct edgeNode //边表结点 {...
  • 第9章 结构体和共用体9.1 结构体【学习目标】(1)掌握结构体的类型定义方法(2)掌握定义的结构体类型变量和指针变量的引用方法(3)掌握结构体类型数组的定义及数组元素的引用实例45 结构体类型变量、指针变量的定义与...

    9  结构体和共用体

    9.1  结构体

    学习目标

    (1)掌握结构体的类型定义方法

    (2)掌握定义的结构体类型变量和指针变量的引用方法

    (3)掌握结构体类型数组的定义及数组元素的引用

    实例45  结构体类型变量、指针变量的定义与引用——我的个人信息

    实例任务】

    定义一个结构体类型,然后定义两个自定义结构体类型的变量,通过引用这两个变量输出个人信息。程序的运行结果如图9-1所示。

    fc9f0cfa59be654340da40e74ecc4a5d.png

                                 9-1  程序运行结果

    程序代码

    #include "stdio.h"

    main()

    { typedef struct

      {int num;

       char *name;

       char sex;

       float score;

      }STU;

      STU girl1, girl2,*girl3;

      /*定义结构体类型*/

    girl1.num=102;  girl1.name="lihong";

    printf("请输入性别和成绩:");

    scanf("%c%f",&girl1.sex,&girl1.score);

    girl2=girl1;

    /*可以为结构体类型的变量整体赋值*/

    girl3=&girl1;

    /*可以让结构体类型的变量指向结构体类型的变量*/

    printf("输出我的学号、姓名、性别、成绩的个人信息为:\n");

    printf("%10d%10s  %c  %.2f",girl2.num,girl2.name,girl2.sex,girl2.score);

    printf("\n通过指针变量输出我的学号、姓名、性别、成绩的个人信息为:\n");

    printf("%10d%10s  %c  %.2f",girl3->num,girl3->name,(*girl3).sex,(*girl3).score);

      }

    相关知识

    1.结构体类型的定义

    前面学过众多的类型定义符,它们的共同特点定义的变量在内存中的空间大小都是固定的。现实生活和工作中,这种单一表现有很大的局限性,结构体类型是在应用原有类型的基础上,用户构造的一种类型,其成员丰富,引用时可以整体引用。以前学过的数组在定义后所有数组元素都属同一类型,而本章所学结构体各个成员可以是不同类型。它的定义形式为:

       struct 结构体标识符

        类型名  成员变量名1;

          类型名  成员变量名2;

               ………

          类型名  成员变量名n;}

    这里,struct是定义结构体类型的关键字,结构体标识符要求是合法的C语言标识符。实例中,定义了一个记录个人信息的结构体,有num、name、sex、score这4个成员。

    2.结构体类型的变量和指针变量的定义

    结构体类型的变量定义方法有多种。可以在定义结构体的同时定义结构体类型的变量;也可以先定义结构体类型,然后再定义相应的变量;也可以通过typedef关键字先为定义的结构体类型命个新名字,再用新名字定义结构类型的变量。

    对于结构体类型的变量,定义时在内存空间中为其分配存储空间,分配时按先后顺序连续分配,所占空间总的大小为所有成员所占空间大小的和值。

    实例中,是在定义的同时,为结构体类型命个新名字STU,然后用新名字直接定义结构体类型的变量和指针变量,这样多次定义时比较简洁。

    struct  stu

    {int num;

           char *name;

           char sex;

           float score;

        }s,*p;

    以上程序段是在定义结构体类型的同时定义结构体类型的变量

       struct  stu

    {int num;

           char *name;

           char sex;

           float score;  };

       struct stu  s,*p;

    以上程序段是先定义好结构体类型,然后再单成立一条语句定义结构体类型的变量。

       struct  stu

    {int num;

           char *name;

           struct  date

              { int  year;

               int  month;

               int  day;}birthday;

           char sex;

           float score;

        }s,*p;

    以上程序段是结构体类型的嵌套定义,引用时分层引用,不可越层。

    struct  stu

        {  int num;

           char *name;

           char sex;

           float score;

            }s={101,"lihong",'F',95.5},*p;

    以上程序段是在定义结构体类型变量的同时对变量进行了初始化。

    结构体类型定义时,可以用关键字typedef为定义的结构体类型变量新命一个名字,然后可以用这个新名字来定义结构类型的变量。如实例中的如下定义形式

    typedef struct

                   {int num;

                    char *name;

                    char sex;

                    float score;

                     }STU;

                      STU girl1, girl2,*girl3;   /*定义结构体类型变量*/

    typedef还可以为其他类型起个别名,如int、char等,均可以为之起别名。如:

         typedef  char  NAME[10];

         NAME  p1,p2;

    相当于如下定义:

      char  p1[10],p2[10];

    3.结构体成员的引用

    结构体成员的引用与数组元素的引用相似,对各个成员要分别引用。结构体成员引用的运算符有“*”和“->”,引用形式如下:

       结构体变量名.结构体成员

       结构体变量指针->结构体成员

       (*结构体变量指针).结构体成员

    实例中,相对应的表达式有:

        girl2.num 

        girl3->num

         (*girl3).sex

    实例46  结构体类型的数组的定义与引用——成绩统计

    实例任务】

        嵌套定义一个结构体,定义一个结构类型的变量并赋初值,编程输出学生的信息并输出每位同学的平均成绩和总成绩。程序运行结果如图9-2所示。

    60fd1d7c04d82403b2f60538f24dd32a.png

     9-2 程序运行结果

    程序代码

    #include  "stdio.h"

    struct  birthday

    {int year;

     int month;

     int day;}; 

    struct student

    { char name[10];

      struct birthday date;

      int chinese;

      int math;

      int english;

      int ave;

      int count;

    }stu[5]={ {"李一",1980,5,12,69,82,91},

             {"李二",1981,6,26,73,68,81},

             {"李三",1980,12,7,88,81,75},

             {"李四",1981,7,30,77,95,61},

             {"李五",1980,1,22,96,71,64}};

    /*嵌套定义结构体类型,定义结构体类型数组的同时进行初始化*/

    main()

    { char *p[10]={"姓名","出生年月","语文","数学","英语","平均分","总分"};

      int i;

     for(i=0;i<5;i++)< span="">

     {stu[i].count=stu[i].chinese+stu[i].math+stu[i].english;

      stu[i].ave=(stu[i].count)/3;  

     }

    printf("五名同学的成绩表:\n");

    for(i=0;i<7;i++)< span="">

    printf("%-12s",p[i]);

    for(i=0;i<5;i++)< span="">

    printf("\n%-12s%-4d-%-2d-%-6d%-12d%-12d%-12d%-12d%-12d",stu[i].name,stu[i].date.year,stu[i].date.month,stu[i].date.day,stu[i].chinese,stu[i].math,stu[i].english,stu[i].ave,stu[i].count);

    }

    相关知识

    1.结构体类型数组的定义

    结构体类型一旦定义好后,就可以和C语言固有类型一样定义数组,只是每个数组元素都是该结构体类型。

    实例中,在定义结构体类型student的同时定义结构体类型的数组,并为每个数组元素赋初值。每个数组元素都是结构体类型,赋值时按各成员的顺序依次赋值。且每个数组元素的值用{}括起来。

    当定义的结构体类型的二维数组时,要分行赋值,详见实例中为stu[5]数组的赋值过程。

    2.结构体类型数组元素的引用

    结构体类型数组元素引用时,要指明引用哪个数组元素的哪个成员,如表达式stu[i].count就是引用数组元素stu[i]的count成员。

    当结构体类型数组元素为结构体类型指针变量赋值时,可以直接取该数组元素的地址,让该指针变量指向该数组元素,则可以通过指针变量引用数组元素的各个成员。

    实例47  函数之间结构体类型变量的数据传递——输出排序后的姓名和学号

    实例任务】

    输入几名学生的姓名和学号,然后按学号由小到大的顺序排序,再输出排序后的结果。程序的运行结果如图9-3所示。

    3fbfa4729dd6c568af5e47219b862094.png

                               9-3  程序运行结果

    程序代码

    #include "stdio.h"

    typedef struct

    {  char  name[20];

       char  number[5];

    }STU; 

    main()

    { STU s[5];

      int i;

      for(i=0;i<5;i++)< span="">

      getdata(&s[i]);

      /*将结构体类型变量的地址传递给形参*/

      printf("\n输入的数据为:");

      for(i=0;i<5;i< span="">++)

        printf("\n%-10s%-5s",s[i].name,s[i].number);

      tosort(s);

      /*将结构体类型的一维数组元素的首地址传递给形参*/ 

      outdata(s);

      getch();  }

    getdata(STU *p)

    {  {gets(p->name);    gets(p->number);}  } 

    tosort(STU *p)

    { int i,j,k;

      STU temp;

      for(i=0;i<4;i++)< span="">

      {k=i;

        for(j=i+1;j<5;j++)< span="">

         if(strcmp(p[k].number,p[j].number)>0) k=j;

         temp=p[k];p[k]=p[i];p[i]=temp;  }  }

     outdata(STU *p)

     { int i;

      printf("\n排序后输出为:\n");

      for(i=0;i<5;i++)< span="">

        printf("%s  %s  \n",p[i].name,p[i].number);  }

    相关知识

    1.向形参传递结构体类型变量成员的值

    结构体变量的成员,和前几章学过的基本数据类型的变量、数组、指针等变量是一样的,值传递时,可以直接传递成员的值;地址传递时,直接取成员的地址传递给形参就可以了。

    2.向形参传递结构体类型变量的值

    当向形参传递结构体类型变量的值的时候,形参需定义为该结构体类型。在自定义函数内对形参的任何重新赋值过程不会影响到实参。

    3.向形参传递结构体类型变量的地址

    当向函数传递结构体类型变量的地址时,对应的形参需定义为基类型为该结构体类型的指针变量。这样,指针变量直接指向实参的结构体类型的变量,系统中只需开辟一个存储单元存放指针变量即可。实例中,调用getdata函数时,向形参传递的就是结构体类型变量的地址。

    4.向形参传递结构体类型数组名

    当向函数传递结构体类型数组名时,形参需定义为基类型是该结构体类型的指针变量。因为数组名的值就是这个数组的首地址,数据传递后该指针变量就指向了这个结构体类型的数组,引用时可以通过指针的移动来引用各个数组元素,且自定义函数时对结构体成员的重新赋值即对实参各个成员的重新赋值。实例中,调用tosort和outdata函数时,向形参传递的是结构体类型数组名。

    5.函数数返回结构体类型值或返回指向结构体类型的指针

    结构体类型除定义变量、指针变量、数组等元素外,还可以定义函数,来返回结构体类型的值或指针值。这在用法上和其他类型的函数一样,需要在调用处定义相同基类型的变量来接收函数返回的值。

    课堂精练

    1. 定义一个结构体类型,然后通过调用函数为之赋值。程序的运行结果如图9-4所示。

    5753e6be577021c540e1ae6b28f8217e.png

                        9-4  程序运行结果。      

    根据程序的运行结果,请将程序补充完整并调试。

    #include  "stdio.h"

    struct  stu

    {  char  name;

       int  num;  };

    struct stu fun(struct stu y)

     { printf("\n请输入更换的值:\n");

       scanf("%c",&y.name);

       _____________________________

       return y;  } 

    main()

    {struct  stu  x;

      scanf("%c",&x.name);

      scanf("%d",&x.num);

      printf("\n你输入的值为:\n");

      printf("%c  %d",x.name,x.num);

      ____________________________

      printf("\n你更换后的值为:\n");

      printf("%c  %d",x.name,x.num);

      } 

    2.输入结构体类型变量的两个成员值,然后通过调用返回地址值的函数为两个成员赋另外一组值。程序的运行结果如图9-5所示。  5a2126684ad4f45851d4cc93368674d7.png

                            9-5  程序的运行结果。

    根据程序的运行结果,将下列程序补充完整并调试。

    #include  "stdio.h"

    struct  stu

    {  char  name;

       int  num;

    };

    struct stu *fun(struct stu *y)

    /*自定义函数,函数返回指针*/

     {   printf("\n请输入更换的值:\n");

       scanf("%c",&y->name);

      __________________________________    } 

    main()

    {struct  stu  x,*p;

     scanf("%c",&x.name);

     scanf("%d",&x.num);

      printf("\n你输入的值为:\n");

      printf("%c  %d",x.name,x.num);

     ________________________________

      printf("\n你更换后的值为:\n");

      printf("%c  %d",(*p).name,p->num);

      }

    9.2  链表

    学习目标

    (1)掌握动态开辟存储空间的相关函数的使用

    (2)掌握单向链表的建立方法

    (3)掌握链表的基本操作的相关函数的使用

    实例48  单向链表的建立——输出五名同学的信息

    实例任务】

    定义一个结构体类型的数组,然后将这五个数组元素连接起来生成一个链表,通过每个结构体类型数组元素的指针成员输出每名同学的信息。程序运行结果如图9-6所示。                               186bcdb9fc63c75fcc689cca44b918fa.png

                               9-6  程序运行结果

    程序代码

    #include  "stdio.h"

    #include  "string.h"

    typedef struct student

    { char name[20];

      int  num;

      struct  student  *next;

    } ST;

    main()

    { ST a[5],*head,*p;

    /*定义a[5]是有5个元素的结构体类型的数组*/

      int i;

      printf("请依次输入五名同学的姓名和学号:\n");

      for(i=0;i<5;i++)< span="">

       {gets(a[i].name);

        scanf("%d",&a[i].num);     }   

       head=a;

       /*头指针head指向第一个数组元素*/

       a[0].next=a+1;/*将第1个数组元素连接到第0个数组元素的后面*/

       a[1].next=a+2;/*将第2个数组元素连接到第1个数组元素的后面*/

       a[2].next=a+3;

       a[3].next=a+4;

       a[4].next='\0';

       /*最后一个数组元素的指针成员不再有任何指向,赋值为'\0'*/ 

       p=head;/*p先指头指针*/ 

       printf("请输出这五名同学的个人信息:\n"); 

       for(i=0;i<5;i+< span="">+)

       {printf("%15s",p->name);

        printf("%10d\n",p->num);

        p=p->next; } 

        /*通过每个结点的next成员值,实现了链表结点的后移*/ 

       }

    相关知识

    1.结构体的成员可以为指向本结构体的指针

    结构体类型定义时,可以为各种固有的类型。对于构造结构体类型时,可以为指向本结构体类型的指针。实例中定义结构体类型时的next成员,是基类型为指向自身的指针变量,这样可以通过这个变量记录下一个相同类型的结构体类型变量或数组元素,从而逻辑上连接起来,生成一个链表。

    2.单向链表的建立

    实例中,基于结构体类型构造时含有一个指向自身的指针变量,通过这个指针变量,将5个数组元素连接起来,从而通过这个指针成员来引用结构体类型数组元素的各个成员。其链表形式如图9-7所示。

    1322b5238275c7de80293f8648a7787d.png

    9-7  链表的构成

    连接到链表的每个元素,在链表中称为结点。这些结点在存储空间的地址可以连续,也可以不连续,都是通过指针域连接到一起。

    单向链表都有一个头指针,它指向链表的第一个结点,这个结点也称为链表的头结点。链表的最后一个结点为尾结点,因其指针域不再有任何指向,其指针域赋值为NULL(空),通常我们赋值为'\0'。实例中,a[4]元素的指针赋值为'\0'                   

    实例49  动态链表的建立及常用操作——输出学生的信息

    实例任务】

    动态开辟存储空间,将新建立的各个结点依次链接到链表中,然后按顺序输出学生的学号和姓名信息。程序的运行结果如图9-8所示。

    e1c07d98c5b874c40239d0f30401f9ea.png

                               9-8  程序运行结果

    程序代码

    #include  "stdio.h"

    #include  "string.h"

    #include  "stdlib.h"

    typedef struct  student

    { int num;

      char name[20];

      struct student  *next;

    }ST;/*为结构体命别名为ST*/

    main()

    { ST *head,*p,*s,new;

      head='\0';/*初始化头指针,或用语句head=NULL;*/ 

     /*创建一个空链表,并将头指针各参数初始化*/

      head=malloc(sizeof(ST));/*为头指针动态开辟存储空间*/

      if(head==NULL)

       {printf("没有足够的内存!请返回!");

        return;    }

      head->next=NULL;

      head->num=0;

     /*在链表中插入结点*/

     p=head;/*p先指向头指针*/

     do

     { printf("请输入学生的学号为:\n");

       scanf("%d",&new.num);

       if(new.num==0)/*学号为0时循环结束*/

         break;

       printf("请输入学生的姓名为:\n");

       scanf("%s",new.name);

       s=malloc(sizeof(ST));/*开辟一个ST结构体类型的存储空间*/

     if(s==NULL)

       {printf("没有足够的内存!请返回!");

        return;    }

      strcpy(s->name,new.name);/*将姓名存入s结点中*/

      s->num=new.num;/*将学生存入s结点中*/ 

      s->next=NULL;/*将s结点的指针域赋值为空*/ 

      p->next=s;/*将s结点连接到链表的结尾*/ 

      p=s;/*p指向新产生的结点*/ 

    }while(1);

    printf("结点已经插入,成功!\n");

    p=head->next;/*p指向头结点*/

    while(p!=NULL)/*只要p所指向结点的指针域不为空,循环不结束*/

    {printf("学生的学号为:%d   姓名为:%s\n",p->num,p->name);

     p=p->next;}/*指针逐个结点后移*/

        }

    相关知识

    1.动态链表

    对于已经存在的各个相同类型的结构体类型的变量或数组元素,可以通过指针域连接成链表。对于结构体类型的存储空间,可以在程序运行过程根据需要动态地开辟。动态链表就是这样一种能动态地进行存储空间分配的数据结构。

    2.malloc()函数

    C语言中提供了一个函数malloc(),该函数在头文件“stdlib.h”中声明,它用于根据需要动态地为链表开辟存储空间,其函数值为所开辟空间的起始地址,并赋值给一个与其数据类型相同的指针变量,其使用形式为:

       s=malloc(sizeof(数据类型));

    如,

      s=malloc(sizeof(char[5])); /*开辟5个字符的存储空间*/

    s=malloc(sizeof(int));/*开辟2个字节的整型存储空间*/

      s=malloc(sizeof(ST));/*开辟1个别名为ST的结构体类型存储空间*/

    3.free()函数

    系统中,为了防止资源浪费,提供了另外一个函数free(),用于释放指针所指向的存储空间。该函数也在头文件“stdlib.h”中声明。其使用形式为:

       free(指针变量);

    实例50  链表的操作——学生信息管理系统

    实例任务】

    建立一个目录,有6个选项,根据需要选择其中一项进行操作,来实现链表的创建、结点插入、信息查找、删除结点、浏览信息、退出功能。程序的运行结果如图9-9所示。

    9ceaf2f5d3713ae8cfcef91765dc9f65.png

                               9-9  程序运行结果

    程序代码

    #include "stdio.h"

    #include "stdlib.h"

    #include "string.h"

    typedef struct student

    {int  num;

    char name[20];

    struct student *next;

    }ST;

    ST *create_list();

    /*创建链表,只有头指针*/

    int insert_list(ST *head,ST *stu,int n);

    /*向链表插入结点,n值用于指定插入的学号*/

    int delete_list(ST *head,ST *stu);

    /*从链表删除指定的结点,按姓名删除*/

    ST *find_list(ST*head,ST *stu);

    /*从链表中查找结点,显示个人信息*/

    void browse_list(ST *hea(D);

    /*将链表中各结点的信息全部输出*/

    main()

    { ST *head,new;/*head为链表的头指针,new为新建结点*/

      int number,n;/*用于选择操作选项号*/

      head='\0';/*头指针初始化*/

      printf("请选择操作选项(1-6):\n");

      printf("1.建立学生信息链表\n");

      printf("2.插入一名新的学生\n");

      printf("3.从链表中删除学生\n");

      printf("4.在链表中查找学生\n");

      printf("5.在链表中浏览信息\n");

      printf("6.退出程序结束操作\n");

     do

      {scanf("%d",&number);

      if(number>6||number<=0)/*操作项目编写为1-6*/

        {printf("超出操作选项编号,请重新输入");

          continue;       } 

      switch(number)

      { case 1:

           if(head=='\0') 

              head=create_list();

           break;

       case 2:

           if(head=='\0')

            {printf("链表尚未创建!请先创建链表!\n");

             break;}

            do

           {printf("请输入学生的学号:\n");

            scanf("%d",&new.num);

            printf("请输入学生的姓名:\n");

            scanf("%s",new.name);

            printf("请输入指定学生的学号:\n");

            scanf("%d",&n);

            insert_list(head,&new,n); 

            printf("请选择下一步操作!\n"); 

            }while(new.num==0);

           break;      

       case 3:

            printf("请输入待删除学生的姓名:\n");

            scanf("%s",&new.name);/*按输入的姓名删除*/       

            delete_list(head,&new);

            break;

       case 4:

            printf("请输入待查找学生的姓名:\n");

            scanf("%s",&new.name);/*按输入的姓名查找*/ 

            find_list(head,&new);

            break;

       case 5:

            browse_list(hea(D);/*将链表头指针作为实参传递*/ 

            break;

       case 6:

            return;     } 

    } while(1);

      }

    相关知识

    1.链表的建立函数

    利用malloc()函数开辟一存储空间,然后对其进行初始化后将头指针返回调用处,其函数代码为:

    ST *create_list()

    { ST *head;

      head=malloc(sizeof(ST));/*为头指针动态开辟存储空间*/ 

      if(head!=NULL)

        printf("链表已经建立成功!请选择下一步操作!\n");

      else

        printf("内存不足!\n");

      head->next=NULL;/*将头指针指针域赋值为空*/ 

      head->num=0;/*num域赋值为0*/ 

      return head; }   /*返回创建链表的头指针地址*/

    2.插入结点函数

    对于已经创建的链表,可以向链表插入结点。插入过程分两种情况,一种是插入到链表结尾,另一种是指定插入位置,实例中指定插入位置n,实例中插入结点过程形如图9-10所示,其中虚线为原链表中q、p所指向结点的连接情况。

    5a7de85f18e42fcc7f4ed28daac6ebaf.pngb5f872ce0df237f69548c69be859d48e.png

                          9-10  插入结点的过程

    插入结点函数代码为:

    int insert_list(ST *head,ST *stu,int n)

    {ST *q,*p,*newstu;

     newstu=malloc(sizeof(ST));/*新开辟一空间,用于存放新插入的结点*/

     if(newstu==NULL)

      {printf("内存空间不足!\n");

      return 0;   }

      q=head;

      p=head->next;

      while(p!=NULL&&n!=q->num) 

      { q=p;/*q记录插入位置的前一结点,p记录后一结点*/

        p=p->next;  }    /*通过移动指针变量p来查找插入的位置*/

      q->next=newstu;/*q的next域值为新插入结点的地址值*/ 

      newstu->next=p;/*新插入结点的next域存放后一结点的地址值*/ 

      strcpy(newstu->name,stu->name);/*数据成员域分别从调用处得到值*/ 

      newstu->num=stu->num;

      return 1;  }

    3.删除结点函数

    要删除结点,首先要找到指定的结点,然后是一个断链重新接上的过程,如图9-11所示,再将被删除结点所占的存储空间释放掉,图中虚线为被删除的结点。

    6d5470a9bee0e9209ea941aba88bcd82.png12fb4df88330fb990fa7c92152660533.pngd19c6372e14610c471f499e1c50555d9.png

                       9-11  删除结点过程

    删除结点函数代码为:

    int delete_list(ST *head,ST *stu)

     { ST *q,*p;

      q=head;

      p=head->next;

      while(p!=NULL&&strcmp(p->name,stu->name))

        /*调用函数strcmp查找姓名字符串,直到找到相同的字符串为止*/ 

      { q=p;

      p=p->next; }        /*通过p的移动来查找*/   

     if(p!=NULL)

     {q->next=p->next;

      free(p);/*如果删除结点,要释放掉它占用的空间*/ 

      printf("删除成功!");

      return 1;     }

    else

      {printf("查无此人!");

       return 0;     }

           printf("请选择下一步操作!\n"); }

    4.查找结点函数

    由于链表中各结点存储空间并不一定连续,但可以通过各结点的指针域去查找指定条件的结点。本函数用来查找指定姓名的结点,如果找到返回该结点的首地址;如果找不到,返回空指针。

    查找结点函数代码为:

    ST *find_list(ST *head,ST *stu)

    { ST *p;

      p=head;

      while(p!=NULL&&strcmp(p->name,stu->name))

      /*调用函数strcmp查找姓名字符串*/ 

        p=p->next;

      if(p!=NULL)

        printf("学号:%d    姓名:%s\n",p->num,p->name);

      else

        printf("查无此人!"); 

        printf("请选择下一步操作!\n");

        return p;   }

    5.浏览信息函数

    链表将位于不同存储空间位置的相同数据结构的结点连接起来,那么可以通过移动指向各结点的指针访问各个结点。

    浏览信息函数的代码为:

    void browse_list(ST *hea(D)

    { ST *p;

     p=head->next;

     while(p!=NULL)

     {   printf("学号:%d    姓名:%s\n",p->num,p->name);

         p=p->next;   }

        printf("请选择下一步操作!\n");   }

    课堂精练

    1.计算一组同学的平均成绩,并统计一下不及格的人数。程序的运行结果如图9-12所示。

        dcf4e1889d7dc7f2513d7d2e6692dc69.png

                     9-12   程序运行结果

    根据程序的运行结果,请将下面程序补充完整并调试。

    #include "stdio.h"

    struct stu

    { int  num;

    char name[20];

    float score;

    }student[5]={{10,"stu0",65},

                 {20,"stu1",38},

                 {30,"stu2",92.5},

                 {40,"stu3",48.5},

                 {50,"stu4",76}};

    main()

    { int i,count=0;

    float ave,sum=0.0;

    for(i=0;i<5;i++)< span="">

    { sum+=student[i].score;

      if(student[i].score<60) 

      _________________________________   }

     printf("这组学生的平均成绩为%.2f\n",sum/5);

     ___________________________________

     getch();   }

    2.建立一个结构体类型,然后动态生成几个结点并建立起链表。输出五名同学的平均成绩,并统计一下不及格学生的人数。程序的运行结果如图9-13所示。

    37d8ec10ebc72e7a863be85965bdcdc8.png

                       9-13  程序运行结果

    根据程序的运行结果,请将下面程序补充完整并调试。

    #include  "stdio.h"

    #include  "string.h"

    #include  "stdlib.h"

    typedef struct  student

    { int num;

      char name[20];

      float score;

      struct student  *next;

    }ST;/*为结构体命别名为ST*/

    main()

    { ST *head,*p,*s,new;

      int count1=0,count2=0;

      float sum=0.0;

      head='\0';/*初始化头指针,或用语句head=NULL;*/ 

     /*创建一个空链表,并将头指针各参数初始化*/

      head=malloc(sizeof(ST));/*为头指针动态开辟存储空间*/

      if(head==NULL)

       {printf("没有足够的内存!请返回!");

        return;     }

      head->next=NULL;

      head->num=0;

      head->score=0.0;     

     /*在链表中插入结点*/

     p=head;/*p先指向头指针*/

     do

     { printf("请输入学生的学号为:");

       scanf("%d",&new.num);

       if(new.num==0)/*学号为0时循环结束*/

         break;

       printf("请输入学生的姓名为:");

       scanf("%s",new.name);

       printf("请输入学生的成绩为:");

       scanf("%f",&new.score);

       s=malloc(sizeof(ST));/*开辟一个ST结构体类型的存储空间*/

     if(s==NULL)

       {printf("没有足够的内存!请返回!");

        return;      }   

      strcpy(s->name,new.name);/*将姓名存入s结点中*/ 

      s->num=new.num;/*将学生存入s结点中*/ 

      ___________________________________________

      s->next=NULL;/*将s结点的指针域赋值为空*/ 

      p->next=s;/*将s结点连接到链表的结尾*/ 

      p=s;/*p指向新产生的结点*/ 

    }while(1);

    printf("结点已经插入,成功!\n"); 

    /*统计不及格学生的人数*/

    p=head->next;/*p指向头结点*/

    while(p!=NULL)/*只要p所指向结点的指针域不为空,循环不结束*/

    { sum+=p->score;

      __________________________________________

      if(p->score<60)< span="">

        count2++;

       p=p->next;}/*指针逐个结点后移*/ 

     printf("\n这组同学的平均成绩为:%.2f\n",sum/count1);

     printf("这组同学中不及格的学生数为:%d",count2);

       }

    9.3  共用体与枚举类型

    学习目标

    (4)掌握共用体类型的定义方法

    (5)掌握共用体类型变量或数组元素各成员的引用方法

    (6)掌握枚举类型的定义及枚举成员的引用方法

    实例51  共用体类型的定义与变量引用——灵活应用存储空间

    实例任务】

    定义一个共用体类型,并定义一个共用体类型的变量,分别分三次对三个成员域赋值,然后输出各成员域的值。程序运行结果如图9-14所示。

    c140defc4be86f58364de90f173274c4.png

                             9-14  程序的运行结果

    程序代码

    #include "stdio.h"

    union num

    {char c[10];

     int n[2];

     float f;

    };

    main()

    { union num x;

    scanf("%s",&x.c);

    getchar();

    printf(" 字符串为:%s\n",x.c);

    printf("x.n[0]的值为:%d\n  x.n[1]的值为:%d\n",x.n[0],x.n[1]);

    printf("单精度类型f的值为:%f\n\n",x.f);

    scanf("%d,%d",&x.n[0],&x.n[1]);

    getchar();

    printf(" 字符串为:%s\n",x.c);

    printf("x.n[0]的值为:%d\n  x.n[1]的值为:%d\n",x.n[0],x.n[1]);

    printf("单精度类型f的值为:%f\n\n",x.f);

    scanf("%f",&x.f);

    getchar();

    printf(" 字符串为:%s\n",x.c);

    printf("x.n[0]的值为:%d\n  x.n[1]的值为:%d\n",x.n[0],x.n[1]);

    printf("单精度类型f的值为:%f\n\n",x.f);

    scanf("%s",&x.c);

    getchar();

    scanf("%d,%d",&x.n[0],&x.n[1]);

    getchar();

    scanf("%f",&x.f);

    getchar();

    printf(" 字符串为:%s\n",x.c);

    printf("x.n[0]的值为:%d\n  x.n[1]的值为:%d\n",x.n[0],x.n[1]);

    printf("单精度类型f的值为:%f\n\n",x.f);

    /*后面新赋的值依次覆盖前面的值*/

    }

    相关知识

    1.共用体类型的定义

    共用体,又称为联合体,它是与结构体类型相近的一种自定义类型。与结构体不同的是它的各个成员分占用同一存储空间。对于共用体所有成员,新赋值的成员将覆盖原有成员所得到的值。共用体中最大成员的大小决定共用体类型元素存储空间的大小。实例中,c[10]成员占用10个字节的空间,决定该共用体类型变量最大空间为10个字节。共用体的定义形式为:

        union 共用体标识符

        类型名  成员变量名1;

          类型名  成员变量名2;

               ………

          类型名  成员变量名n;}

    2.共用体类型变量的引用

    共用体类型变量的引用方法与结构体相同,可以通过“*”和“->”来引用共用体成员的值。形式如下:

       共用体变量.成员名;

       共用体类型指针变量->成员名;

    实例52 枚举类型——输出给定月份的天数

    实例任务】

    定义一个枚举类型,然后输入待查询的月份总数,之后输出所查询的每个月份的天数。程序的运行结果如图9-15所示。

    8bc4e813492aa4b9fe79a9c939204469.png

                               9-15 程序运行结果

    程序代码

    #include "stdio.h"

    enum month {Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec};

    /*定义枚举类型*/

    main()

    {enum month mon;

    int i,n;

    printf("请输入要查询月份个数:\n");

    scanf("%d",&n);/*先确定要查询几个月份*/

    getchar();

    for(i=0;i

    { printf("输入月份(1~12):\n");

     scanf("%d",&mon);/*输入欲查询的月份*/

     getchar();

     switch(mon)

     {case Jan:

      case Mar:

      case May:

      case Jul:

      case Aug:

      case Oct:

      case Dec:

          { printf("%d月有%d天\n",mon,31);

            break;}

      case Feb:

          { printf("%d月有%d天\n",mon,28);

            break;}

      case Apr:

      case Jun:

      case Sep:

      case Nov:

          { printf("%d月有%d天\n",mon,30);

            break;}

      default:

          {printf("输入数据有误!");

           break;}

    }

    }

    }

    相关知识

    1.枚举类型的定义

    在程序设计过程中,往往有一些量是有固定个数的元素。如一年有12个月,一星期有7天,空间有东西南北四个方向等,对于这样的数据结构可以通过枚举类型来定义。枚举是能将变量所有的值一一列举出来,给定一个限定的范围的数据结构。其定义形式如下:

     enum  枚举类型标识符

      {标识符[=整型常量1],

        标识符[=整型常量2],

        ……

        标识符[=整型常量n],};

    枚举类型定义时,后面的整型常量是枚举成员的值为整型常量的值。定义枚举类型时,如果将整型常量表达式均省略,表示默认从0依次赋值为0、1、2、3、…。枚举类型元素在被定义后,其身份均为常量,不能再为其赋值。

    定义枚举类型时,可以强制为各元素赋值,如:

    enum week {sun=7,mon=1,tue,wed,thu,fri,sat};

    则sun值为7,mon值为1,tue值为2,依次类推为3,4,5,6。

    2.枚举类型变量的定义与引用

    枚举类型变量的定义可以在定义类型的同时定义变量,也可以先定义枚举类型,然后再定义变量。可以为下面三种形式之一:

      enum week {sun,mon,tue,wed,thu,fri,sat};

      enum week a,b,c;

    或者:

      enum week {sun,mon,tue,wed,thu,fri,sat} a,b,c;

    或者:

      enum {sun,mon,tue,wed,thu,fri,sat} a,b,c;

    枚举类型的变量被认为是有范围的整型变量,所赋的值也应该是枚举类型的值,如果不是枚举类型请强制其类型转换为枚举类型。枚举类型变量赋值的一般形式为:

        枚举变量=枚举值; 

     课堂精练

    1.定义一个共用体类型,定义其变量后为其成员依次赋值,然后输出各成员的值。运行结果如图9-16所示。

    426f6a22c5461d84c92b081bc58da358.png

                         9-16  程序运行结果

    根据程序的运行结果,请将下面程序补充完整并调试。

    #include "stdio.h"

    typedef union

    {int  num;

     float f;

    }UN;

    main()

    { UN  x;

      x.num=10;

      x.f=10.5;

      printf("请输出x.num成员的值为:%d\n",x.num);

      _______________________________________ 

    getch();   }

    2.定义一个枚举类型,为第一个枚举成员赋值为1,然后定义一个枚举型数组并通过枚举成员为之赋值,输出各数组元素的值。其运行结果如图9-17所示。

      18b3a6919bee9feb0b69460ef6e4a1fa.png

                       9-17   程序运行结果

    根据程序的运行结果,请将下面程序补充完整并调试。

    #include "stdio.h"

    main()

    {  enum body {a=1,b,c,d} num[8],j;

    /*此处a=1,后面默认依次值为2,3,4*/

       int i;

     _______________________________

    for(i=0;i<8;i++)< span="">

      {num[i]=j;

     _______________________________

     if(j>d) j=a;   }

    printf("依次输出各数组元素的值为:\n");

    for(i=0;i<8;i++)< span="">

       printf("%-5d",num[i]); 

    getch();  }

    9.4  课后习题

    9.4.1  项目练习

     一.练习目的

      1.进一步巩固结构体类型和共用体类型的定义与引用

      2.进一步复习链表的建立过程

      3.进一步巩固枚举类型的定义与枚举元素的引用方法

     二.练习内容

    1. 用结构体变量表示平面上的一个点(横坐标和纵坐标),输入两个点,求两点之间的距离。

     2.用结构类型描述一个学生的有关数据,其中含有:姓名,学号,语文成绩,数学成绩,外语成绩,平均成绩,排名次序。输入全班学生(人数不超过50人)的数据(不包括平均成绩和排名次序),求出各人的平均成绩,并按平均成绩由高到低将学生排名次(要考虑并列名次),按名次顺序输出这些学生的所有数据。

    3.16同学围成一圈,从第1个人开始按1、2、3的顺序报号凡报到3者退出圈子。找出最后留在圈子中的人原来的序号。

    4.建立一个链表,每个结点包含的成员为:职工号、工资。用malloc函数开辟新结点。要求链表包含5个结点,从键盘输入结点中的数据。然后把这些结点的数据打印出来。要求用函数creat来建立函数,用list函数来输出数据。这5个职工的号码为10,11,12,13,14。用insert函数来新增一个职工的数据,这个新结点,按职工号顺序插入。用delete函数来删除一个结点。

    9.4.2 练习题

    一.填空题

    1.若程序中有下面的说明和定义
     struct abc
     {int x;char y;}
     struct abc s1,s2;
    则会发生的情况是
    _____________。

    (A) 编译出错                        (B)程序将顺利编译连接执行
    
    (C)能顺利通过编译连接但不能执行   (D) 能顺利通过编译但连接出错

    2.以下scanf函数调用语句中对结构体变量成员的不正确引用是_____________。

    struct pupil

    { char name[20]; int age; int sex;} pup[5],*p;  p=pup;

    (A)scanf("%s",pup[0].name);       (B)scanf("%d",&pup[0].age);

    (C)scanf("%d",&(p->sex));         (D)scanf("%d",p->age);

    3.以下对结构体变量stul中成员age的非法引用是_____________。

    struc student

    { int age; int num;  }stul,*P;  p=&stul;

    (A)stul.age       (B)student.age     (C)p->age   (D)(*p).age

    4.设有以下说明和定义语句,则下面表达式中值为3的是_____________。

    struct s

    { int i1;  struct s *i2;};

    struct s a[3]={1,&a[1],2,&a[2],3,&a[0]},*ptr;

    ptr=&a[1];

    (A)ptr->i1++   (B)ptr++->i1  (C)*ptr->i1   (D)++ptr->i1

    5. 若要用下面的程序片段使指针变量p指向一个存储整型变量的动态存储单元:

    int *p;

    p=__________ malloc( sizeof(int));

    则应填入_____________。

    (A) int                     (B) inst *                (C) (*int)               (D) (int *)

    6.若要利用下面的程序片段使指针变量p指向一个存储整型变量的存储单元,则空中应填入的内容是_____________。

    int *p;     p=_____________malloc(sizeof(int));

    (A)int       (B)int *  (C)(*int)    (D)(int *)

    7.设有如下定义:

    struct sk

    { int n; float x;}data,*p;

    若要使p指向data中的n域,正确的赋值语句是_____________。

    (A)p=&data.n;               (B)*p=data.n;  

    (C)p=(struct sk *)&data.n;      (D)p=(struct sk *)data.n;

    8.设有以下语句:

    struct st

    { int n; struct st *next;  };

    struct st a[3]={5,&a[1],7,&a[2],9,'\0'},*p;  p=&a[0];  则以下表达式的值为6的是_____________。

    (A)p++->n     (B)p->n++      (C)(*p).n++      (D)++p->n

    9.以下程序的输出结果是_____________。

    struct stu

    { int x; int *y;  }*p;

    int dt[4]={10,20,30,40};

    struct stu a[4]={50,&dt[0],60,&dt[1],70,&dt[2],80,&dt[3]};

    main()

    { p=a; printf("%d",++p->x); printf("%d",(++p)->x); printf("%d\n",++(*p->y));}

    (A)50,20,20   (B)50,20,21      (C)51,60,21      (D)51,60,31

    10.以下对C语言中共用体类型数据的叙述正确的是_____________。

    (A)可以对共有体变量名直接赋值    (B)一个共用体变量中可以同时存放其所有成员

    (C)一个共有体变量中不能同时存放其所有成员

    (D)共用体类型定义中不能出现结构体类型的成员

    11.当说明一个共用体变量时系统分配给它的内存是_____________。

    (A)各成员所需内存量的总和       (B)结构中第一个成员所需内存量

    (C)成员中占内存量最大者所需的容量      (D)结构中最后一个成员所需内存量

    12若有下面的说明和定义,则sizeof(struct a(A) 的值是_____________。
    struct aa
    { int r1;double r2; float r3;
    union uu{char u1[5]; long u2[2]; } ua;
    } mya;
    
    (A)30        (B)29       (C)24        (D)22

    13字符'0'的ASCII码的十进制数为48,且数组的第0个元素在低位,则以下程序的输出结果是_____________。
    #include
    main( )
    { union { int i[2]; long k; char c[4]; }r,*s=&r;
    s->i[0]=0x39;
    s->i[1]=0x38;
    printf("%c\n",s->c[0]) }
    
    (A) 39       (B) 9       (C) 38       (D) 8

    14设有以下定义:
    typedef union { long i;int k[5];char c;}DATE;
    struct date { int cat;DATE cow;double dog;}too;
    DATE max;
    则下列语句的执行结果是
    _____________。
    printf("%d",sizeof(struct date)+sizeof(max));
    
    (A) 25       (B) 30       (C) 18      (D) 815以下对枚举类型名的定义中正确的是_____________。
    
    (A)enum a={one,two,three};          (B)enum a {one=9,two=-1,three};
    
    (C)enum a={"one","two","three"};    (D)enum a {"one","two","three"};

    16.设有定义 enum         date {yearmonthday}  d ;则下列叙述中正确的是_____________。

    (A) date是类型、d是变量、year是常量

    (B) date是类型、dyear是变量

    (C) dated是类型、year是常量

    (D) dated是变量、year是常量

    17 设有定义 enum         date {yearmonthday}  d ;则正确的表达式是_____________。

    (A)  year=1                     (B) d=year

    (C) d="year"                     (D) date="year"

    二.填空题

    1.若有定义:
      struct  num
      {int a;
        int b;
        float  f;
       }n={1,3,5.0};
      struct num *pn=&n;
      则表达式pn->b/n.a*++pn->b的值是
    _____________。表达式(*pn).a+pn->f的值是_____________。
    3. 以下程序的运行结果是
    _____________。
      struct ks
      {int a;
      int *b; }s[4],*p;
      main()
      {int n=1;
      printf("\n");
      for(i=0;i<4;i++)
       { s[i].a=n;
         s[i].b=&s[i].a;
         n=n+2;
         }
      p=&s[0];
      p++;
      printf("%d,%d\n",(++p)->a,(p++)->
    b; 
    4.结构数组中存有三人的姓名和年龄,以下程序输出三人中最年长者的姓名和年龄。请在_______内填入正确内容。
      stati struct man{

    char name[20];   int age; }person[]={"li=ming",18, "wang-hua",19, zhang-ping",20 };  
      main()
      {struct man *p,*q;
       int old=0
       p=person;
      for(  ;p____
    ______;p++)
        if(oldage)
         {q=p;_____
    ______;}
       printf("%s %d",____
    ________); 
    5. 以下
    程序段的功能是统计链表中结点的个数,其中first为指向第一个结点
    的指针(链表不带头结点)。请在______内填入正确内容。
      struct link
      {char data ;
       struct link *next;
      };

      ....
      struct link *p,*first;
      int c=0;
      p=first;
      while(____
    ______)
       {_____
    _______;
        p=___
    _________; }

    展开全文
  • 空指针与结构体指针赋值操作

    千次阅读 2020-04-24 16:33:51
    } 2、输出结果: 3、结论: 1、空指针可以被/给任何类型的指针赋值指针赋值的实质是传递地址。 2、同类型的结构体指针可以直接赋值也可以通过空指针作为中转。 3、不同类型的结构体指针可以通过空指针的中转赋值...

    1、测试代码:

    #include<stdio.h>
    #include<string.h>
    struct DATA
    {
    	int year;
    	int month;
    	int day;
    };
    struct TEST
    {
    	int a;
    	char b;
    };
    int main(void)
    {
    	struct DATA data1;
    	void *p;
    	data1.year = 2020;
    	data1.month = 4;
    	data1.day = 2;
    	p = &data1;
    	struct DATA *data2;
    	data2 = p ;
    	printf("data2 : year =%d, month =%d, day =%d\r\n ",data2->year,data2->month,data2->day);
    	data2->day = 5;
    	printf("data2 : year =%d, month =%d, day =%d\r\n ",data2->year,data2->month,data2->day);
    	printf("data1 : year =%d, month =%d, day =%d\r\n ",data1.year,data1.month,data1.day);
    
    
    	struct TEST *test;
    	test = p ;
    	printf("test : a =%d, b=%d\r\n",test->a,test->b);
    	printf("test : a =%d, b=%d\r\n",test->a,*(test+1));
    	printf("test : a =%d, b=%d c=%d\r\n",test->a,*(test+1),*(test+2));
    	return 0 ;
    }
    

    2、输出结果:
    在这里插入图片描述
    3、结论:
    1、空指针可以被/给任何类型的指针赋值,指针赋值的实质是传递地址。
    2、同类型的结构体指针可以直接赋值也可以通过空指针作为中转。
    3、不同类型的结构体指针可以通过空指针的中转赋值,如果不同结构体的成员的类型和数量相同还好,如果不同,虽然能够编译过,但得到的值需谨慎对待。

    展开全文
  • typedef struct { int header_ptr; char buf[DSP_INFO_SIZE]; }BUF; BUF *dsp_buf_addr=(BUF *)-1; 代码的最后一句看不懂
  • [img=https://img-bbs.csdn.net/upload/201903/30/1553951554_512379.png][/img] 这里为什么会报这个错误呀
  • struct paiming { char name[20]; int b; struct paiming *next; }; 程序1: paiming *p=NULL,*q; q = p; q= (struct paiming*)malloc(sizeof(paiming)); strcpy(q->name, "abc");...
  • 最近用c实现基本数据结构,用的codeblocks+gcc。二叉树这里出了点问题,请高手指点一下: 实现的是基本的二叉树操作:初始化,左插入,又插入,左删除,右删除。。。 用了一个树测试了一下,发现输出完左子树,该...
  • 仔细看看是不是你的结构体忘记写 这样居然就不会报错了………… 有大神明白这到底是为什么吗?

    仔细看看是不是你的结构体忘记写
    在这里插入图片描述

    在这里插入图片描述

    这样居然就不会报错了…………
    有大神明白这到底是为什么吗?

    展开全文
  • 话说,今天遇到这么一个问题。...所以,我想请教大虾们一下,结构体指针赋值的时候赋值的什么,是地址吗?是不是像int* 赋给 int* 一样? 还有,再temp = mru后,能够delete temp吗?delete的是哪个空间?
  • strcpy(pstudent->name, "guo zhao wei "); 为什么错误,该怎么写,(红色行) ...用char nnnn[20]定义的,用strcpy 用char *ppp定义的,用=来赋值 转载于:https://www.cnblogs.com/phpxuetang/p/597...
  • 目的:在实际使用链表时,发现无法正常对嵌入的指向其他结构体指针的内容进行赋值,故而有了以下的记录。 我们在使用链表时,有时候会包含指向其他结构体的指针 比如说 typedef struct A { uint8_t a1; uint8_t a2...
  • C++ 结构体指针与结构体数组的赋值

    千次阅读 2019-07-18 22:15:39
    对于结构体指针,可以用来指向结构体数组的首地址,但是不能按照结构体数组的赋值方式进行赋值,感觉是无法预知后面批量赋值的大小。具体情况见以下代码: #include <iostream> using namespace std; ...
  • C语言中结构体直接赋值

    万次阅读 多人点赞 2018-10-21 10:47:29
    FROM:http://codewenda.com/c语言结构体直接赋值/ 在C语言中结构体变量之间可以...简单结构体(不包含指针成员)直接赋值没有问题。 我们先下面一段代码: 1 2 3 4 5 6 7 8 ...
  • 为此,C提供了结构体变量提高表示数据的能力,它能让你创造新的形式。 1、结构体的定义 struct book { char title[40]; //书名 char author[40]; //作者 float price; //单价 }; 在结构体声明中,用一对...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,318
精华内容 527
关键字:

结构体指针赋值