C第八天任務
動態內存分配
下面的四個函數在stdlib.h中,因此,要用下面四個函數的時候需include <stdlib.h>
使用malloc函數
函數原型:void *malloc(unsigned int size);
作用:在內存的動態內存區中分配一個長度爲size的連續空間
返回值:所分配空間的第一個字節的地址;或者說,該函數是一個指針型函數,返回的指針指向該分配區域的第一個 字節地址(若不能成功執行,則返回NULL)
使用calloc函數
函數原型:void *calloc(unsigned n,unsigned size);
作用:在內存的動態內存區中分配n個長度爲size的連續空間,這個空間一般比較大,足以保存一個數組。
返回值:函數返回指向所分配域的起始位置指針;如果分配不成功,返回NULL;
使用free函數
函數原型:void free(void *p);
作用:釋放指針變量p所指向的動態空間,使這一部分空間能夠被其他變量使用;p是最近一次用malloc或calloc得到的返回值;
返回值:free無返回值;
使用realloc函數
函數原型:void *realloc(void *p,unsigned int size);
作用:改變malloc/calloc所分配的動態存儲空間大小,重新分配;用、用realloc函數將p所指向的動態空間大小改變爲size;p不變,改變不成功,返回NULL;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define uint unsigned int
int n;
int numb=0;
struct data *creat();
//void find();
//void del();
void delall();
void findall();
struct data
{
char name[20];
uint math;
uint cn;
uint eng;
int *next;
} ;
struct data *head,*p1,*p2;
void main()
{
printf("歡迎使用學生成績管理系統\n");
printf("請輸入您要執行的操作編號\n");
printf("1 新建學生成績信息\n2 查詢單一學生信息\n3 查詢全部學生成績信息\n4 刪除單一學生成績信息\n5 刪除全部學生成績信息\n您要執行的操作是:");
scanf("%d",&numb);
while(1)
{
switch (numb)
{
case 1:creat();break;
// case 2:find();break;
case 3:findall();break;
// case 4:del();break;
case 5:delall();break;
default:printf("操作指令有誤,請重新輸入");
}
printf("請輸入您要執行的操作:");
scanf("%d",&numb);
}
}
struct data *creat()
{
printf("請輸入學生姓名 語文成績 數學成績 英語成績(以空格爲分隔符,以輸入end 0 0 0爲結束標誌)\n");
n=0;
p1=p2=(struct data*)malloc(sizeof(struct data)); //開闢一個大小爲 struct data 大小的內存堆空間,並把該空間的首地址給p1,p2指針
head=NULL;
while(strcmp(p1->name,"end")) //一直循環,當遇到輸入end時候跳出這個循環
{
n=n+1; // 記錄一共輸入幾個學生的數據
if (n==1)
head=p1; //當輸入第一個學生的數據的時候,把第一個堆空間的首地址給head,讀取數據的時候從head開始讀取
else
p2->next=p1; //如果不是第一個學生的數據,那麼就讓該堆空間的next成員表示爲下一個堆空間的首地址
p2=p1; //讓p2和p1指向同一個堆空間的首地址
p1=(struct data*)malloc(sizeof(struct data));//開闢一個大小爲 struct data 大小的內存堆空間,並把該空間的首地址給p1空間
printf("學生%d:",n); //打個序列號,說明這個是第幾個學生的信息
scanf("%s %d %d %d",p1->name,&p1->cn,&p1->math,&p1->eng);//輸入對應的結構體成員的值
}
p2->next=NULL; //當全部循環結束後,讓最後一個堆空間的next指向NULL,表示鏈表結束
return(head); //返回這次循環中所創建的第一個堆空間的首地址,方便我們讀取的時候運用
}
void findall()
{
struct data *p;
p=head;
printf("全部學生信息如下:\n");
if (head!=NULL)
while(p!=NULL)
{
printf("姓名:%s 語文:%d 數學:%d 英語:%d\n",p->name,p->cn,p->math,p->eng);
p=p->next;
}
}
void delall()
{
printf("正在執行刪除操作......請等待\n");
free(head);
free(p1);
free(p2);
printf("全部信息已刪除成功\n\n\n");
}
/*void find()
{
struct data *p;
char nam[20];
uint num=n,count;
printf("請輸入您要查找的學生姓名:");
scanf("%s",nam);
p=head;
if (head!=NULL)
while (!strcmp(nam,p->name)&&!(count==n))
{
p=p->next;
count+=1;
if (p->next==NULL)
{
printf("您查找的學生不存在\n");
break;
}
}
printf("姓名:%s 語文:%d 數學:%d 英語:%d\n",p->name,p->cn,p->math,p->eng);
}
*/
/*
void del()
{
struct data *p;
char nam[20];
uint num=n,count;
printf("請輸入您要刪除信息的學生姓名:");
scanf("%s",nam);
p=creat();
if (head!=NULL)
while(strcmp(nam,p->name)&&(count!=num))
{
p=p->next;
count+=1;
}
if(count==num)
printf("您要刪除信息的學生不存在\n");
else
printf("暫時不知道如何刪除單一學生數據......");
}
*/
目前水平不夠,單一查找做不出來,單一刪除做不出來,
同時程序中輸出全部信息的時候第一個信息會輸出指針的指的地址給的隨機數,
如果把p=p->next換到下面去,則程序會崩潰,不能循環執行,具體原因還不太清楚。
指針這一塊有點讓人頭疼.
同時也尋求各位大佬的幫助,幫小弟改下錯誤,在評論區裏。
謝各位大佬!!!!
附加符合要求的程序
#include <stdio.h>
list head; //頭成員 不用存儲數據
typedef struct List
{
int data;
struct List *next;
}list;
void AddList(int data)
{
list *p,*end;
p=(list *)malloc(sizeof(list));
p->data = data;
p->next = NULL;
end = &head;
while(end->next !=NULL)
end = end->next;
end->next = p;
}
void CheckList(void) //遍歷鏈表成員
{
list *p;
p= head.next;
while(1)
{
if(p== NULL)
break;
printf("%d ",p->data);
p=p->next;
}
printf("\n*********鏈表尾*********\n");
}
void DelList(int data)
{
list *p,*q;
if(head.next == NULL)
return;
p= &head;
q= p->next;
while(1)
{
if(q == NULL)
break;
if((q->data) == data)
{
p->next = q->next;
free(q);
}
p=p->next;
q=p->next;
}
}
int main(void)
{
int i;
head.next =NULL;
for(i=0;i<5;i++) //創建鏈表 並增加成員
AddList(i);
CheckList(); //遍歷成員信息 打印出來
DelList(2); //根據成員信息刪除成員
CheckList();
return 0;
}