一。使用链表的原因
1.结构体数组是固定的,效率低。
2.链表可以动态存储分配,用则申请,不用则释放。
二。存储空间的分配和释放
1.malloc——动态分配一段内存空间
void*malloc(unsigned int size)
功能:在内存的动态存储区申请长度为size字节的连续存储空间,返回一个指针指向所分配存储空间的起始地址。若空间不够,返回空指针NULL
说明:要将这个指针值赋给其他类型的指针变量,应进行强制类型转换
malloc函数经常使用sizeof
malloc()函数存储在stdlib.h中
例子:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int*pi=(int*)malloc(sizeof(int));
*pi=100;
printf("%d",*pi);
}
2.calloc——动态分配连续内存空间
void*calloc(unsigned int n,unsigned int size)
功能:在内存申请n个长度为size字节的存储空间,并返回该存储空间的起始位置,不够则返回空指针NULL,该函数主要用于为动态数组申请存储空间,n是元素个数,size是元素存储长度
说明:int*p=(int*)calloc(10,sizeof(int))可以将p作为10个元素的整型数组使用,没有数组名,只能用p来访问,该语句也可用malloc实现:int*p=(int*)malloc(sizeof(int)*10);
例子:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i;
char*ch1=(char*)malloc(sizeof(char)*26);
char*ch2=(char*)calloc(26,sizeof(char));
for(i=0;i<26;i++)
{
ch1[i]=65+i;
ch2[i]=97+i;
}
for(i=0;i<26;i++)
{
printf("%c",ch1[i]);
printf("%c",ch2[i]);
}
}
3.realloc——改变指针指向空间的大小
void*realloc(void*ptr,size_t size);
功能:改变ptr指针指向大小为size的空间,设定的size可以比之前大也可以比之前小,返回值是一个指向新地址的指针,如果出现错误,返回NULL
例子:从运行结果可以知道,新旧空间起始地址一样,但是大小不一样
#include <stdio.h>
#include <stdlib.h>
int main()
{
int*q;
double*p=(double*)malloc(sizeof(double));
printf("p指向内存空间的起始地址:%p\n",p);
printf("p指向内存空间的大小:%d字节\n",sizeof(*p));
q=(int*)realloc(p,sizeof(int));
printf("q指向内存空间的起始地址:%p\n",q);
printf("q指向内存空间的大小:%d字节\n",sizeof(*q));
}
4.free——释放存储空间
void free(void*p)
功能:将指针变量p指向的存储空间释放,交还给系统,无返回值
说明:p只能是程序中此前最后一次调用malloc或calloc函数所返回的地址
例如:
int*p,*q=(int*)malloc(10*sizeof(int));
p=q;
q++;
free(p);
如果改用free(q)则运行会提示错误,因为执行q++之后,q已经改变
例子:释放后再输出的是一个不可预料的值
#include <stdio.h>
#include <stdlib.h>
int main()
{
int*p;
p=(int*)malloc(sizeof(int));
*p=100;
printf("%d\n",*p);
free(p);
printf("%d\n",*p);
}