指向函数的指针变量

合集下载

C语言:指针变量

C语言:指针变量

C语言:指针变量声明指针变量:基数据类型 * 指针变量名如 int *p ;例:int *p1, *p2;p1和p2是int型指针变量,可以指向int型变量或int数组元素。

char *p3 ; p3是char型指针变量,可以指向char型变量或char数组元素。

指针变量可用来表示它所指向的变量(或数组元素)。

所指向变量的数据类型必须和指针变量的基数据类型相同。

(注:还可声明指向数组、结构、和函数等的指针变量。

)为了让指针变量指向某一变量,须把该变量的地址赋给这个指针变量:指针变量 = &所指向变量如 int k,*p ; p=&k;也可以把一个指针变量如p1的值赋给另一指针变量如p2:p2=p1,只要它们有相同的基数据类型。

此时,p2和p1指向同一变量:指针变量 1 = 指针变量 2 如 int k, *p1,*p2; p1=&k; p2=p1;例:int k, n, a[10], *p1, *p2 ; char c, s[20], *p3, *p4, *p5 ;p1 = &k ; p2 = &a[6] ; p3 = &c ; p4 = &s[0] ; p5 = p4;为引用指针变量所指向的变量,只须在该指针变量前加一星号:*指针变量,如 *p 。

例如, int k,*p; p=&k;接上例:*p1 = 100; /* 同 k=100; */n = *p1 + 5 ; /* 同 n=k+5; */*p4 = ’A’ ; /* 同 s[0]=’A’; */s[1]=*p4; /* 同 s[1]=s[0]; */对指向数组元素的指针变量,可以做整数加减法: 指针变量±整数如p2=p1+1;例如,设p1指向a[i]:p1=&a[i]; 则p1+m指向a[i+m], 即 *(p1+m) 是 a[i+m]。

例: int *p1,*p2, a[10]={0,1,2,3,4,5,6,7,8,9};p1=&a[0]; /* 也可写成p1=&a; 或p1=a; */p2=p1+8; /* p2指向a[8], 同 p2=&a[8] */printf(“%d,%d,%d”, *p1, *p2, *(p1+8) );/* 输出 0,8,8 */注意,数组名本身就代表数组首元素的地址,即:设a[]是数组,则a , &a , 和 &a[0]是一回事,都表示数组首元素的地址。

函数指针和指针函数用法和区别

函数指针和指针函数用法和区别

函数指针和指针函数用法和区别函数指针和指针函数(pointerfunction)是C语言编程中常用的技术,在一些高级编程技术(例如设计模式)中也有广泛的应用。

它们的概念比较复杂,有时候会让初学者有点晕头,但是一旦理解了它们的用法和区别,大家就会发现它们对于结构化编程的设计有着重要的意义。

本文尝试以最简单的方式阐述函数指针和指针函数的用法和区别。

首先,在我们讨论函数指针和指针函数之前,我们最好以一个函数为例来介绍它们:void foo (int a, int b){int c = a + b;printf(%dc);}foo函数接收两个整数参数a和b,并将它们相加后输出结果。

接下来我们来看看函数指针是什么:函数指针(function pointer)是一种指向函数的指针,它可以把函数的地址保存在指针变量中,这样你就可以通过指针调用函数。

句话说,它实际上指向一个函数,通过调用它,你可以调用函数。

函数指针的声明可以形式如下:void (*fooPtr)(int, int);其中,fooPtr是函数指针变量,函数指针变量fooPtr可以指向函数foo()。

函数指针可以赋值,例如:fooPtr=foo;此外,你可以使用函数指针调用函数,例如:(*fooPtr)(1,2);这里,可以说fooPtr指向函数foo(),并且调用函数foo()。

现在,让我们来看看指针函数是什么:指针函数(pointer function)是一种特殊的函数,其返回值类型是指针,即它是一种不接受参数并返回指针的函数。

指针函数的声明可以形式如下:int *fooPtr(void);其中,fooPtr()是指针函数,它返回一个int类型的指针。

指针函数可以调用,例如:int *p = fooPtr();这里,fooPtr()调用了指针函数,并将返回的指针赋值给*p。

了解了函数指针和指针函数的基本概念及其用法后,那么函数指针和指针函数有什么区别?函数指针和指针函数的主要区别在于,函数指针可以指向任何函数,而指针函数必须返回指针类型的变量,并且不接受任何参数。

《C语言程序设计》第8章指针

《C语言程序设计》第8章指针
}
10.3.3 指针变量和数组作函数参数 数组名作形参时,接收实参数组的起始地址;
作实参时,将数组的起始地址传递给形参数组。
引入指向数组的指针变量后,数组及指向数 组的指针变量作函数参数时,可有4种等价形式 (本质上是一种,即指针数据作函数参数):
(1)形参、实参都用数组名 (2)形参、实参都用指针变量 (3)形参用指针变量、实参用数组名 (4)形参用数组名、实参用指针变量
(4)指针变量的++、--与&、*的结合
对于指针变量的++、--与&、*的结合 使用,关键要注意按照运算符的优先级和 结合性进行。
例如: int a=2, *p; p=&a;
•表达式:(*p)++,按运算符的优先级,等价于 a++。其含义为:取出指针变量p所指向的内存单 元的值(即a的值),a的值加1,送回a的内存单 元,a的值变为3,p的值未发生变化,仍然指向 变量a。
程序说明:printf("%s\n",s);语句 通过指向字符串的指针变量s,整体引
用它所指向的字符串的原理:系统首先输出s 指向的第一个字符,然后使s自动加1,使 之指向下一个字符;重复上述过程,直至遇到 字符串结束标志。
main() { char string[ ]=”I love Beijing.”; printf(“%s\n”,string); }
3.数组元素的引用 数组元素的引用,既可用下标法,也可用
指针法。
10.3.2 通过指针引用数组元素 如果有“int a [10],*p=a;” ,则: (1)p+i和a+i都是数组元素a [i]的地址。
(2)*(p+i)和*(a+i)就是数组元素a [i]。 int a [3]; a [0]——*a a [1]——*(a +1) a [2]——*(a +2)

C语言中指针变量作为函数参数详解

C语言中指针变量作为函数参数详解

C语言中指针变量作为函数参数详解C语言中指针变量作为函数参数详解在C语言中,函数的参数不仅可以是整数、小数、字符等具体的数据,还可以是指向它们的指针。

用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着函数的结束而被销毁。

像数组、字符串、动态分配的内存等都是一系列数据的集合,没有办法通过一个参数全部传入函数内部,只能传递它们的指针,在函数内部通过指针来影响这些数据集合。

有的时候,对于整数、小数、字符等基本类型数据的操作也必须要借助指针,一个典型的例子就是交换两个变量的值。

有些初学者可能会使用下面的方法来交换两个变量的值:#includevoid swap(int a, int b){ int temp; //临时变量 temp = a; a = b; b = temp;}int main(){ int a = 66, b = 99; swap(a, b); printf("a = %d, b = %dn", a, b); return 0;}运行结果:a = 66,b = 99从结果可以看出,a、b 的值并没有发生改变,交换失败。

这是因为 swap() 函数内部的 a、b 和 main() 函数内部的 a、b 是不同的变量,占用不同的内存,它们除了名字一样,没有其他任何关系,swap() 交换的是它内部 a、b 的值,不会影响它外部(main() 内部)a、b 的值。

改用指针变量作参数后就很容易解决上面的问题:#includevoid swap(int *p1, int *p2){ int temp; //临时变量temp = *p1; *p1 = *p2; *p2 = temp;}int main(){ int a = 66, b = 99; swap(&a, &b); printf("a = %d, b = %dn", a, b); return 0;} 运行结果:a = 99,b = 66调用 swap() 函数时,将变量 a、b 的地址分别赋值给 p1、p2,这样 *p1、*p2 代表的就是变量 a、b 本身,交换 *p1、*p2 的值也就是交换 a、b 的值。

定义函数指针

定义函数指针

函数指针
将函数的首个地址(入口地址)赋予一个指针变量,使指针变量指向函数所在的内存空间,然后通过指针变量就可以找到并调用函数。

这种指针就是函数指针。

函数指针的定义格式为:
数据类型符(*指针名)(参数表);
int (*p)(int n);
因为()的优先级高于“*”,所以指针名的括号不能省略。

如果省略,则为返回值为指针的函数原型。

说明:
●数据类型符是指指针返回值的类型。

●定义指向函数的指针变量,并不意味着这个指针变量可以指向任何函数,它只能指向在
定义时指定的类型的函数。

●如果要用指针调用函数,必须先使指针变量指向该函数
●在给函数指针变量赋值使,只需给出函数名而不必给出参数
●要用函数指针变量调用函数时,只需将(*p)代替函数名即可,在(*p)之后的括号中根据
需要写上实参
●对指向函数的指针变量不能进行算术运算
●用函数名调用函数,只能调用所指定的一个函数,而通过指针变量调用函数比较灵活,
可以根据不同情况先后调用不同的函数。

●指向函数的指针变量的一个重要的用途是把函数的地址作为参数传递给其他函数,这样
就能够在被调的函数中使用实参函数。

c语言二级指针详解

c语言二级指针详解

c语言二级指针详解C语言中,指针是一种重要的数据类型,它可以指向另一个变量或者数据结构中的一个元素,并且可以进行不同种类的操作(如解引用、赋值、比较、运算等)。

在C语言中,指针本身也是一个变量,它具有一个内存地址,并且其值就是指向的地址。

而指针变量可以通过指定自己的类型来控制指向的变量或者数据结构元素的类型。

在C语言中,指针本身也可以被指针所指向,这样的指针就被称为“二级指针”或者“指向指针的指针”。

二级指针在一些情况下比普通指针更加灵活,比如当我们需要在函数内部进行指针变量的修改或者返回值时,就可以使用二级指针。

1、指向指针的指针需要使用两个星号(**)来声明,例如:int **p;2、在函数中传递指向指针的指针时,需要将变量的地址传递给函数,而函数需要使用指向指针的指针来访问实际的指针变量。

3、在使用二级指针时,我们需要防止指针变量指向非法内存地址,否则会导致程序出现意想不到的错误。

二级指针是C语言中非常重要的概念,尤其在函数调用和指针变量的修改或返回值时,更是非常有用。

不过,我们在使用二级指针时需要额外注意指向内存地址的合法性,否则会导致程序出现异常。

二级指针是指指向指针对象的指针,即指针的指针,它可以通过间接的方式访问一个指针变量所指向的地址,这种间接的访问方式可以增加程序的灵活性,从而使程序更加易于理解和维护。

1、动态内存管理在C语言中,动态内存分配是通过调用malloc函数来实现的,而释放动态内存则需要使用free函数。

在使用malloc函数分配内存时,它会返回一个指针,指向分配的内存空间的首地址,我们可以将这个指针赋值给一个普通的指针变量,然后通过这个普通指针变量来访问分配的内存空间。

不过,当我们使用malloc来分配一个指针数组时,我们就需要使用二级指针来存储这个指针数组的首地址。

int **p = (int **)malloc(sizeof(int *) * 10);for (int i = 0; i < 10; ++i) {p[i] = (int *)malloc(sizeof(int) * 10);}以上代码中,我们使用了二级指针来存储指向指针数组的地址,然后使用循环语句来为每一个指针分配空间。

c语言中 指针的类型

c语言中 指针的类型

c语言中指针的类型在C语言中,指针是一种非常重要的概念。

它是一个变量,其值为内存地址。

通过使用指针,我们可以直接访问和修改内存中的数据,这使得我们能够更高效地处理数据和实现复杂的数据结构。

在C语言中,指针的类型决定了指针变量可以指向的数据类型。

以下是一些常见的指针类型:1. void指针:void指针是一个通用的指针类型,可以指向任意类型的数据。

它的定义方式为void *ptr。

由于void指针没有具体的数据类型信息,因此在使用时需要进行强制类型转换。

2.整型指针:整型指针可以指向整型数据。

例如,int *ptr可以指向一个int类型的变量。

可以使用指针来操作该变量的地址,读取或修改其值。

3.浮点型指针:浮点型指针可以指向浮点型数据。

例如,float*ptr可以指向一个float类型的变量。

使用指针可以更高效地进行浮点计算,同时可以实现对浮点数据的修改。

4.字符型指针:字符型指针可以指向字符型数据。

例如,char*ptr可以指向一个字符型变量或字符数组。

通过指针,我们可以更方便地操作字符串,包括拷贝、连接、查找等。

5.结构体指针:结构体指针可以指向结构体类型的数据。

结构体是一种自定义的数据类型,可以包含多个不同数据类型的成员变量。

通过结构体指针,我们可以访问和修改结构体的成员,实现对结构体的操作。

6.数组指针:数组指针可以指向数组类型的数据。

例如,int*ptr可以指向一个int类型的数组。

通过指针,我们可以遍历数组中的每个元素,进行读取、修改或其他操作。

7.函数指针:函数指针可以指向函数。

函数是一段可执行的代码块,通过函数指针,我们可以像调用普通函数一样调用被指向的函数。

8.指向指针的指针:指向指针的指针是指针的指针,通过它可以实现更复杂的数据结构,如链表、二维数组等。

在C语言中,指针的类型非常灵活,可以根据实际需求选择合适的指针类型。

通过使用指针,我们可以提高程序的效率和灵活性,同时能够更方便地进行内存管理和数据操作。

指针

指针

(main)
9 5 5 9 2000 2002
(swap)
2000 2002 5
...
…...
整型变量a 整型变量b 指针pointer_1 指针pointer_2
指针p1 指针p2
整型p
例 将数从大到小输出
swap(int *p1, int *p2) { int p; 2000 p=*p1; 2002 *p1=*p2; 2004 *p2=p; 2006 } 地址传递 2008 main() 200A { int a,b; int *pointer_1,*pointer_2; 200C scanf("%d,%d",&a,&b); 200E pointer_1=&a; pointer_2=&b; 2010 if(a<b)swap(pointer_1,pointer_2); printf("\n%d,%d\n",a,b); }
#define NULL 0 int *p=NULL:
p=NULL与未对p赋值不同 用途: 避免指针变量的非法引用 在程序中常作为状态比较
例 例 char *p; int *p1; ...... void *p2; while(p!=NULL) p1=(char *)p2; { ...… p2=(void *)p1; } 表示不指定p是指向哪一种 类型数据的指针变量
…...

整型变量i
i=3;-----直接访问
2000 2001 2002 2003 2004 3 20 10
变量i_pointer 2000
2005
2006
指针变量

*i_pointer=20; -----间接访问
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.一般定义形式:返回值的数据类型(*指针变量名)();for example: int function(int a, int b){...;}int (*pointer_of_function)();pointer_of_function = function; //相关联的语句就是这么简单。

2.函数的调用可以通过函数名调用,也可以通过函数指针调用(即用指向函数的指针变量调用)。

3.(*p)() 表示定义一个指向函数的指针变量,它不是固定指向哪一个函数的,而只是表示定义了这样一个类型的变量,它是专门用来存放函数的入口地址的。

在程序中把哪一个函数的地址赋给它,它就指向哪一个函数。

在一个程序中,一个指针变量可以先后指向返回类型相同的不同的函数。

4.在给函数指针变量赋值时,只需给出函数名而不必给出参数,如:pointer_of_function = function ,因为是将函数入口地址赋给pointer_of_function, 而不牵涉到实参与形参结合的问题。

不能写成pointer_of_function = function(a,b)。

5.用函数指针变量调用函数时,只需将(*P)代替函数名即可,在(*p)之后的括弧中根据需要写上实参。

6.对指向函数的指针变量,像p++ 等类似运算是没有意义的。

7.区别int (*p)() 与int *p():由于()的优先级高于*,它就成了声明一个函数了,这个函数的返回值是指向整形变量的指针。

1 定义和调用程序在编译后,每个函数都有一个首地址(也就是函数第一条指令的地址),这个地址称为函数的指针。

可以定义指向函数的指针变量,使用指针变量间接调用函数。

下面通过一个简单的例子来说明:float max(float x,float y){return x>y?x:y;}float min(float x,float y){return x<y?x:y;}main(){float a=1,b=2, c;float (*p)(float x, float y);p=max;c=(*p)(a,b); /*等效于max(a,b)*/printf("\nmax=%f",c);p=min;c=(*p)(a,b); /*等效于min(a,b)*/printf("\nmin=%f",c);}程序运行的结果为:max=2.000000min=1.000000说明:(1)语句float (*p)(float x, float y);定义了一个指向函数的指针变量。

函数的格式是:返回值为float型,形式参数列表是(float x, float y)。

p定义后,可以指向任何满足该格式的函数。

(2)定义指向函数的指针变量的格式为:(3)数据类型(*指针变量名称)(形式参数列表);(4)其中数据类型是函数返回值的类型,形式参数列表是函数的形式参数列表。

(5)形式参数列表中,参数名称可以省略。

比如,float (*p)(float x, float y);可以写为:(6)float (*p)(float, float);(7)注意指针变量名称两边的括号不能省略。

(8)语句p=max;将max函数的首地址值赋给指针变量p,也就是使p指向函数max。

C语言中,函数名称代表函数的首地址。

(9)第一个c=(*p)(a,b);语句:由于p指向了max函数的首地址,(*p)(a,b)完全等效于max(a,b)。

函数返回2.0。

注意*p两边的括号不能省略。

(10)语句p=min; 将min函数的首地址值赋给指针变量p。

p是一个变量,p的值实际上是一个内存地址值,可以指向max,也可以指向min,但指向函数的格式必须与p的定义相符合。

(11)第二个c=(*p)(a,b);语句:由于p指向了min函数的首地址,(*p)(a,b)完全等效于min(a,b)。

函数返回1.0。

(12)将函数首地址赋给指针变量时,直接写函数名称即可,不用写括号和函数参数。

(13)利用指针变量调用函数时,要写明函数的实际参数。

提示:定义一个指向函数的指针变量时,一定要使用括号。

比较下面的两个定义:float (*p1)(int x, long y);float *p2(int x, long y);第一个语句定义了一个指向函数的指针变量p1;第二个语句声明了一个函数p2,p2的形式参数为(int x, long y),返回值为一个float型的指针。

2 指向函数的指针作为函数参数有时候,许多函数功能不同,但它们的返回值和形式参数列表都相同。

这种情况下,可以构造一个通用的函数,把函数的指针作为函数参数,这样有利于进行程序的模块化设计。

比如下面的例子中,我们把对2个float型数进行加、减、乘、除操作的4个函数归纳成一个数学操作函数MathFunc。

这样,在调用MathFunc函数时,只要将具体函数名称作为函数实际参数,MathFunc就会自动调用相应的加、减、乘、除函数,并计算出结果。

下面是程序的代码:float Plus(float f1, float f2);float Minus(float f1, float f2);float Multiply(float f1, float f2);float Divide(float f1, float f2);float MathFunc(float (*p)(float, float), float para1,float para2);main(){float a=1.5, b=2.5;printf("\na+b=%f", MathFunc(Plus, a,b));printf("\na-b=%f", MathFunc(Minus, a,b));printf("\na*b=%f", MathFunc(Multiply, a,b));printf("\na/b=%f", MathFunc(Divide, a,b));}float Plus(float f1, float f2){return f1+f2;}float Minus(float f1, float f2){return f1-f2;}float Multiply(float f1, float f2){return f1*f2;}float Divide(float f1, float f2){return f1/f2;}floatMathFunc(float (*p)(float, float), float para1,float para2){return (*p)( para1, para2);}程序运行的结果为:a+b=4.000000a-b=-1.000000a*b=3.750000a/b=0.600000例8-10 利用指向函数的指针,求如下函数在一个区段内的最小值。

本题可以利用指向函数的指针。

虽然所给的函数互不相同,但其在一定区间内求最小值的算法都是通用的。

因此,可以写一个通用的函数float GetMin(float (*p)(float), float fPos1,float fPos2),用于计算不同函数的最小值。

该函数的第一个参数p是一个指向函数的指针,p指向包含一个float型参数的函数。

对应于题目的要求,分别写三个数学函数。

在主函数中,调用GetMin时,第一个参数分别使用上述数学函数的名称,后两个参数传入区间值。

这样,调用三次GetMin即可以求出三个函数在给定区间的最小值。

#include "math.h"float f1(float x){return x*x+2*x+1; /*f1的表达式*/}float f2(float x){return 2*sin(x); /*f2的表达式*/}float f3(float x){return 2*x+1; /*f3的表达式*/}/*p为指向函数的指针,fPos1和fPos2为左右区间的值*/float GetMin(float (*p)(float), float fPos1,float fPos2){float f,t, fMin, fStep=0.01; /* fStep为步长值*//*在fPos1至fPos2的区间内,以fStep为步长,依次比较最小f值*/fMin=(*p)(fPos1);for(f=fPos1;f<=fPos2;f+=fStep){t=(*p)(f);if(t<fMin)fMin=t;}/*返回求出的最小值*/return fMin;}main(){/*直接计算并输出结果*/printf("\nMin value of f1: %f",GetMin(f1,-1,1));printf("\nMin value of f2: %f",GetMin(f2,1,3));printf("\nMin value of f3: %f",GetMin(f3,-1,1));}程序运行的结果为:Min value of f1: 0.000000Min value of f2: 0.282244Min value of f3: -1.000000主函数main调用GetMin函数时,传入了函数名称和区间值。

GetMin函数在计算函数最小值时,根据传入的函数指针p调用相应的函数。

灵活使用指向函数的指针可以提高程序的扩充性。

比如本题,如果要增加条件,计算一个f4(x)=2*logx+1在(0,5)内的最小值,那么我们只需要增加一个f4函数的定义,然后在main 函数中就可以直接进行计算GetMin(f4,0,5),GetMin函数不用进行任何修改。

相关文档
最新文档