函数指针和指针函数有什么区别 (函数指针和指针函数用法和区别)
本文目录导航:
函数指针和指针函数有什么区别?
函数指针和指针函数的区别:\x0d\x0a一、【函数指针】\x0d\x0a 在程序运转中,函数代码是程序的算法指令局部,它们和数组一样也占用存储空间,都有相应的地址。
可以经常使用指针变量指向数组的首地址,也可以经常使用指针变量指向函数代码的首地址,指向函数代码首地址的指针变量称为函数指针。
\x0d\x0a1、函数指针定义 \x0d\x0a函数类型(*指针变量名)(形参列表); \x0d\x0a“函数类型”说明函数的前往类型,因为“()”的优先级高于“*”,所以指针变量名外的括号必无法少,前面的“形参列表”示意指针变量指向的函数所带的参数列表。
\x0d\x0a例如: \x0d\x0aint (*f)(int x); \x0d\x0adouble (*ptr)(double x); 在定义函数指针时请留意:\x0d\x0a函数指针和它指向的函数的参数个数和类型都应该是—致的; 函数指针的类型和函数的前往值类型也必定是分歧的。
\x0d\x0a2、函数指针的赋值 \x0d\x0a函数名和数组名一样代表了函数代码的首地址,因此在赋值时,间接将函数指针指向函数名就行了。
例如, \x0d\x0aint func(int x); /* 申明一个函数 */ \x0d\x0aint (*f) (int x);/* 申明一个函数指针 */ \x0d\x0af=func;/* 将func函数的首地址赋给指针f */ \x0d\x0a赋值时函数func不带括号,也不带参数,因为func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。
\x0d\x0a3、经过函数指针调用函数 \x0d\x0a函数指针是经过函数名及无关参数启动调用的。
\x0d\x0a与其余指针变量相相似,假设指针变量pi是指向某整型变量i的指针,则*p等于它所指的变量i;假设pf是指向某浮点型变量f的指针,则*pf就等价于它所指的变量f。
雷同地,*f是指向函数func(x)的指针,则*f就代表它所指向的函数func。
所以在口头了f=func;之后,(*f)和func代表同一函数。
\x0d\x0a因为函数指针指向存储区中的某个函数,因此可以经过函数指针调用相应的函数。
如今咱们就探讨如何用函数指针调用函数,它应口头上方三步: 首先,要说明函数指针变量。
\x0d\x0a例如:int (*f)(int x); \x0d\x0a其次,要对函数指针变量赋值。
\x0d\x0a例如: f=func;(func(x)必定先要有定义) \x0d\x0a最后,要用 (*指针变量)(参数表);调用函数。
\x0d\x0a例如:(*f)(x);(x必定先赋值) \x0d\x0a【例】恣意输入n个数,找出其中最大数,并且输入最大数值。
\x0d\x0amain() \x0d\x0a{ \x0d\x0aint f(); \x0d\x0a int i,a,b; \x0d\x0aint (*p)();/* 定义函数指针 */ \x0d\x0ascanf(%d,&a); \x0d\x0ap=f;/* 给函数指针p赋值,使它指向函数f */ \x0d\x0afor(i=1;i<9;i++)\x0d\x0a{ \x0d\x0ascanf(%d,&b); \x0d\x0aa=(*p)(a,b);/* 经过指针p调用函数f */\x0d\x0a }\x0d\x0a printf(The Max Number is:%d,a) \x0d\x0a} \x0d\x0a \x0d\x0af(int x,int y) \x0d\x0a{\x0d\x0a int z;\x0d\x0a z=(x>y)?x:y;\x0d\x0a return(z); \x0d\x0a} \x0d\x0a运转结果为: \x0d\x0a343 -45 4389 4235 1 -534 988 555 789_ The Max Number is:4389 \x0d\x0a \x0d\x0a二、【指针函数】 \x0d\x0a一个函数不只可以带回一个整型数据的值,字符类型值和实型类型的值,还可以带回指针类型的数据,使其指向某个地址单元。
\x0d\x0a 前往指针的函数,普通定义格局为: \x0d\x0a 类型标识符*函数名(参数表)\x0d\x0aint *f(x,y); \x0d\x0a其中x,y是方式参数,f是函数名,调用后前往一个指向整型数据的地址指针。
f(x,y)是函数,其值是指针。
\x0d\x0a如:char *ch();示意的就是一个前往字符型指针的函数,请看上方的例题: \x0d\x0a【例】将字符串1(str1)复制到字符串2(str2),并输入字符串2. \x0d\x0a#include stdio.h\x0d\x0a main() \x0d\x0a{\x0d\x0achar *ch(char *,char *); \x0d\x0achar str1[]=I am glad to meet you!; \x0d\x0achar str2[]=Welcom to study C!; \x0d\x0aprintf(%s,ch(str1,str2)); \x0d\x0a} \x0d\x0achar *ch(char *str1,char *str2) \x0d\x0a{\x0d\x0a int i; \x0d\x0achar *p; \x0d\x0ap=str2\x0d\x0aif(*str2==NULL) exit(-1); \x0d\x0ado \x0d\x0a{\x0d\x0a*str2=*str1; \x0d\x0astr1++;\x0d\x0astr2++; \x0d\x0a}\x0d\x0awhile(*str1!=NULL); \x0d\x0areturn(p); \x0d\x0a} \x0d\x0a经过分析可得: \x0d\x0a函数指针是一个指向函数的指针,而指针函数只是说明他是一个前往值为指针的函数, 函数指针可以用来指向一个函数。
函数指针和指针函数用法和区别
在C言语学习中,函数指针和指针函数是常被提及的概念,尤其对初学者来说,了解它们的用法和区别是一项应战。
实践上,复杂的相关概念如函数指针函数、指针数组等对实践编程或者并不经常出现,因此,咱们先从基础的两个概念入手,它们在名目中更为适用。
指针函数
指针函数的基本定义是前往指针的函数。
申明时,方式为*类型标识符 函数名(参数表),例如,一个前往整型指针的函数申明可以写为:int* fun(int x, int y)。
这个函数与普通函数的不同在于,它的前往值是一个地址,而非数值。
在经常使用时,须要一个同类型的指针来接纳前往值。
函数指针
函数指针则是指针变量,它指向一个函数。
申明为类型说明符 (*函数名)(参数),如int (*fun)(int x, int y),区别在于这里的星号是在类型前面,代表它是一个指向函数的指针。
函数指针须要明白地给它赋一个函数的地址,调用方式有两种,明白经过指针调用更介绍。
区别总结
关键区别在于定义:指针函数是函数自身能前往指针,而函数指针是寄存函数地址的指针。
写法上,指针函数的星号在类型前面,函数指针的星号在函数名前。
便捷的区分方法是:带括号的函数名是函数指针,反之则是指针函数。
在实践运行中,了解这两个概念的经常使用方法至关关键,防止混杂。
经过详细示例,可以更好地把握它们的用法。
C言语中函数指针用法
函数在内存中有一个物理位置,而这个位置是可以赋给一个指针的。
一零点函数的地址就是该函数的入口点。
因此,函数指针可被用来调用一个函数。
函数的地址是用不带任何括号或参数的函数名来获取的。
(这很相似于数组地址的获取方法,即,在只要数组名而无下标是就获取数组地址。
)怎么说明一个函数指针变量呢 ?为了说明一个变量 fn_pointer 的类型是前往值为 int 的函数指针, 你可以经常使用上方的说明语句:int (*fn_pointer) ();为了让编译器能正确地解释这句语句, *fn_pointer 必定用括号围起来。
若漏了这对括号, 则:int *fn_pointer ();的意思齐全不同了。
fn_pointer 将是一个函数名, 其前往值为 int 类型的指针。
2:函数指针变量在C言语中规则,一个函数总是占用一段延续的内存区, 而函数名就是该函数所占内存区的首地址。
咱们可以把函数的这个首地址 ( 或称入口地址 ) 赋予一个指针变量, 使该指针变量指向该函数。
而后经过指针变量就可以找到并调用这个函数。
咱们把这种指向函数的指针变量称为 函数指针变量 。
函数指针变量定义的普通方式为:类型说明符 (* 指针变量名 )();其中 类型说明符 示意被指函数的前往值的类型。
(* 指针变量名 ) 示意 * 前面的变量是定义的指针变量。
最后的空括号示意指针变量所指的是一个函数。
例如: int (*pf)();示意 pf 是一个指向函数入口的指针变量,该函数的前往值 ( 函数值 ) 是整型。
上方经过例子来说明用指针方式成功对函数调用的方法。
int max(int a,int b){if(a>b)return a;else return b;}main(){int max(int a,int b);int(*pmax)();int x,y,z;pmax=max;printf(input two numbers:/n);scanf(%d%d,&x,&y);z=(*pmax)(x,y);printf(maxmum=%d,z);}从上述程序可以看出用,函数指针变量方式调用函数的步骤如下:1>. 先定义函数指针变量,如后一程序中第 9 行 int (*pmax)(); 定义 pmax 为函数指针变量。
2>. 把被调函数的入口地址 ( 函数名 ) 赋予该函数指针变量,如程序中第 11 行 pmax=max;3>. 用函数指针变量方式调用函数,如程序第 14 行 z=(*pmax)(x,y); 调用函数的普通方式为: (* 指针变量名 ) ( 实参表 ) 经常使用函数指针变量还应留意以下两点:a. 函数指针变量不能启动算术运算,这是与数组指针变量不同的。
数组指针变量加减一个整数可使指针移动指向前面或前面的数组元素,而函数指针的移动是毫有意义的。
b. 函数调用中 (* 指针变量名 ) 的两头的括号无法少,其中的 * 不应该了解为求值运算,在此处它只是一种示意符号。
3:指针型函数前面咱们引见过,所谓函数类型是指函数前往值的类型。
在C言语中准许一个函数的前往值是一个指针 ( 即地址 ) ,这种前往指针值的函数称为指针型函数。
定义指针型函数的普通方式为:类型说明符 * 函数名 ( 形参表 ){…… /* 函数体 */}其中函数名之前加了 * 号标明这是一个指针型函数,即前往值是一个指针。
类型说明符示意了前往的指针值所指向的数据类型。
如:int *ap(int x,int y){…… /* 函数体 */}示意 ap 是一个前往指针值的指针型函数, 它前往的指针指向一个整型变量。
下例中定义了一个指针型函数 day_name ,它的前往值指向一个字符串。
该函数中定义了一个静态指针数组 name 。
name 数组初始化赋值为八个字符串,区分示意各个星期名及出错揭示。
形参 n 示意与星期名所对应的整数。
在主函数中, 把输入的整数 i 作为实参, 在 printf 语句中调用 day_name 函数并把 i 值传送给形参 n 。
day_name 函数中的 return 语句蕴含一个条件表白式, n 值若大于 7 或小于 1 则把 name[0] 指针前往主函数输入出错揭示字符串 Illegal day 。
否则前往主函数输入对应的星期名。
主函数中的第 7 行是个条件语句,其语义是,如输入为正数 (i<0) 则停止程序运转分开程序。
exit 是一个库函数, exit(1) 示意出现失误后分开程序, exit(0) 示意反常分开。
应该特意留意的是函数指针变量和指针型函数这两者在写法和意义上的区别。
如 int(*p)() 和 int *p() 是两个齐全不同的量。
int(*p)() 是一个变量说明,说明 p 是一个指向函数入口的指针变量,该函数的前往值是整型量, (*p) 的两头的括号不能少。
int *p() 则不是变量说明而是函数说明,说明 p 是一个指针型函数,其前往值是一个指向整型量的指针,*p 两头没有括号。
作为函数说明, 在括号内最好写入方式参数,这样便于与变量说明区别。
关于指针型函数定义,int *p() 只是函数头局部,普通还应该有函数体局部。
main(){int i;char *day_name(int n);printf(input Day No:/n);scanf(%d,&i);if(i<0) exit(1);printf(Day No:%2d-->%s/n,i,day_name(i));}char *day_name(int n){static char *name[]={ Illegal day,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};return((n<1||n>7) ? name[0] : name[n]);}本程序是经过指针函数,输入一个 1 ~ 7 之间的整数, 输入对应的星期名。
指针数组的说明与经常使用一个数组的元素值为指针则是指针数组。
指针数组是一组有序的指针的汇合。
指针数组的一切元素都必定是具备相反存储类型和指向相反数据类型的指针变量。
指针数组说明的普通方式为: 类型说明符 * 数组名 [ 数组长度 ]其中类型说明符为指针值所指向的变量的类型。
例如: int *pa[3] 示意 pa 是一个指针数组,它有三个数组元素, 每个元素值都是一个指针,指向整型变量。
理论可用一个指针数组来指向一个二维数组。
指针数组中的每个元素被赋予二维数组每一行的首地址,因此也可了解为指向一个一维数组。
图 6—6 示意了这种相关。
int a[3][3]={1,2,3,4,5,6,7,8,9};int *pa[3]={a[0],a[1],a[2]};int *p=a[0];main(){int i;for(i=0;i<3;i++)printf(%d,%d,%d/n,a[i][2-i],*a[i],*(*(a+i)+i));for(i=0;i<3;i++)printf(%d,%d,%d/n,*pa[i],p[i],*(p+i));}本例程序中, pa 是一个指针数组,三个元素区分指向二维数组 a 的各行。
而后用循环语句输入指定的数组元素。
其中 *a[i] 示意 i 行 0 列元素值; *(*(a+i)+i) 示意 i 行 i 列的元素值; *pa[i] 示意 i 行 0 列元素值;因为 p 与 a[0] 相反,故 p[i] 示意 0 行 i 列的值; *(p+i) 示意 0 行 i 列的值。
读者可细心体会元素值的各种不同的示意方法。
应该留意指针数组和二维数组指针变量的区别。
这两者只管都可用来示意二维数组,然而其示意方法和意义是不同的