引言
C高级学习笔记(上)-CSDN博客整理了存储类型,宏定义相关知识,多文件编程,动态内存分配。本篇笔记将整理用户空间内存,指针函数和函数指针等相关知识。
一、用户空间内存
用户空间包含了堆区、栈区、静态区,而静态区还包含data段、bss段、text段、rodata段,除了用户空间还有个内核空间。
堆区是利用malloc函数手动分配,利用free函数手动释放,栈区是自动分配自动释放,保存局部变量,函数调用分配空间,data段保存已经初始化的全局变量,bss段保存未初始化的全局变量,text段是代码段,rodata段是只读数据段
二、指针函数和函数指针
2.1指针函数
指针函数是一个函数,函数的返回类型是一个指针
格式:
数据类型 *函数名(形参列表){
函数体;
}
2.2函数指针
函数指针是一个指针数据类型,函数指针指向的是一个具有相同的形参列表、相同返回类型的函数
格式:
数据类型 函数名(形参列表){ //函数的名字就可以表示函数的入口地址
函数体;
}
数据类型 (*函数指针变量名字)(形参列表) = 函数名;
调用函数时可以通过函数的原型直接调用,也可以通过函数指针进行调用。
2.3回调函数
回调函数就是指,函数指针作为另外一个函数的形参,在此函数中就可以回调通过函数指针传递的函数
2.4函数指针数组
函数指针数组本身是一个数组,数组的每一个成员是一个函数指针
2.4.1格式:
数据类型 (*函数指针的数组名[成员个数])(形参列表);
2.4.2初始化的方式
函数指针数组的初始化分为两种,一种是定义的同时进行初始化操作,另一种是先定义后进行初始化的操作
定义的同时进行初始化的操作格式
数据类型 (*函数指针的数组名[成员个数])(形参列表) = {函数名0,函数名1,……}
先定义后进行初始化的操作
数据类型 (*函数指针的数组名[成员个数])(形参列表);
函数指针的数组名[0] = 函数名0;
函数指针的数组名[1] = 函数名1;
函数指针的数组名[2] = 函数名2;
……
访问函数指针数组中的成员:
如果有返回值: 变量名 = 函数指针数组名[下标](实参列表);
如果没有返回值: 函数指针数组名[下标](实参列表);
三、函数指针数组指针
函数指针数组指针本身是一个指针,指向的是一个函数指针数组,函数指针数组中函数指针指向的是一个函数
格式:
数据类型 (*(*函数指针数组指针变量名[成员个数]))(形参列表);
初始化:
定义函数指针数组:
数据类型 (*函数指针数组名[成员人数])(形参列表) = {函数名0,函数名1,……};
定义函数指针数组指针并初始化:
数据类型 (*(*函数指针数组指针变量名1)[成员人数])(形参列表) = &函数指针数组名;
数据类型 (*(*函数指针数组指针变量名2))(形参列表) = 函数指针数组名;
使用说明:
(*函数指针数组指针变量名1)[0](实参列表);
(*函数指针数组指针变量名2)[1](实参列表);
…………
函数指针数值指针变量名2[0](实参列表);
函数指针数组指针变量名2[1](实参列表);
四、数据类型起别名(typedef)
4.1 typedef的使用
将typedef写到定义变量的前面,此时变量名就是新定义的数据类型,可以使用新的数据类型定义变量,使用typedef对数据类型起别名,使用别名定义变量和使用本身代表的类型定义变量一样。例如:基本的数据类型 typedef int myint32_t
4.2 typedef 和 #define的区别
#define宏定义对数据类型起别名在预处理阶段展开,typedef对数据类型起别名参与了编译的阶段。
使用typedef对数据类型起别名相当于重新定义了一个新的数据类型,宏定义就是在预处理阶段进行替换。
注意:在编写上宏定义的结尾不允许出现分号,typedef的结果必须加分号。