C/C++中函数指针和数组指针的一些个人理解
一、有关于数组名以及指针的一些联系与不同
在C/C++中数组名的本质上是一个指针,这导致了他很容易与一个单纯的指针弄混淆,同时也使得我们在很多情况下可以用访问一个指针的方式去访问一个数组,使得编程时的自由度很高。一下例举一些数组名和指针之间的相同之处。
- 本质上两者都是一个指针
- 都可以使用*的方式解引用访问其中的内容
- 都可以使用[n]的方式访问从当前位置起第n个元素,当前位置为0
- 都可以使用*(p+n)的形式访问从p起的第n个元素,当前位置为0
- 在一个函数参数需要接受一个数组或者指针时,传入同类型数组或者指针都是正确的
- 在赋值时数组名可以赋值给同类指针型并且可以正确访问
以下列举一些它们之间的不同之处
- 他们虽然同为指针,但是在编译器看来他们之间的意义截然不同
- 在使用sizeof时,指针返回一个固定的值(根据系统不同返回4或者8等),但是数组会返回整个数组的大小
- 数组名不能被赋值改变其内容,指针可以被改变
函数指针
函数指针顾名思义,就是指向一个函数的指针,其原理在于当程序开始执行每个函数都会获得一个地址,而这个地址就是函数体(函数代码)储存的位置,当一个函数被调用时,再从那个地址读取函数执行。函数名也是一个函数指针。函数指针的定义方式如下:
#include<stdio.h>
#define refptr(p) void(*p)(void)
void test(void)
{
printf("is ok\n");
}
int main()
{
/*void(*p)(void) = test;*/
refptr(p) = test;
p();
system("pause");
return 0;
}
以此可以很明显地看出函数指针的定义方式:
返回值(*指针名)(返回值)
函数指针的作用:
- 函数指针大多数时候是在仿函数中使用的,例如STL中就大量使用了该方法,大大提高了代码的可重用性
- 在一些程序中需要通过参数的传入使用不同的方法(如不同的排序方式,不同的比较方式等),这时将这些方法分别写在单独的函数中再通过参数的方式传入,既提高了代码的可读性,又提高了代码的可复用性
数组指针
数组指针顾名思义就是指向一个数组的指针,具体特点通过代码来讨论:
#include<iostream>
using namespace std;
int main()
{
int(*p)[3];
int a[2][3];
p = a;
cout << "p:" << p << endl;
cout << "p + 1:" << p + 1 << endl;
system("pause");
return 0;
}
运行结果:
显然,p+1比p大了12, 即当p被加一时指针向后移动了十二个字节刚好三个整型变量,即一个int[3]。所以大家明白了吗?
而且从上述代码可以看出:int[2][3] 类型的变量可以赋值给一个int(*)[3]的变量,说明他们的类型相同。即一个二维数组名的类型是一个如下的指针:
类型(*)[列数]