一、函数指针
1.什么是函数指针
(1)函数指针的实质还是指针变量,与数组指针、普通指针之间并没有本质区别。
(2)如果在程序中定义了一个函数,那么在编译时系统就会为这个函数代码分配一段存储空间,这段存储空间的首地址称为这个函数的地址。而且函数名表示的就是这个地址
函数指针的定义方式为:
函数返回值类型 (* 指针变量名) (函数参数列表);
但是这里需要注意的是:“(*指针变量名)”两端的括号不能省略,括号改变了运算符的优先级。如果省略了括号,就不是定义函数指针而是一个函数声明了,即声明了一个返回值类型为指针型的函数。
例如:
int(*p)(int, int);
这个语句就定义了一个指向函数的指针变量 p。首先它是一个指针变量,所以要有一个“*”,即(*p);其次前面的 int 表示这个指针变量可以指向返回值类型为 int 型的函数;后面括号中的两个 int 表示这个指针变量可以指向有两个参数且都是 int 型的函数。所以合起来这个语句的意思就是:定义了一个指针变量 p,该指针变量可以指向返回值类型为 int 型,且有两个整型参数的函数。p 的类型为 int(*)(int,int)。
2.如何用函数指针调用函数
主要就是三个步骤,如下:
int Func(int x); /*声明一个函数*/
int (*pFunc) (int x); /*定义一个函数指针*/
pFunc = Func; /*将Func函数的首地址赋给指针变量pFunc pFunc = &Func也可以 */
实例:
#include <stdio.h>
int add(int a, int b);
int sub(int a, int b);
int multiply(int a, int b);
int divide(int a, int b);
// 定义了一个类型pFunc,这个函数指针类型指向一种特定参数列表和返回值的函数
typedef int (*pFunc)(int, int);
int main(void)
{
pFunc p1 = NULL;
char c = 0;
int a = 0, b = 0, result = 0;
printf("请输入要操作的2个整数:\n");
scanf("%d %d", &a, &b);
printf("请输入操作类型:+ | - | * | /\n");
do
{
scanf("%c", &c);
}while (c == '\n');
// 加一句调试
//printf("a = %d, b = %d, c = %d.\n", a, b, c);
switch (c)
{
case '+':
p1 = add; break;
case '-':
p1 = sub; break;
case '*':
p1 = multiply; break;
case '/':
p1 = divide; break;
default:
p1 = NULL; break;
}
result = p1(a, b);
printf("%d %c %d = %d.\n", a, c, b, result);
return 0;
}
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int multiply(int a, int b)
{
return a * b;
}
int divide(int a, int b)
{
return a / b;
}
二、指针数组与数组指针
1.定义
(1)指针数组的实质是一个数组,这个数组中存储的内容全部是指针变量。
(2)数组指针的实质是一个指针,这个指针指向的是一个数组。
2.分析指针数组与数组指针的表达式
int *p[5];
核心是p,p是一个数组,数组有5个元素大,数组的类型时int*类型(数组中的元素都是指针,指针指向的元素类型是int类型的);整个符号是一个指针数组。
int (*p)[5];
核心是p,p是一个指针,指针指向一个数组,数组有5个元素,数组中存的元素是int类型; 总结一下整个符号的意义就是数组指针。
3.示例
int *p;
int a[5];
int (*p1)[5] ;
p1 = &a; // p1类型是int (*)[5],&a的类型也是int (*)[5]