五、指针数组
指针数组本质上是数组,该类数组内存放的的元素是指针。
int* arr1[10]; //整形指针的数组
char *arr2[4]; //一级字符指针的数组
char **arr3[5];//二级字符指针的数组
六、数组指针
1、数组指针定义
数组指针本质上是指针,该类指针指向的是一个数组。
example:
int (*p)[10];
//解释:p先和*结合,说明p是一个指针变量,然后指着指向的是一个大小为10个整型的数组。所以p是一个
指针,指向一个数组,叫数组指针
2、数组指针&数组
首先需要看的是数组名与&数组名(可以等价于数组指针)之间的关系
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
printf("arr = %p\n", arr);
printf("&arr= %p\n", &arr);
printf("arr+1 = %p\n", arr+1);
printf("&arr+1= %p\n", &arr+1);
return 0;
}
在这里插入图片描述
根据上面的代码我们发现,其实&arr和arr,虽然值是一样的,但是意义应该不一样的。实际上: &arr 表示的是数组的地址,而不是数组首元素的地址。(细细体会一下)本例中 &arr 的类型是: int(*)[10] ,是一种数组指针类型数组的地址+1,跳过整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40
七、数组传参,指针传参
1、一维数组传参
数组传参会发生降维,最终传入的是首元素的地址(指针),并利用此来访问数组内其他元素。
#include <stdio.h>
void test(int arr[])//ok
{}
void test(int arr[10])//ok
{}
void test(int *arr)//ok
{}
void test2(int *arr[20])//不ok
{}
void test2(int **arr)//不ok
{}
int main()
{
int arr[10] = {0};
int *arr2[20] = {0};
test(arr);
test2(arr2);
}
2、二维数组传参
二维数组传参,函数形参的设计只能省略第一个[]的数字。
因为对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。
void test(int arr[3][5])//ok
{}
void test(int arr[][])//不ok
{}
void test(int arr[][5])//ok
{}
void test(int *arr)//不ok
{}
void test(int (*arr)[5])//ok
{}
void test(int* arr[5])//不ok
{}
void test(int **arr)//ok
{}
int main()
{
int arr[3][5] = {0};
test(arr);
}
3、一级指针传参
需要传入一个地址
#include <stdio.h>
void print(int *p, int size)
{
int i = 0;
for(i=0; i<size; i++)
{
printf("%d\n", *(p+i));
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9};
int *p = arr;
int size = sizeof(arr)/sizeof(arr[0]);
//一级指针p,传给函数
print(p, size);
return 0;
}
4、二级指针传参
#include <stdio.h>
void test(int** ptr)
{
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0;
}
八、函数指针
1、函数指针定义
函数指针是指指向函数而非指向对象的指针。像其他指针一样,函数指针也指向某个特定的类型(特定的函数类型)。函数类型由其返回类型以及形参表确定,而与函数名无关 。
代码在电脑中同样占据内存空间,所以具有存储地址,而代码部分在电脑中也是不可被修改的类似字符串常量。
在函数中,函数名单独时即为函数的地址(eg:main=&main),所以在用指针调用函数时,可以直接用指针调用不需要加*
Type (*pFunc)(datatype args);
//pFunc为函数指针,Type为数据类型,参数(datatype args)可以有多个,也可以没有。
使用示例
bool max(int a, int b)
{
if (a>b)
{
return a;
}else{
return b;
}
}
void Test()
{
bool (*pFunc)(int, double);
pFunc = max;
cout << max(5, 10) << endl;
}
九、函数指针数组
指针指向一个数组 ,数组的元素都是函数指针
使用方法: 把几个相同类型的函数地址放到一个数组中,这个数组就是函数指针的数组。
十、回调函数
解释:调用库中函数,但是库中函数需要编写程序时编写一个调用函数,该库中的函数为回调函数。也就是说一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
回调函数必须在中间函数以及回调函数同时具备时才可以实现。
作者:no.body
链接:https://www.zhihu.com/question/19801131/answer/27459821
来源:知乎
//大佬在这个帖子里对于概念解释的很好,可以做参考!
回调函数就是回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。