函数是存放在代码区,当然也有内存地址,要注意函数存放在代码区,函数里面定义的变量(包括形参,形参是局部变量)都是定义在栈区。里面用的字符串常量则保存在字符串专门的存储空间。
函数指针
数组指针针对不同的数值进行定义:int (*x)[4]; int (*y)[5]; 分别指向大小为4、5的数组。函数指针也一样,针对不同的函数来定义指针。语法:
函数类型 (* 函数指针名) (形参列表);
#include <iostream>
#include <stdio.h>
using namespace std;
void fun(int (*x)[4])
{
int i,j;
for(i=0;i<5;i++)
for(j=0;j<4;j++)
x[i][j]=i * j;
}
int main()
{
int a[5][4];
int i,j;
void (*lp)(int (*)[4]);
lp=&fun;
lp(a);
for(i=0;i<5;i++)
{
for(j=0;j<4;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
void (*lp)(int (*)[4]); 可以理解为定义了一个 返回类型为void ; 形参为 int (*)[4] 的函数模板,模板名称为lp ;当然这个模板是指针,取函数地址 & fun 与普通变量方法类似;函数指针调用 模板+实参 lp(a)
问题:fun(a) 就可以,何必用lp(a) ?
通用性一直是代码追求的目标,实现一个用户可以自己指定排序规则的函数,当然比针对特定数据排序更强大,比如:整数与复数通过同一给函数排序。
函数指针则有了用武之地,排序函数可以增加一个指定的函数指针(当然可以带默认值,比如数值类型的直接用通用方法)格式基本如下:
bool (* fun) (T x,T y) ;
T当然就是模板类型,形参x, y 表明该数据类型T进行比较的值,返回值可以为布尔或int类型
这样的函数指针,即可以用默认的比较函数来实现,当然也可以自定义来完成。在STL里有很多这样的例子。
从函数指针(C++纯虚类、函数重载等等机制)可以发展到了所谓的“接口编程”,也就是说系统提供通用的接口,程序员自己来具体实现,有点像电脑自带USB接口,则可以连接U盘、键盘、鼠标、移动硬盘等符合USB接口要求的设备,达到通用的目的。
函数指针 数组 、指针
函数指针语法上等价于普通指针,既然有指针数组,当然也会有函数指针的数组。语法:
函数类型 (* 函数指针名 [常量表达式] ) (形参列表);
#include <iostream>
#include <stdio.h>
using namespace std;
void fun(int (*x)[4])
{
int i,j;
for(i=0;i<5;i++)
for(j=0;j<4;j++)
x[i][j]=i * j;
}
int main()
{
int a[5][4];
int i,j;
void (*lp)(int (*)[4]);
void (*xp[2])(int (*)[4]);
lp=&fun;
xp[0]=lp;
xp[0](a);
for(i=0;i<5;i++)
{
for(j=0;j<4;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
不仅仅是数组,而且可以是函数指针的指针(二维指针)
#include <iostream>
#include <stdio.h>
using namespace std;
typedef void (*T)(int (*)[4]);
void fun(int (*x)[4])
{
int i,j;
for(i=0;i<5;i++)
for(j=0;j<4;j++)
x[i][j]=i * j;
}
int main()
{
int a[5][4];
int i,j;
T lp;
T *xp;
lp=&fun;
xp = new T[2];
xp[0]=lp;
xp[0](a);
for(i=0;i<5;i++)
{
for(j=0;j<4;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
return 0;
}
typedef void (*T)(int (*)[4]); 是类型定义,也就是给类型取别名,这里定义了一个T的类型名称,它是指向一个 void 函数名 (int (*)[4]) 函数 的指针类型。