1、二级指针 |
2、指针数组 |
3、数组指针 |
4、函数指针 |
5、指针函数 |
指针的基础概念和用法相信大家都比较清楚,但还是让我简单诠释一下把。
#include<stdio.h>
int main()
{
int a = 10;
int* p = &a;
printf("%d",p);
return 0;
}
这就是最基础的指针用法,其中假设a的地址是0x11223344,那么p的值就是0x11223344,p就被我们成为指针变量,通过” * “解引用指向a。
让我们更深入一点,探讨一下二级指针,指针数组,数组指针,指针函数,函数指针的概念与使用。
先简单介绍一下二级指针,二级指针和一级指针类似,如果说一级指针中储存的是变量a的地址,那么二级指针储存的就是一级指针的地址,包括后面的三级,四级......等
int main()
{
int a = 10;//假设他的地址是0x11223344
int* p = &a;//p的值就是0x11223344
int** pp = &p;//假设p的地址是0x22334455,那么pp的值就是0x22334455
printf("%d , %d", *p, **pp);
return 0;
}
有了二级指针这道开胃小菜,那我们就可以更深入的分析其他指针类型了。
我们先看看指针数组 。
指针数组说到底也是一个数组,数组里面存放的是指针类型而已。
先让我们看看一个例子
int main()
{
int a = 10;
int b = 20;
int c = 30;
int* p[3];
p[0] = &a;
p[1] = &b;
p[2] = &c;
for (int i = 0; i < 3; i++)
{
printf("%d ", *p[i]);//结果为10 20 30
}
return 0;
}
我们可以看到p先和[]结合,所以他是个数组,数组里面的每个类型是int*,存放的是指针变量。至于为什么会先和[]结合,这是因为[]的优先级比*要高。
如果我们想先和*结合呢,那么这就是第二个内容,数组指针了。
如果我们想要一个数组指针,只需要加个()即可,
int (*arr)[3];//这是一个数组指针,初始化为了三个长度。
那么数组指针具体能干嘛呢 ,具体来说,访问二维数组才是数组指针发挥作用的地方。以上述数组指针初始化为例,在括号内部+1就代表跳过一个长度为3的的一维数组,下面是遍历数组指针的方法之一。
int main()
{
int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };
int(*p)[4] = arr;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", (*p + i)[j]);
}
printf("\n");
}
return 0;
}
如果难以理解这样遍历也可以
printf("%d ", p[i][j]);
有了数组指针后,我们就可以在函数中找到二维数组的地址并进行修改了。当然,数组指针还有更大的作用,这里我们不再深入赘述。
当我们理解了数组指针后,我们就会发现函数指针和数组指针竟惊人的相似。函数指针通常是这样定义的
int (*p)(int,int);
这样,我们就可以用这个指针指向一个函数了。
下面,假设我要用这个指针指向一个我编写的add函数,返回类型是int型的,那么该如何编写呢?
int add(int x, int y)
{
return x + y;
}
int main()
{
int (*p)(int, int) = add;
int ret = p(1, 2);
printf("%d", ret);//结果自然是3
return 0;
}
在这个方面我们可以稍微深入点,我们是否可以结合前面指针数组的知识编写一个存放指针的数组把指向函数的函数指针储存在里面呢?
int add(int x, int y)
{
return x + y;
}
int mul(int x, int y)
{
return x * y;
}
int main()
{
int(*pfarr[3])(int,int) = {NULL,add,mul};//这里我结合了指针数组和函数指针。
//注意到函数名也是地址,所以此方法才可以成立,否则应该加上取值符&
printf("输入你要选择的模式,1加法,2乘法\n");
int input = 0;
cin >> input;
printf("输入你要操作的两个数字\n");
int x, y;
cin >> x >> y;
int ret = pfarr[input](x, y);
printf("%d ", ret);
return 0;
}
请让我再介绍一种函数,回调函数。
何谓回调函数,在函数里调用函数就可以称之为回调函数,对于上述计算器,我们可以用回调函数的方式再编写一遍。
int add(int x, int y)
{
return x + y;
}
int mul(int x, int y)
{
return x * y;
}
void cal(int (*pf)(int, int))
{
printf("输入你要操作的两个数字\n");
int x, y;
cin >> x >> y;
int ret = pf(x, y);
cout << ret;
}
int main()
{
int input = 0;
printf("输入你要选择的模式,1加法,2乘法\n");
cin >> input;
switch (input)
{
case 1:cal(add);
break;
case 2:cal(mul);
break;
default:cout << "输入有误" << "\n";
}
return 0;
}
cal函数就是调用了add和mul函数。使用回调函数可以减少代码的不必要重复,使代码更加美观以及可读性更高。
那么什么叫做指针函数呢?
简单来说,指针函数是一种函数就,简单来说就是在定义完返回值之后加上一颗*。如果我们想返回一个void*的话,可以这样编写
void* pfunc(int* a)
{
*a = 20;
return (int*)a;
}
int main()
{
int a = 10;
cout << a << endl;//10
pfunc(&a);
cout << a << endl;//20
return 0;
}