C语言 指针(7)

目录

1.函数指针变量

2.函数指针数组

3.转移表


1.函数指针变量

1.1函数指针变量的创建

什么是函数指针变量呢?
 
根据前面学习整型指针,数组指针的时候,我们的类比关系,我们不难得出结论:

函数指针变量应该是用来存放函数地址的,未来通过地址能够调用函数的。
 
那么函数是否有地址呢?

我们做个测试:

#include <stdio.h>
void test()
{
    printf("hehe\n");
}
int main()
{
    printf("test:  %p\n", test);
    printf("&test: %p\n", &test);
    return 0;
}

输出结果如下:

1. test:  005913CA
2. &test: 005913CA

确实打印出来了地址,所以函数是有地址的,函数名就是函数的地址,当然也可以通过 &函数名

的方式获得函数的地址。
 
如果我们要将函数的地址存放起来,就得创建函数指针变量咯,函数指针变量的写法其实和数组指

针非常类似。如下:

void test()
{
    printf("hehe\n");
}
void (*pf1)() = &test;
void (*pf2)() = test;

int Add(int x, int y)
{
    return x+y;
}
int(*pf3)(int, int) = Add;
int(*pf3)(int x, int y) = &Add; //x和y写上或者省略都是可以的

函数指针类型解析:

int     (*pf3)   (int x, int y)
|       |        |
|       |        |-- pf3指向函数的参数类型和个数的交代
|       |
|       |-- 函数指针变量名
|
|-- pf3指向函数的返回类型
int (*) (int x, int y) //pf3函数指针变量的类型

1.2函数指针变量的使用

通过函数指针调用指针指向的函数

#include <stdio.h>
int Add(int x, int y) {
    return x + y;
}
int main() {
    int(*pf3)(int, int) = Add;
    printf("%d\n", (*pf3)(2, 3));
    printf("%d\n", pf3(3, 5));
    return 0;
}

输出结果:

1. 5
2. 8

1.3 typedef关键字

typedef 是用来给类型重命名的,可以把复杂的类型变得简单。
 
比如,觉得  unsigned int  写起来麻烦,要是能写成  uint  就方便多了,那就可以这样用:

typedef unsigned int uint; 
//把unsigned int 重命名成uint

指针类型也能重命名,比如把 int*  重命名成 ptr_t  ,像这样:

typedef int* ptr_t;

不过对于数组指针和函数指针,重命名有点不一样。
 
比如有个数组指针类型  int(*)[5]  ,要把它重命名成  parr_t  ,就得这么写:

typedef int(*parr_t)[5]; 
//新的类型名必须在*的右边

函数指针类型的重命名也是一样的,比如,将 void(*)(int)  类型重命名为 pf_t ,就可以这样写:

typedef void(*pfun_t)(int); //新的类型名必须在*的右边

2.函数指针数组

数组是一个存放相同类型数据的存储空间,我们已经学习了指针数组,比如:

int * arr[10]; 
//数组的每个元素是int*

那要把函数的地址存到一个数组中,那个数组就叫函数指针数组,那函数指针的数组如何定义呢?

int (*parr1[3])();
int *parr2[3]();
int (*)() parr3[3];

答案是: parr1 

parr1  先和  []  结合,说明  parr1  是数组,数组的内容是什么呢?

是  int (*)()  类型的函数指针。

3.转移表

函数指针数组的用途: 转移表

举例:计算器的一般实现

#include <stdio.h>
int add(int a, int b)
{
    return a + b;
}
int sub(int a, int b)
{
    return a - b;
}
int mul(int a, int b)
{
    return a * b;
}
int div(int a, int b)
{
    return a / b;
}
int main()
{
    int x, y;
    int input = 1;
    int ret = 0;
    do
    {
        printf("********************\n");
        printf("  1:add        2:sub \n");
        printf("  3:mul        4:div \n");
        printf("  0:exit              \n");
        printf("********************\n");
        printf("请选择: ");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            printf("输入操作数: ");
            scanf("%d %d", &x, &y);
            ret = add(x, y);
            printf("ret = %d\n", ret);
            break;
        case 2:
            printf("输入操作数: ");
            scanf("%d %d", &x, &y);
            ret = sub(x, y);
            printf("ret = %d\n", ret);
            break;
        case 3:
            printf("输入操作数: ");
            scanf("%d %d", &x, &y);
            ret = mul(x, y);
            printf("ret = %d\n", ret);
            break;
        case 4:
            printf("输入操作数: ");
            scanf("%d %d", &x, &y);
            ret = div(x, y);
            printf("ret = %d\n", ret);
            break;
        case 0:
            printf("退出程序\n");
            break;
        default:
            printf("选择错误\n");
            break;
        }
    } while (input);
    return 0;
}

代码解释 :

(1)头文件的引入:

#include <stdio.h>

 #include <stdio.h>  指令用于引入标准输入输出头文件,该文件包含了  printf 、 scanf  等输入输

出函数的声明,使得程序能够进行输入输出操作。

(2)函数定义:

int add(int a, int b)
{
    return a + b;
}
int sub(int a, int b)
{
    return a - b;
}
int mul(int a, int b)
{
    return a * b;
}
int div(int a, int b)
{
    return a / b;
}

这里定义了四个函数,分别是 add(加法)、sub (减法)、mul (乘法)、div (除法)。每

个函数都接收两个 int  类型的参数,并根据相应的运算规则返回计算结果。

(3)main函数:

int main()
{
    int x, y;
    int input = 1;
    int ret = 0;

-  int x, y;  声明了两个整型变量  x  和  y ,用于存储用户输入的操作数。

-  int input = 1;  声明并初始化了变量  input ,用于存储用户选择的操作选项,初始值设为  1  是为

了确保  do - while  循环至少执行一次。

-  int ret = 0;  声明并初始化了变量  ret ,用于存储运算结果,初始值为  0  。

(4)do-while循环

    do
    {
        printf("********************\n");
        printf("  1:add        2:sub \n");
        printf("  3:mul        4:div \n");
        printf("  0:exit              \n");
        printf("********************\n");
        printf("请选择: ");
        scanf("%d", &input);

-  do - while  循环保证了循环体至少执行一次。

- 循环体中,首先通过  printf  函数打印出操作选项菜单,提示用户进行选择。然后使用  scanf  函

数读取用户输入的整数,并存储到  input  变量中。

(5)switch语句:

        switch (input)
        {
        case 1:
            printf("输入操作数: ");
            scanf("%d %d", &x, &y);
            ret = add(x, y);
            printf("ret = %d\n", ret);
            break;
        case 2:
            printf("输入操作数: ");
            scanf("%d %d", &x, &y);
            ret = sub(x, y);
            printf("ret = %d\n", ret);
            break;
        case 3:
            printf("输入操作数: ");
            scanf("%d %d", &x, &y);
            ret = mul(x, y);
            printf("ret = %d\n", ret);
            break;
        case 4:
            printf("输入操作数: ");
            scanf("%d %d", &x, &y);
            ret = div(x, y);
            printf("ret = %d\n", ret);
            break;
        case 0:
            printf("退出程序\n");
            break;
        default:
            printf("选择错误\n");
            break;
        }
    } while (input);

-  switch  语句根据  input  的值来执行不同的分支:

-  case 1 :当用户选择  1  时,提示用户输入两个操作数,然后使用  scanf  读取,再调用  add  函

数进行加法运算,将结果存储在  ret  中,并打印出结果。

-  case 2 :与  case 1  类似,调用  sub  函数进行减法运算。

-  case 3 :调用  mul  函数进行乘法运算。

-  case 4 :调用  div  函数进行除法运算。不过这里没有对除数为  0  的情况进行处理,如果用户

输入  0  作为除数,程序会产生未定义行为。

-  case 0 :当用户选择  0  时,打印“退出程序”,此时  input  的值为  0 , do - while  循环条件不

满足,程序结束。

-  default :当用户输入的不是  0  -  4  之间的数字时,打印“选择错误”。

-  do - while  循环的条件是  input ,只要  input  不为  0 ,循环就会继续执行,用户可以不断进行操作选择。

(6)函数返回:

    return 0;
}

 main  函数返回  0  ,表示程序正常结束。在C语言中, main  函数返回  0  通常用于向操作系统表

明程序执行成功。

希望大家能够好好理解转移表这块的代码,感谢大家的观看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值