再论函数指针、函数指针数组

一、基本概念
数组名:本质是指向数组第一个元素的常量指针,即数组首地址
函数名:本质是指向函数第一条指令的常量指针,即函数首地址
函数指针:保存了函数首地址,可以看做函数的别名

二、函数指针的声明方法
type (*func)(type &, type &)
1、该语句声明了一个指针func,它指向了一个函数;
2、该函数带有2个type型参数,并返回一个type型的值;
p.s. tpye类型可以看做int或者float等C++类型
3、可以把整个函数看做一个数据类型
tpye func(type, type)
指针变量func就指向这样的数据类型

三、注意事项
1、一个指向函数的指针必须保证该函数被定义了,且被分配了内存,
否则它指向一个空地址,这可是大忌!
2、特别注意第一个括号的位置,如果把括号去掉
type *func(type &, type &)
就变成了一个返回type *类型的函数了

四、函数指针应用举例
1、通过函数指针调用函数
# include <stdio.h>
void f(int x)
{
printf("%d\n", x);
}
int main()
{
f(10); //直接调用函数f
void (*p)(int); //定义一个函数指针p
p = f; //对指针变量p赋值,函数名f即为函数首地址 ,p=&f也正确
(*p)(20); //通过指针而非函数名调用函数
return 0;
}
2、函数指针的typedef用法
typedef void (*PINT)(int) ; //声明该函数结构void f(int)为一个数据类型
PINT是该数据类型的名字
//注意区别于结构体的typedef用法
PINT p;
p = f;
3、函数指针作为函数参数
设计一个CallMyFun函数,这个函数可以通过参数中的函数指针值不同来分别调用
MyFun1、MyFun2、MyFun3这三个函数(注:这三个函数的定义格式应相同)。
# include <stdio.h>
typedef void (*PM)(int); //定义新的函数数据类型为PM
void CallMyfun(PM p, int x) //函数指针作为形参
{
p(x);
}
void MyFun1(int x)
{
printf("MyFun1 = %d\n", x);
}
void MyFun2(int x)
{
printf("MyFun2 = %d\n", x);
}
void MyFun3(int x)
{
printf("MyFun3 = %d\n", x);
}
int main()
{
CallMyfun(MyFun1, 10);
CallMyfun(MyFun2, 20);
CallMyfun(MyFun3, 30);
return 0;
}

五、再次深入学习
1、*(int*)&p ----这是什么?
void Function()
{
  printf("Call Function!\n");
}<br>
int main()
{
  void (*p)(); //定义函数指针变量p
  *(int*)&p=(int)Function;//&p求指针变量p的地址,这是一个32位的二进制数
//(int *)&p表示将地址强制转化为指向int型数据的指针
//(int)Function表示将函数入口地址强制转换成int型数据
  (*p)();
  return 0;
} 
2、(*(void (*)(void))(0x30700000)()--这是什么?
void (*reset)(void) = (void (*)(void))0
reset();
等式左边为定义函数指针reset;
等式右边为强制类型转换,将数值“0”强行转换为函数指针地址“0”;
下一句表示调用函数reset(),从地址"0"处开始执行;
举例:
void (*theUboot)(void); //定义函数指针theUboot
theUboot = (void (*)(void))(0x30700000);//将绝对地址0x30700000
强制转换为函数指针地址,然后赋给theUboot
theUboot(); //调用函数theBoot()

p.s.以上代码可以合并为下面一行代码:
(*(void (*)(void))(0x30700000)();
3、总结
其实函数指针与普通指针没什么差别,只是指向的内容不同而已。
使用函数指针的好处在于,可以将实现同一功能的多个模块统一起来标识,这样一来更容易后期的维护,系统结构更加清晰。或者归纳为:便于分层设计、利于系统抽象、降低耦合度以及使接口与实现分开。

六、函数指针数组
例:char * (*pf[3])(char *)
函数指针数组本质是一个数组,这里pf就是数组名;
该数组有3个元素pf[0]、pf[1]、pf[2],分别存放了3个函数指针;
指向的3个函数的返回值都是 char *,形参都是 char *;
程序示例:
# include <stdio.h>
void fun1(char * p)
{
printf("%s\n", p);
}
void fun2(char * p)
{
printf("%s\n", p);
}
void fun3(char * p)
{
printf("%s\n", p);
}
int main()
{
void (*pf[3])(char *); //定义函数指针数组
pf[0] = fun1;
pf[1] = fun2;
pf[2] = fun3;
pf[0]("fun1"); //形参为字符串"fun1",传递给形参字符串首地址
pf[0]("fun2");
pf[0]("fun3");
return 0;
}

七、函数指针数组指针
例 char * (*(*pf)[3])(char * p);
函数指针数组指针本质是一个指针;
该指针指向一个数组;
该数组里面存放的都是指向函数的指针;
程序示例:
#include <stdio.h>
#include <string.h>

char * fun1(char * p)
{
printf("%s\n",p);
return p;
}

char * fun2(char * p)
{
printf("%s\n",p);
return p;
}

char * fun3(char * p)
{
printf("%s\n",p);
return p;
}

int main()
{
char * (*a[3])(char * p);
char * (*(*pf)[3])(char * p);
pf = &a;

a[0] = fun1;
a[1] = &fun2;
a[2] = &fun3;

pf[0][0]("fun1");
pf[0][1]("fun2");
pf[0][2]("fun3");
return 0;
}

时间: 2024-11-06 07:39:14

再论函数指针、函数指针数组的相关文章

数组指针、指针数组、函数指针、指针函数 -----笔记

1.数组的四种访问方式 定义数组 a[]; 指针 *p 指向数组a; (1) 利用数组的下表进行访问 a[i]; (2) 数组名+地址的偏移量i *(a+i) (3) 利用指针 p 进行下表访问 p[i] (4) 指针p + 地址的偏移量i *(p+i) 一维数组数组名:相当于一个单指针 2. 数组指针(指针)     指针数组(数组) 函数指针(指针)     指针函数(函数)    -------->只看后边两个字就能够区分是指针还是数组或函数 _______________________

指针数组,数组指针、指针函数,函数指针

听到这几个名词不知道大家什么感受,反正我是一脸懵逼,不过我还是比较好学的,在老师的指导下,自己下去也钻研了一下,有一些自己的见解,我想在学习过程中也有童鞋遇到了相同的问题,希望我的总结能给你带来帮助. 首先我们想明确一下这几个概念,知道他们都表示什么,ok,请看: 函数指针:函数指针是指向函数的指针变量. 因而"函数指针"本身首先应是指针变量,只不过该指针变量指向函数.这正如用指针变量可指向整型变量.字符型.数组一样,这里是指向函数.如前所述,C在编译时,每一个函数都有一个入口地址,该

指针数组vs数组指针 指针函数vs函数指针

在分辨这些重要的概念时,我们先回顾一下前面所讲的C之三值合一,由于三个值所求出的地址是相同的,所以经常有传言说他们都是首元素的地址.这种说法是不正确的.为什么说它是不正确的呢? 首先定义一个指针,将三个值赋给它 *p=ar; *p=&ar[0]; *p=&ar//出错 程序编译后在表达式*p=&ar时出错,说明ar并不是指针类型.ar是数组名代表的是整个空间,因此ar应该是数组指针. 这四个概念看起来很容易混淆,但实际上只需要记住再看这些概念的时候先看后两个字,就可以看出它的类型,

指针数组,数组指针,指针函数,函数指针,二级指针详解

先看个简单的:char *p,这定义了一个指针,指针指向的数据类型是字符型,char  *(p)定义了一个指针P: char *p[4], 为指针数组,由于[]的优先级高于*,所以p先和[]结合,p[]是一个数组,暂时把p[]看成是q,也就是char *(q),定义了一个指针q,只不过q是一个数组罢了,故定义了一个数组,数组里面的数据是char *的,所以数组里面的数据为指针类型.所以char *p[4]是四个指针,这四个指针组成了一个数组,称为指针数组,既有多个指针组成的数组. char(*p

再议指针---------函数回调(qsort函数原理)

我们能否写一个这样的函数: 可以对任何类型数据排序 任何人在使用该函数不需要修改该函数代码(即:用户可以不必看到函数源 码,只会调用就行) 思考: 用户需要排序的数据的类型千变万化,可能是int型,也有可能是自定义的结构体类型,各种类型的大小比较规则是不一样的,这样看来实现一个这样全能的排序函数似乎不可能. 但具体需要排序的类型应按照什么规则确定大小只有使用该函数的用户最清楚,那我们可不可以把实现比较大小的功能交给用户来完成了,到时候用户只需告诉该函数比较规则(函数)在什么位置,这样排序函数不就

关于复杂指针数组,函数以及函数指针,数组思考

指针数组其实是数组,只不过是数组里面放着指针如int *p[],由于中括号的优先级高于星号,所以p先与中括号结合形成数组,然后再与星号结合形成指针数组,即每一个数组元素是一个指向整形数据的指针.而数组指针实际上是指向数组的指针如int(*p)[]. 同理函数指针是指向一个函数的指针,指针函数是说这个指针指向了一个函数如int(*fun)(int) ,而函数指针则意味着它是一个函数,这个函数的返回值是一个指针,如int * fun(intx).因此通过这个规律我们可以理解更深层次的更复杂的指针,

指针 函数指针 指针数组

指针变量的分析原则:从变量名起,根据运算符优先级结合,一步一步分析.(从p开始后要把小括号去掉) 指针,指向什么(X),X是什么类型的 Int *p;   //首先从P处开始,先与*结合,说明P是一个指针,然后再与int结合,说明指针所指向的内容的类型为int型,所以P是一个返回整形数据的指针 Int *p[3]; //首先从P处开始,先与[]结合所以P是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与Int结合,说明指针所指向的内容类型是整形的,所以,P是一个由返回整形数据的指针

C语言 指针基础篇 数组,函数与指针的运用 2 14

下面看看如何在函数中运用指针吧 下面是往函数传入指针的简单操作,不是传入数组的.判断一个a是否大于b是的话给,是的话对其进行操作,不是的话就直接返回. 1 #include <stdio.h> 2 int main(){ 3 int num1,num2,*p1,*p2; 4 p1 = &num1,p2=&num2; 5 scanf("%d%d",&num1,&num2); 6 7 int fun(int *n1,int *n2); //我们在

C++——指针---指向数组的指针---指向字符串的指针--指向函数的指针--指针的指针--指针的引用

一.指向数组的指针 代码示例1: 1 int main() 2 { 3 int a[10]={0,2,4,6,8,10,12,14,16,18}; 4 int *p; 5 for(p=&a[0];p<&a[0]+10;p++) 6 printf("%d ",*p); 7 } 代码示例2: int a[10]={0,2,4,6,8,10,12,14,16,18}; int *p; p=a; printf("%d\n",*(a+5));//注意加括

【C/C++学院】0726-cppIDE/一级指针/指针数组/函数指针/函数指针数组/二级指针

[送给在路上的程序员] 对于一个开发者而言,能够胜任系统中任意一个模块的开发是其核心价值的体现. 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步. 对于一个开发团队而言,能在短期内开发出用户满意的软件系统是起核心竞争力的体现. 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我. cppIDE 使用mfc和codeblocks中的mingw编译器.执行system命令中的bat批处理脚本. 一级指针 指针,结构体struct,