概念:
数组指针是指针,指向数组的指针,例如int (*a)[10],a为指向10个int类型数据的指针,a存储的是数组的地址
指针数组是数组,存储指针的数组,例如int *a[5],a为数组,放了5个指向int类型数据的指针
函数指针是指针,指向函数的指针,例如double (*pa)(int),pa为指向函数的指针,pa存储的是函数的地址
指针函数是函数,返回值为指针的函数,例如double *pa(int),pa为函数,返回值为指向double类型数据的指针
理解与使用:
数组指针和指针数组
可以与二维数组相比较,比如一个2行3列的数组a[2][3]
当你用数组指针来完成
#include<iostream>
using namespace std;
int main()
{
int array[2][3];
int (*a)[3] = array;//a为行指针,a+i指向第i-1行
//也可以int (*a)[3]; a=array
//为数组赋值
cout << "Input" << endl;
for(int i = 0;i < 2;++i)
{
for(int j = 0;j < 3;++j)
{
cout << i+1 << "行" << j+1 << "列:";
cin >> *(*(a+i)+j);//i表示行,j表示列,
//cin >> (*(a+i))[j] 这样也可以
}
}
// 输出数组的值
cout << "Output" << endl;
for(int i = 0;i < 2;++i)
{
for(int j = 0;j < 3;++j)
{
cout << i+1 << "行" << j+1 << "列:";
cout << array[i][j];
cout << endl;
}
}
return 0;
}
当你用指针数组来完成
#include<iostream>
using namespace std;
int main()
{
int array[2][3];
int *a[2];//数组里放2个指针
//每个指针指向3个int类型数据的首地址
for(int i = 0;i < 2;++i)
a[i] = array[i];
//为数组赋值
cout << "Input" << endl;
for(int i = 0;i < 2;++i)
{
for(int j = 0;j < 3;++j)
{
cout << i+1 << "行" << j+1 << "列:";
cin >> *(*(a+i)+j);//i表示行,j表示列
}
}
// 输出数组的值
cout << "Output" << endl;
for(int i = 0;i < 2;++i)
{
for(int j = 0;j < 3;++j)
{
cout << i+1 << "行" << j+1 << "列:";
cout << array[i][j];
cout << endl;
}
}
return 0;
}
在对二维数组操作时两种方式对指针初始化方式不同(第二种不能直接用a = array,因为一个是一维数组,另一个是二维数组),引用是一样的,实质都是把a作为行指针使用,但理解可以有些许不同,第二种方式a+i是数组的第i-1个元素的地址,*(a+i)则是第i-1个元素,也就是指针,而加上j再次解引用则是取指针所指向的数组(这里说的数组为第二维数组)中的第j-1个值
函数指针与指针函数
函数指针指向的是某个函数,从而方便调用不同的函数
#include<iostream>
//函数原型
double Method_1(int);
double Method_2(int);
int Method_3(double);
void estimate(int,double (*p)(int));
/*
typedef double (*pa)(int);
void estimate(int,pa);
*/ //另一种写法
int main()
{
void estimate(2,Method_1);
void estimate(3,Method_2);
//void estimate(5,Method_3);错误,因为返回类型和参数列表类型不一致
return 0;
}
//省略
指针函数是使返回值为指针,从而使用这个指针的地址或者值
#include<iostream>
//函数原型
double *pam(double);
int main()
{
double *a = pam(2.3);//取得地址
cout << *a;//输出地址存储的值
return 0;
}
//省略
补充1:数组指针指向一维数组的情况
#include<iostream>
using namespace std;
int main()
{
int b[3] = {1,2,3};
int (*a)[3] = &b;
for (int i = 0; i < 3; ++i)
cout << &((*a)[i]) << ":" << (*a)[i] << endl;
return 0;
}
补充2:函数指针和指针数组以及数组指针一起使用的例子
#include<iostream>
using namespace std;
double add_1(double, double);
double add_2(double, double);
double add_3(double, double);
double calculate(double, double, double (*p)(double, double));
int main()
{
typedef double (*p_func)(double, double);//定义函数指针
p_func p[3] = {add_1, add_2, add_3};//放函数指针的数组
//等效为 double (*p[3])(double, double) = {add_1, add_2, add_3};
auto a = &p;//指向指针数组的指针
//等效为 p_func (*a)[3] = &p;或double (*(*a)[3])(double, double) = &p;
double x,y;
cout << "Enter x and y:";
cin >> x >> y;
for(int i = 0; i < 3; ++i)
{
cout << (*a)[i](x,y) << endl;
}
return 0;
}
double add_1(double x, double y)
{
return x+y;
}
double add_2(double x, double y)
{
return 2*x+y;
}
double add_3(double x, double y)
{
return x+2*y;
}
double calculate(double x, double y, double (*p)(double, double))
{
return (*p)(x,y);
}
总结
数组指针是指针,指针数组是数组,函数指针是指针,指针函数是函数
个人理解,数组指针是为了方便调用数组,指针数组是为了存放一系列指针,函数指针是为了方便调用函数,指针函数是为了取得指针类型的返回值。
可以这样判别:
int (*a)[3];//看的时候可以看成int b[3],int *a = &b;
int *a[3];//(int*)和a[3]
double (*p)(double);//double和 (*p)(double)
double *p(double);//double*和p(double)