易混淆概念(三)指针函数与函数指针

xiaoxiao2021-02-28  108

指针函数与函数指针

一、指针函数(函数):指返回值是指针的函数

     类型标识符    *函数名(参数表)       int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。 注意指针函数与函数指针表示方法的不同,千万不要混淆。最简单的辨别方式就是看 函数名前面的指针*号有没有被括号()包含 如果被包含就是函数指针,反之则是指针函数。 如下例: [cpp] view plain copy int *f(int a, int b); // 声明指针函数      int _tmain(int argc, _TCHAR* argv[])   {       printf("------------------------------ Start\n");          int *p1 = NULL;       printf("The memeory address of p1 = 0x%x \n", p1);          p1 = f(1, 2);          printf("The memeory address of p1 = 0x%x \n", p1);       printf("*p1 = %d \n", *p1);          printf("------------------------------ End\n");       getchar();       return 0;   }      /*   * 指针函数的定义   * 返回值是指针类型int *   */   int *f(int a, int b) {       int *p = (int *)malloc(sizeof(int));       printf("The memeory address of p = 0x%x \n", p);       memset(p, 0, sizeof(int));       *p = a + b;       printf("*p = %d \n", *p);          return p;   }   通过运行结果,可以看出,指针函数f返回的类型是一个指针类型,因为f是赋值给int类型指针p1的,如果不是指针类型,编译就会出错。

下面是运行结果:

从上图的运行结果可以看出,指针函数f的返回值p和f赋值给的指针p1的地址是相同的,都是指向指针函数内部申请的内存地址0x3b88d0。

下面是debug查看的指针p1和指针p的内存地址。

(1)指针p1刚定义时的指向NULL,也就是空指针,地址是0。p1的地址如红色框内所示,p1地址为0x00000000。

(2)指针函数f内的返回值p的地址如下图中红色框内所示,p的地址是0x003b88d0:

(3)执行完指针函数f后,把f的返回值p赋给先前定义的地址p1,此时p1的地址和p的地址相同。p1的地址如下图中红色框内所示,p1的地址是0x003b88d0,与p的地址相同,p的地址如下图中蓝色框内所示,并且两者的值也都是3,因为是指向同一个地址,所以值必然相同:

所以,指针函数就是返回一个地址给调用者,用于需要地址的情况。

二、函数指针(指针):是指指向函数的指针变量,本质是一个指针变量。(可简单理解为将(*指针变量名)用其他函数名替换)

 int (*f) (int x); /* 声明一个函数指针 */  f=func; /* 将func函数的首地址赋给指针f */ 顾名思义,函数指针说的就是一个指针,但这个指针指向的函数,不是普通的基本数据类型或者类对象。 指向函数的指针包含了函数的地址,可以通过它来调用函数。声明格式如下:         类型说明符 (*函数名)(参数)     其实这里不能称为函数名,应该叫做指针的变量名。这个特殊的指针指向一个返回整型值的函数。指针的声明必须和它指向函数的声明保持一致。         指针名和指针运算符外面的括号改变了默认的运算符优先级。如果没有圆括号,就变成了一个返回整型指针的函数的原型声明。     例如:         void (*fptr)();     把函数的地址赋值给函数指针,可以采用下面两种形式:         fptr=&Function;         fptr=Function;     取地址运算符&不是必需的,因为单单一个函数标识符就标号表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。     可以采用如下两种方式来通过指针调用函数:         x=(*fptr)();         x=fptr();     第二种格式看上去和函数调用无异。但是有些程序员倾向于使用第一种格式,因为它明确指出是通过指针而非函数名来调用函数的。下面举一个例子: [cpp]  view plain  copy int (*f)(int a, int b); // 声明函数指针   通过与1中指针函数的定义对比可以看到,函数指针与指针函数的最大区别是函数指针的函数名是一个指针,即函数名前面有一个指针类型的标志型号“*”。

当然,函数指针的返回值也可以是指针。

上面的函数指针定义为一个指向一个返回值为整型,有两个参数并且两个参数的类型都是整型的函数。

下面是利用函数指针分别求两个整数的最大值和最小值的用法。

[cpp]  view plain  copy /*   * 求最大值   * 返回值是int类型,返回两个整数中较大的一个   */   int max(int a, int b) {       return a > b ? a : b;   }      /*   * 求最小值   * 返回值是int类型,返回两个整数中较小的一个   */   int min(int a, int b) {       return a < b ? a : b;   }      int (*f)(intint); // 声明函数指针,指向返回值类型为int,有两个参数类型都是int的函数      int _tmain(int argc, _TCHAR* argv[])   {       printf("------------------------------ Start\n");          f = max; // 函数指针f指向求最大值的函数max       int c = (*f)(1, 2);          printf("The max value is %d \n", c);          f = min; // 函数指针f指向求最小值的函数min       c = (*f)(1, 2);          printf("The min value is %d \n", c);          printf("------------------------------ End\n");       getchar();       return 0;   }  

执行结果如下:

主要的区别是一个是指针变量,一个是函数。在使用是必要要搞清楚才能正确使用 顶 44 [cpp]  view plain  copy int *f(int a, int b); // 声明指针函数      int _tmain(int argc, _TCHAR* argv[])   {       printf("------------------------------ Start\n");          int *p1 = NULL;       printf("The memeory address of p1 = 0x%x \n", p1);          p1 = f(1, 2);          printf("The memeory address of p1 = 0x%x \n", p1);       printf("*p1 = %d \n", *p1);          printf("------------------------------ End\n");       getchar();       return 0;   }      /*   * 指针函数的定义   * 返回值是指针类型int *   */   int *f(int a, int b) {       int *p = (int *)malloc(sizeof(int));       printf("The memeory address of p = 0x%x \n", p);       memset(p, 0, sizeof(int));       *p = a + b;       printf("*p = %d \n", *p);          return p;   }   通过运行结果,可以看出,指针函数f返回的类型是一个指针类型,因为f是赋值给int类型指针p1的,如果不是指针类型,编译就会出错。

下面是运行结果:

从上图的运行结果可以看出,指针函数f的返回值p和f赋值给的指针p1的地址是相同的,都是指向指针函数内部申请的内存地址0x3b88d0。

下面是debug查看的指针p1和指针p的内存地址。

(1)指针p1刚定义时的指向NULL,也就是空指针,地址是0。p1的地址如红色框内所示,p1地址为0x00000000。

(2)指针函数f内的返回值p的地址如下图中红色框内所示,p的地址是0x003b88d0:

(3)执行完指针函数f后,把f的返回值p赋给先前定义的地址p1,此时p1的地址和p的地址相同。p1的地址如下图中红色框内所示,p1的地址是0x003b88d0,与p的地址相同,p的地址如下图中蓝色框内所示,并且两者的值也都是3,因为是指向同一个地址,所以值必然相同:

所以,指针函数就是返回一个地址给调用者,用于需要地址的情况。

[cpp]  view plain  copy int (*f)(int a, int b); // 声明函数指针   通过与1中指针函数的定义对比可以看到,函数指针与指针函数的最大区别是函数指针的函数名是一个指针,即函数名前面有一个指针类型的标志型号“*”。

当然,函数指针的返回值也可以是指针。

上面的函数指针定义为一个指向一个返回值为整型,有两个参数并且两个参数的类型都是整型的函数。

下面是利用函数指针分别求两个整数的最大值和最小值的用法。

[cpp]  view plain  copy /*   * 求最大值   * 返回值是int类型,返回两个整数中较大的一个   */   int max(int a, int b) {       return a > b ? a : b;   }      /*   * 求最小值   * 返回值是int类型,返回两个整数中较小的一个   */   int min(int a, int b) {       return a < b ? a : b;   }      int (*f)(intint); // 声明函数指针,指向返回值类型为int,有两个参数类型都是int的函数      int _tmain(int argc, _TCHAR* argv[])   {       printf("------------------------------ Start\n");          f = max; // 函数指针f指向求最大值的函数max       int c = (*f)(1, 2);          printf("The max value is %d \n", c);          f = min; // 函数指针f指向求最小值的函数min       c = (*f)(1, 2);          printf("The min value is %d \n", c);          printf("------------------------------ End\n");       getchar();       return 0;   }  

执行结果如下:

转载请注明原文地址: https://www.6miu.com/read-67554.html

最新回复(0)