- 1、指针函数:
-
- 指针函数是指带指针的函数,即本质是一个函数。我们知道函数都又返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针。其定义格式如下所示:
-
- 返回类型标识符 *返回名称(形式参数表)
-
- { 函数体 }
-
- 返
回类型可以是任何基本类型和复合类型。返回指针的函数的用途十分广泛。事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该
地址相当于一个指针。比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”。例如
下面一个返回指针函数的例子:
-
- 例一、
-
- #include<stdio.h>
-
- float *find(float(*pionter)[4],int n)
-
- {
-
- float *pt;
-
- pt=*(pionter+n);
-
- return(pt);
-
- }
-
- void main()
-
- {
-
- static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}};
-
- float *p;
-
- int i,m;
-
- printf("Enter the number to be found:");
-
- scanf("%d",&m);
-
- printf("the score of NO.%d are:\n",m);
-
- p=find(score,m);
-
- for(i=0;i<4;i++)
-
- printf("%5.2f\t",*(p+i));
-
- }
-
- 学生学号从0号算起,函数find()被定义为指针函数,起形参pointer是指针指向包含4个元素的一维数组的指针变量。pointer+1指向score的第一行。*(pointer+1)指向第一行的第0个元素。pt是一个指针变量,它指向浮点型变量。main()函数中调用find()函数,将score数组的首地址传给pointer.
-
- 例二、将字符串1(str1)复制到字符串2(str2),并输出字符串2
-
- #include <stdio.h>
-
- #include<stdlib.h>
-
- char * mystrcpy(char * str1,char * str2)
-
- {
-
- char * pr;
-
- pr=str2;
-
- if(*str2==NULL)
-
- exit(-1);
-
- while(*str1!=NULL)
-
- {
-
- *str2++=*str1++;
-
- }
-
- return pr;
-
- }
-
- void main()
-
- {
-
- char str1[]="I LOVE SHY";
-
- char str2[]="awenandy";
-
- char *p;
-
- p=mystrcpy(str1,str2);
-
- printf("%s\n",p);
-
- }
-
- 例三、
-
- #include<stdio.h>
-
- int * GetDate(int wk,int dy)
-
- {
-
- static int calendar[5][7]=
-
- {
-
- {1,2,3,4,5,6,7},
-
- {8,9,10,11,12,13,14},
-
- {15,16,17,18,19,20,21},
-
- {22,23,24,25,26,27,28},
-
- {29,30,31,-1,0}
-
- };
-
- return (&calendar[wk-1][dy-1]);
-
- }
-
- void main()
-
- {
-
- int wk,dy;
-
- do
-
- {
-
- printf("Enter week(1-5)day(1-7)\n");
-
- scanf("%d %d",&wk,&dy);
-
- }
-
- while(wk<1||wk>5||dy<1||dy>7);
-
- printf("%d",*GetDate(wk,dy));
-
- }
-
- 2 函数指针
-
- “函
数指针”是指向函数的指针变量,因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,
这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调
用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上一致的。函数指针有两个用途:调用函数和做函数的参数。函数指针的说明方法为:
-
- 函数类型 (*指针变量名)(形参列表);
-
- “函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少,后面的“形参列表”表示指针变量指向的函数所带的参数列表。
-
- 例如:
-
- int (*f)(int x);
-
- double (*ptr)(double x);
-
- 在定义函数指针时请注意:
-
-
-
- 函数指针和它指向的函数的参数个数和类型都应该是—致的;
-
- 函数指针的类型和函数的返回值类型也必须是一致的。
-
- 函数指针的赋值
-
- 函数名和数组名一样代表了函数代码的首地址,因此在赋值时,直接将函数指针指向函数名就行了。
-
- 例如,
-
- int func(int x);
-
- int (*f) (int x);
-
- f=func;
-
- 赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。
-
- 与
其他指针变量相类似,如果指针变量pi是指向某整型变量i的指针,则*p等于它所指的变量i;如果pf是指向某浮点型变量f的指针,则*pf就等价于它所
指的变量f。同样地,*f是指向函数func(x)的指针,则*f就代表它所指向的函数func。所以在执行了f=func;之后,(*f)和func代
表同一函数。
-
- 由于函数指针指向存储区中的某个函数,因此可以通过函数指针调用相应的函数。现在我们就讨论如何用函数指针调用函数,它应执行下面三步:
-
- 首先,要说明函数指针变量。
-
- 例如:int (*f)(int x);
-
- 其次,要对函数指针变量赋值。
-
- 例如: f=func; (func(x)必须先要有定义)
-
- 最后,要用 (*指针变量)(参数表);调用函数。
-
- 例如: (*f)(x);(x必须先赋值)
-
- 例一、
-
- #include<stdio.h>
-
- int max(int x,int y)
-
- { return(x>y?x:y);
-
- }
-
- void main()
-
- {
-
- int a,b,c;
-
- int (*ptr)(int,int);
-
- scanf("%d,%d",&a,&b);
-
- ptr=max;
-
- c=(*ptr)(a,b);
-
- printf("a=%d,b=%d,max=%d",a,b,c);
-
-
-
- }
-
- 例二、
-
- #include<stdio.h>
-
- void FileFunc()
-
- {
-
- printf("FileFunc\n");
-
- }
-
- void EditFunc()
-
- {
-
- printf("EditFunc\n");
-
- }
-
- void main()
-
- {
-
- void (*funcp)();
-
- funcp=FileFunc;
-
- (*funcp)();
-
- funcp=EditFunc;
-
- (*funcp)();
-
- }
-
- ptr
是指向函数的指针变量,所以可把函数max()赋给ptr作为ptr的值,即把max()的入口地址赋给ptr,以后就可以用ptr来调用该函数,实际上
ptr和max都指向同一个入口地址,不同就是ptr是一个指针变量,不像函数名称那样是死的,它可以指向任何函数,就看你像怎么做了。在程序中把哪个函
数的地址赋给它,它就指向哪个函数。而后用指针变量调用它,因此可以先后指向不同的函数,不过注意,指向函数的指针变量没有++和--运算,用时要小
心。
-
- 关于函数指针数组的定义
-
- 关于函数指针数组的定义方法,有两种:一种是标准的方法;一种是蒙骗法。
-
- 第一种,标准方法:
-
- {
-
- 分析:函数指针数组是一个其元素是函数指针的数组。那么也就是说,此数据结构是是一个数组,且其元素是一个指向函数入口地址的指针。
-
- 根据分析:首先说明是一个数组:数组名[]
-
- 其次,要说明其元素的数据类型指针:*数组名[].
-
- 再
次,要明确这每一个数组元素是指向函数入口地址的指针:函数返回值类型 (*数组名[])().请注意,这里为什么要把“*数组名[]”用括号扩起来呢?
因为圆括号和数组说明符的优先级是等同的,如果不用圆括号把指针数组说明表达式扩起来,根据圆括号和方括号的结合方向,那么 *数组名[]() 说明的是
什么呢?是元素返回值类型为指针的函数数组。有这样的函数数祖吗?不知道。所以必须括起来,以保证数组的每一个元素是指针。
-
- }
-
- 第二种,蒙骗法:
-
- 尽管函数不是变量,但它在内存中仍有其物理地址,该地址能够赋给指针变量。获取函数方法是:用不带有括号和参数的函数名得到。
-
- 函数名相当于一个指向其函数入口指针常量。 那么既然函数名是一个指针常量,那么就可以对其进行一些相应的处理,如强制类型转换。
-
- 那么我们就可以把这个地址放在一个整形指针数组中,然后作为函数指针调用即可。
-
- 完整例子:
-
- #include "stdio.h"
-
- int add1(int a1,int b1);
-
- int add2(int a2,int b2);
-
- void main()
-
- {
-
- int numa1=1,numb1=2;
-
- int numa2=2,numb2=3;
-
- int (*op[2])(int a,int b);
-
- op[0]=add1;
-
- op[1]=add2;
-
- printf("%d %d\n",op[0](numa1,numb1),op[1](numa2,numb2));
-
- }
-
- int add1(int a1,int b1)
-
- {
-
- return a1+b1;
-
- }
-
- int add2(int a2,int b2)
-
- {
-
- return a2+b2;
-
- }
-
- 再给出常用的C变量的定义方式:
-
- a) 一个整型数(An integer)
-
- b) 一个指向整型数的指针(A pointer to an integer)
-
- c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)
-
- d) 一个有10个整型数的数组(An array of 10 integers)
-
- e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)
-
- f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)
-
- g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)
-
- h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an
-
- integer )
-
- 答案是:
-
- a) int a;
-
- b) int *a;
-
- c) int **a;
-
- d) int a[10];
-
- e) int *a[10];
-
- f) int (*a)[10];
-
- g) int (*a)(int);
-
- h) int (*a[10])(int);
|