1.指针数组
指针数组:本质是数组,该数组中保存的是指针。
语法:
int a[5];
int *a[5];
int *:数组比重保存的数据类型,该数组中保存的元素是int *指针
[5]:该数组中可以保存5个指针(int *)
定义了一个可以保存5个整型指针的数组,整体占40个字节
char *p[5];
1.指针数组的定义
指针类型 数组名[元素个数];
2.指针数组的初始化
char *p[5] = NULL;
char *p[5] = {NULL};
将5个char类型指针初始化成NULL;
char *p = "hello";
char *p ={"hello","world","how","are","you"};
p[0] ==>char * ==>p[0]指针保存字符串常量"hello"的首地址
p[1] ==>char * ==>p[1]指针保存字符串常量"world"的首地址
p[2] ==>char * ==>p[2]指针保存字符串常量"how"的首地址
p[3] ==>char * ==>p[3]指针保存字符串常量"are"的首地址
p[5] ==>char * ==>p[40]指针保存字符串常量"you"的首地址
char *p1 = "hello";
char *p2 = "world";
char *p3 = "you";
char *p[3]={p1,p2,p3};
3.指针数组和二维字符型数组的区别
char str[3][100] ={"hello","world","how","are","you"};
sizeof(str) ==300字节;
char *ptsr[3] ={"hello","world","how","are","you"};
sizeof(pstr) ==3字节 *sizeof(char *) ==24字节
区别:
1.二维字符型数组中保存的是多个字符串本身;指针数组中保存的是多个字符串的首地址2.要保存多个字符串,用二维字符型数组,要操作多个字符串用指针数组
2.二级指针
二级指针:本质还是指针,是一个指针变量的地址。
int **指针名称;———>保存整型指针的指针
char **指针名称;———>保存字符型指针的指针
C语言中有两个二级指针的使用场景:
1.想要在被调函数中修改主调函数中的指针变量,实参需要传递该指针变量的地址,形参用二级指针接收。
2.指针数组的数组名,是一个二级指针,实参传递指针数组数组名时,形参用二级指针接收。
char *str[3]={"hello","world","how"};
str[0] ———>char * ———>保存了字符串常量"hello "的地址
str———>&str[0]——>char ** 二级指针
值传递:无法在被调中修改主调中的变量,只能使用该变量
指针传参:可以在被调中修改主调中定义的变量,也可以使用该变量
值传递:恰好传递的值是一个指针变量,无法在被调用修改主调中定义的指针变量,可以使用该指针变量。
指针传参:可以在被调函数中可以修改主调函数中定义的指针变量,也可以使用该变量
3.指针函数
指针函数:本质是函数,具有指针类型返回值的函数称为指针函数。
指针函数能返回什么指针?
1.局部变量的地址不能被返回(变量,数组)。
2.具有静态生命周期的变量的地址可以被返回。
1.satatic修饰的静态变量的地址。
2.全局变量。
3.可以返回字符串常量的地址。
4.可以返回通过参数传递给该函数的地址。
5.可以返回堆区申请且没有被释放的空间地址。
4.函数指针
函数指针:本质是指针,指向函数的指针。
函数:函数的函数名,为函数的入口地址。
语法:
1.定义函数指针
函数声明:
int fun(int ,int );
int *pfun(int , int);
函数指针:
int (*pfun)(int , int );
定义了一个函数指针变量,该指针变量在内存占8字节,该函数指针可以指向一个具有int类型返回值,两个int类型参数的函数。
char *(*pfun)(char *);
总结:
返回值类型 (*函数名)(形参表);
2.函数指针的初始化
int (*pfun)(int , int )=NULL;
3.函数指针赋值
int add(int num1,int num2)
{}
int (*pfun)(int , int )=NULL;
pfun=add;
4.函数指针调用函数
函数名(实参表);
函数指针名称(实参表);
5.函数指针的应用
- 回调函数:将函数作为某个函数的参数传递,传递的函数称为回调函数
主要为了降低代码的耦合度(关联少),减少重复代码