动态内存申请
申请单个变量的内存
//需要的头文件 malloc
#include<malloc.h>
//1.动态内存是内存都是指针
//2. malloc(内存大小)
//3.需要进行强制类型转换 (int *)
//意义:定义一个整型指针p指向一个4字节的内存地址
int* p =(int *)malloc(sizeof(int));
//因为申请内存可能会失败,所以需要进行防御性编程
if(p == NULL)
{
return;
}
//p指向了内存大小后,*p可以直接当成变量使用
*p = 1234; //等效于 int a = 1234;
//用完后需要手动释放内存,并且需要将指针指向空(避免悬浮指针)
free(p);
p = NULL;
// calloc函数
// 格式:int* p = (int*)calloc(数据数量,每个数据占多少内存)
//特点 默认将该段内存的数据 初始化为0
int* p =(int*)calloc(2,4);
//意义:指针p指向2个数据每个数据占4字节
动态内存申请(指针操作一段内存)
//动态内存申请 指针操作一段内存,产生数组
//申请后直接将指针名(p)当作数组名来用
int* p = (int*)malloc(每个数据大小*数据个数);
//对于指针来说,释放位置要与申请位置一致,若运行过程中指针指向发生了偏移。最后释放时要将指针指向回原地址
int* begin = p; //创建临时指针 保存原来的位 置
free(begin); //释放时用原先保存的
p=NULL;
//二维数组的动态内存申请
//1.通过二级指针生成二维数组
//2.通过数组指针来生成
int(*p)[3]=NULL;
p=(int(*)[3])calloc(2,sizeof(int[3])); //p=(int(*)[3])calloc(数据个数,指针所指向的类型)
重新申请内存
//重新申请的内存需要比原先申请的内存大
int* num = (int*)malloc(4*3); //申请三个数据
//void* realloc(要修改的指针名,每个数据大小*数据数目)
int* p2 = (int*)realloc(num,4*4); //创建另一个指针判定
断言
#include <assert.h>
//作用判断指针是否为空,若为空则触发断点。可充当防御性编程
int* p =NULL;
assert(p); //p为空,中断程序
typedef用法
//给类型起别名
typedef int 整数;
整数 a = 0 ; //等效于 int a = 0
//给数组起别名
typedef int NUM[3];
NUM num; //此后 num 等效于 NUM
//给函数指针起别名
//typedef 返回值类型 新函数名 (函数参数)
typedef int (*Funtion)(int,int)
//Funtion 代表 int (*Funtion)(int,int)
函数指针
创建函数指针
//函数指针:指向函数首地址的指针
//*指针名 替换 函数名
int Max(int a , int b) //取最大值函数
{
return a > b ? a: b;
}
int main()
{
int(*p)(int a , int b);
p = NULL;
//(*指针名)替换函数名
//等效于 Max(int a,int b);
//函数指针调用可以省略形参,即可写作
int(*p)(int , int ); =NULL;
}
使用
int Max(int a , int b)
{
return a > b ? a: b;
}
int sum(int a, int b)
{
return a + b;
}
void print(int(*p)(int,int),int a ,int b)
{
printf("&d\n",p(1,3));
}
int main()
{
int(*p)(int , int ); =NULL;
//赋值
p = Max ; //直接用函数名赋值
p = &Max; //取地址
//调用函数
printf("%d\n",p(1,3)); //指针名代替函数名
printf("%d\n",*p(1,3));//*指针名代替函数名
//函数指针充当函数参数——回调函数
//实现多功能 统一调用接口
print(max,1,3); //通过以相应的函数指针为参数,实现多功能————对应 print指针所需参数
print(sum,1,3);
}