系统/网络安全

作业三

2020-12-25 19:21:31 阅读数 413 收藏 0

一、指向结构体变量的指针变量

指向结构体变量的指针变量的定义形式与一般指针变量的定义形式相同,只是将其指向类型定义为结构体类型即可。例如:

struct person

{ charname[20];

char sex;

int age;

float height;

};

struct person *p;

则指针变量p,它可以指向struct person类型的结构体变量。

将一个指针变量指向一个结构体变量后,可以利用指向该结构体的的指针变量引用成员,如:

(* 指针变量名).成员名

以上形式也常写成:

指针变量名->成员名

其中,->为指向运算符,它是由符号“-”和“>”两部分构成的。指向运算符的优先级和成员运算符相同,也是最高一级。

二、指向结构体数组的指针变量

指针变量可以指向整型、字符型、浮点型等基本类型数组。同样,指针变量也可以指向结构体类型的数组。

程序L13_2.C功能:使用指向结构体数组的指针变量。

#include

void main()

{ struct person

{ char name[20];

char sex;

int age;

float height;

}per={{ "Li Ping", ‘M ‘,20,175},

{"Wang Ling", ‘F ‘,19,162.5},

{"Zhao Hui", ‘M ‘,20,178}};

struct person *p;

for (p=per;pname, p->sex, p->age, p->height);

}

三、 结构体数据作函数参数

不仅结构体变量的成员可以作函数参数,结构体变量以及指向结构体变量的指针都可以作函数参数。

一、结构体变量的成员作函数参数

结构体变量的成员作实参与简单变量、数组元素等作实参是一样的。

二、结构体变量作函数参数

C允许将整个结构体变量作为函数参数传递。传递的是结构体变量全部成员的值,将实参中成员的值赋给对应的形参成员。

用结构体变量作实参时,由于要为形参结构体变量分配存储空间,还要一一对应传递各成员的值,这样会增加处理的时间同时也浪费了内存空间,从而影响程序的运行效率。

三、指向结构体的指针作函数参数

使用指向结构体的指针作函数实参,形参也必须是一个指向相同结构体类型的指针变量,其它使用方法不变。

四、链表的概念

链表是动态数据结构中最基本的形式,它的规模大小可以根据需要进行动态变化,达到合理地使用存储空间。

链表有一个“头指针”变量,用来指向链表的第一个元素。链表中的每个元素都称为“结点”,结点包含两部分内容:一是实际的数据信息;二是下一结点的指针,。链表的最后一个元素置为“NULL”(空地址),标志链表结束。

一个结点可以用一个结构体类型来描述。结构体中包含若干成员,用来表示结点的数据信息。此外必须有一个成员是与结点类型一致的指针,用来指向后续结点。例如,一个链表的结点可以定义为以下的结构体类型:

struct node

{ int data1;

float data2;

struct node *next;

};

其中,成员next是指向结点的指针变量,它指向next所在的struct node结构体类型数据。

C系统的库函数中提供了动态申请和释放内存存储单元的函数。

(1)malloc函数

malloc函数的原型为:

void *malloc(unsigned int size)

函数的功能是:在动态存储区域中分配一个size字节的连续空间。函数的返回值为指针,它的值是所分配的存储区域的起始地址。如没有足够的存储空间分配,则返回0(记为NULL)值。

(2)calloc函数

calloc函数的原型为:

void *calloc(unsigned int n,unsigned int size)

函数的功能是:在动态存储区域中分配n个为size字节的连续空间,并将该存储空间自动置初值0。函数的返回值为指针,它的值是所分配的存储区域的起始地址。如分配不成功,则返回0值。

(3)free函数

free函数的原型为:

void free(void *ptr)

函数的功能是:释放由ptr所指向的存储空间。ptr的值必须是malloc或calloc函数返回的地址。此函数无返回值。

五、链表的相关操作

一、建立链表

建立链表就是从无到有逐渐增加链表结点的过程,即输入结点数据,并建立前后链接的关系。

下面是建立链表的函数creat() :

struct node *create( )

{ struct node *head, *tail, *p;

int x;

head=tail=NULL;

printf("\n请输入一个整数:");

scanf("%d",&x);

while(x!=0)

{ p=(struct node *)malloc(sizeof(struct node));

p->data=x;

p->next=NULL;

if (head= = NULL)

head=tail=p;

else

{ tail->next=p;

tail=p;

}

printf("请输入一个整数:");

scanf("%d",&x);

}

return (head);

}

二、在链表中插入结点

插入结点的操作有以下几种情况:

(1)链表是空链表,插入的结点作为链表的第一个结点。

(2)链表非空,结点插入到链表的第一个结点前,使插入的结点成为链表第一个结点。

(3)链表非空,结点插入到链表的末尾,使插入的结点成为链表最后一个结点。

(4)链表非空,结点插入到链表中间某个结点之后。

下面函数insert (struct node *head, int value)的作用是在已知头结点head链表中按照从小到大的顺序插入数据value。

struct node *insert(struct node *head, intvalue )

{

struct node *new, *p, *q;

new=(struct node *)malloc(sizeof(struct node));

new->data=value;

p=head;

if(head= =NULL) /*链表是空链表*/

{ head=new;

new->next=NULL;

}

else

{ while((p->next !=NULL) &&(p->datanext; }

if(p->data>=value)

{ if(head= =p) /*链表非空,插入到第一个结点前*/

{ new->next=head;

head=new;

}

else /*链表非空,插入到链表中间*/

{ q->next=new;

new->next=p;

}

}

else /*链表非空,插入到链表末尾*/

{ p->next=new;

new->next=NULL;

}

}

return(head);

}

三、删除链表中的结点

从链表中删除结点,是指把该结点从链表中分离出来,即改变链表的链接关系。从链表中删除的结点有两种处理情况:一是调用函数free()来释放该结点所占的存储空间,将它从内存中删除;二是将该结点插入到其它链表中等待处理。

下面函数delete(struct node *head, int value)的作用是在已知头结点head链表中查找一个数据value,并从链表中删除。

struct node *delete(struct node *head, intvalue )

{ struct node *p, *q;

p=head;

if(head= =NULL) /*链表是空链表*/

{ printf("这是一个空链表!\n"); return(head); }

while((p->next !=NULL) &&(p->data!=value)) /*寻找删除结点位置*/

{ q=p; p=p->next; }

if(value= = p->data)

{ if(head= =p) head=p->next; /*删除链表第一个结点*/

else q->next=p->next; /*删除链表结点*/

free(p);

}

else

printf("此链表没有数据%d!\n",value); /*链表中无此结点*/

return(head);

}


四.改进

说明:此代码增加了“创建违纪学生的信息”这一功能

#include"stdio.h"

#include"stdlib.h"

#include"string.h"

#include"conio.h"

#define PAGE 3

#define MAX 1000

#define N 5

int k=0,w=0;

 

typedef struct  

{   int num;

    char name[20];

char sex;

int age;

char studentclass[20];

int room;

int unit;

}STUDENTS;

int read_file(STUDENTS stu[])

{ FILE *fp;

    int i=0;

if((fp=fopen("stu.txt","rt"))==NULL)

{printf("\n\n*****库存文件不存在!请创");

return 0;

}

while(feof(fp)!=1)

    {

fread(&stu,sizeof(STUDENTS),1,fp);

if(stu.num==0)

break;

else

i++;

}

fclose(fp);

return i;

}

void save_file(STUDENTS stu[],int sum)

{FILE*fp;

 int i;

 if((fp=fopen("stu.txt","wb"))==NULL)

 {printf("写文件错误!\n");

  return;

 }

   for(i=0;i

  if(fwrite(&stu,sizeof(STUDENTS),1,fp)!=1)

  printf("写文件错误!\n");

  fclose(fp);

}

int input(STUDENTS stu[])

{  int i,x;

   for(i=0;i