苏州制作网站哪家好,外贸网站建设公司策划,小程序搭建是什么意思,wordpress付费下载插件#x1f341;博客主页#xff1a;江池俊的博客 #x1f4ab;收录专栏#xff1a;C语言进阶之路 #x1f4a1;代码仓库#xff1a;江池俊的代码仓库 #x1f3aa;我的社区#xff1a;GeekHub #x1f389;欢迎大家点赞#x1f44d;评论#x1f4dd;收藏⭐ 文章目录 一… 博客主页江池俊的博客 收录专栏C语言进阶之路 代码仓库江池俊的代码仓库 我的社区GeekHub 欢迎大家点赞评论收藏⭐ 文章目录 一、函数指针代码1代码2 二、函数指针数组什么是函数指针数组为什么使用函数指针数组函数指针数组的基本用法 三、 指向函数指针数组的指针指向函数指针数组的指针是什么为什么使用指向函数指针数组的指针 总结 一、函数指针
在C语言中函数是一等公民可以像其他变量一样被传递和使用。而函数指针就是指向函数的指针变量可以用来调用函数。本文将介绍函数指针的定义、使用方法以及注意事项。
函数指针的定义格式为
返回值类型 (*指针变量名)(参数列表);其中返回值类型表示函数的返回值类型指针变量名是指向函数的指针变量的名称参数列表表示函数的参数类型和数量。
例如定义一个指向返回值为int、参数为两个int类型的函数的指针
int (*pAdd)(int, int);这个指针可以指向任何返回值为int、参数为两个int类型的函数。
先看一段代码
#include stdio.h
void test()
{printf(hehe\n);
}int main()
{printf(%p\n, test);printf(%p\n, test);return 0;
}输出结果 输出的是两个地址这两个地址是 test 函数的地址。 那我们的函数的地址要想保存起来怎么保存 下面我们看代码
void test()
{printf(hehe\n);
}
//下面pfun1和pfun2哪个有能力存放test函数的地址
void (*pfun1)();
void *pfun2();首先能给存储地址就要求pfun1或者pfun2是指针那哪个是指针 答案是 pfun1可以存放。pfun1先和*结合说明pfun1是指针指针指向的是一个函数指向的函数无参数返回值类型为void。 阅读两段有趣的代码
//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int);这两段代码都涉及了函数指针的用法让我们逐一来解释它们
代码1
(*(void (*)())0)();这段代码是一个函数指针调用的例子。让我们逐步分解它 void (*)() 表示一个函数指针类型它指向一个不接受任何参数void并且返回类型为 void 的函数。 (void (*)())0这里的(void (*)())实际上是一个强制转化的操作它是将0强制转化为函数指针类型即是将函数指针初始化为一个地址为 0 的空指针也就是一个无效的函数指针。 (*(void (*)())0)(); 则是将这个无效的函数指针进行了间接调用实际上是试图调用地址为 0 的函数这通常会导致程序崩溃因为操作系统不允许在地址 0 处执行代码会触发段错误。 这段代码在 C 语言中属于未定义行为不应该在实际代码中使用因为它可能导致程序的崩溃或其他不可预测的行为。 代码2
void (*signal(int, void(*)(int)))(int);
//我们也可以将它简化为以下这种形式
typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);这段代码涉及的是 C 语言中的信号处理函数 signal 的声明。让我们逐步解释它 void(*)(int) 表示一个函数指针类型它指向一个接受一个 int 参数并返回 void 的函数。 signal 是一个函数它接受两个参数一个 int 参数和一个函数指针参数然后返回一个与上述函数指针类型匹配的函数指针。 所以整个代码声明的含义是signal 是一个函数它接受一个 int参数和一个函数指针参数返回一个函数指针该函数指针指向一个接受一个 int 参数并返回 void 的函数这个函数通常用于处理信号。 这段代码通常用于在 C 语言中设置信号处理函数以便在程序接收到特定信号时执行特定的操作。 请注意这里只是声明了 signal 函数的原型实际使用时需要根据具体情况编写函数体。 注 推荐《C陷阱和缺陷》 这本书中提及这两个代码。 二、函数指针数组
函数指针数组是 C 语言中一个强大且常用的工具用于存储指向不同函数的指针允许根据需要调用特定的函数。在本文中我们将深入介绍函数指针数组的概念、用途和实例帮助你理解并充分利用这一重要的 C 语言特性。
什么是函数指针数组
数组是一个存放相同类型数据的存储空间那我们已经学习了指针数组 比如
int *arr[10];
//数组的每个元素是int*那要把函数的地址存到一个数组中那这个数组就叫函数指针数组那函数指针的数组如何定义呢
int (*parr1[10])();
int *parr2[10]();
int (*)() parr3[10];答案是parr1 parr1 先和 [] 结合说明 parr1是数组数组的内容是什么呢 是 int (*)() 类型的函数指针。 函数指针数组的用途转移表 总之函数指针数组实际上是一个数组其元素都是指向函数的指针。这使得我们可以将不同的函数存储在数组中并通过索引来调用特定的函数。这种灵活性使得函数指针数组在编写菜单驱动程序、状态机、回调机制等方面非常有用。以下是一个简单的示例
#include stdio.hvoid func1()
{printf(调用 func1函数\n);
}void func2()
{printf(调用 func2函数\n);
}int main()
{void (*funcPtrArray[2])() {func1, func2};//函数指针数组funcPtrArrayfuncPtrArray[0](); //通过函数指针数组调用 func1funcPtrArray[1](); //通过函数指针数组调用 func2return 0;
}为什么使用函数指针数组
函数指针数组在以下情况下非常有用 菜单驱动程序 当需要实现一个用户界面允许用户从菜单中选择不同的操作时函数指针数组可以用来存储每个操作的处理函数。 状态机 在状态机的实现中可以使用函数指针数组来存储每个状态的处理函数从而实现状态转换时的操作。 回调机制 当你需要在某个事件发生时调用不同的函数比如事件处理、信号处理等函数指针数组提供了一种简洁的方式。 动态选择算法 如果你有多个算法实现但在运行时决定使用哪一个算法函数指针数组可以帮助你实现动态选择算法。
函数指针数组的基本用法
让我们通过一个简单的例子来演示函数指针数组的基本用法实现一个简单的计算器允许用户选择不同的操作。 例子计算机
#include stdio.hint add(int a, int b)
{return a b;
}int subtract(int a, int b)
{return a - b;
}int multiply(int a, int b)
{return a * b;
}int division(int a, int b)
{return a / b;
}int main()
{int x, y;int input 1;int restult 0;// 定义函数指针数组存储不同的操作函数//转移表int(*operation[])(int x, int y) { 0,add,subtract,multiply,division };while (input){printf(\n*************************\n);printf( 1:add 2:subtract \n);printf( 3:multiply 4:division \n);printf(*************************\n);printf(请选择);scanf(%d, input);if ((input 4 input 1)){printf(输入操作数);scanf(%d %d, x, y);restult (*operation[input])(x, y);// 调用选定的函数printf(restult %d\n, restult);}elseprintf(输入有误,请重新输入\n);}return 0;
}在上述示例中我们定义了一个函数指针数组 operation其中的元素分别指向 add、subtract 、 multiply和division 函数。用户可以根据选择来执行不同的操作。 三、 指向函数指针数组的指针
指向函数指针数组的指针是什么
指向函数指针数组的指针是一个指针指针指向一个的数组数组元素都是函数指针。这种指针提供了对函数指针数组的更高级别的访问方式使我们能够更灵活地处理函数指针数组。以下是一个示例
#include stdio.hvoid func1()
{printf(调用 func1函数\n);
}void func2()
{printf(调用 func2函数\n);
}int main()
{void (*funcPtrArray[2])() {func1, func2};//函数指针的数组funcPtrArrayvoid (*(*ptrToFuncPtrArray))() funcPtrArray;//指向函数指针数组funcPtrArray的指针ptrToFuncPtrArrayptrToFuncPtrArray[0](); // 通过指向函数指针数组的指针调用 func1ptrToFuncPtrArray[1](); // 通过指向函数指针数组的指针调用 func2return 0;
}为什么使用指向函数指针数组的指针
指向函数指针数组的指针可能在日常编程中不常见但在某些情况下非常有用。以下是一些使用情况 函数指针数组的参数传递 通过传递指向函数指针数组的指针作为参数可以避免复制整个数组从而提高效率。 动态函数调用 使用指向函数指针数组的指针可以在运行时根据条件选择不同的函数进行调用。 代码模块化 当函数指针数组较大或需要在多个函数之间共享时使用指向函数指针数组的指针可以提高代码的模块化性。 函数指针数组的排序 可以使用指向函数指针数组的指针来执行对函数指针数组的排序操作以实现按照某种规则调用函数。
总结 在本篇博客中我们深入探讨了 C语言中的三个重要概念函数指针、函数指针数组和指向函数指针数组的指针。这些概念虽然可能听起来有些复杂但它们为我们在C编程中提供了更大的灵活性和功能。函数指针允许我们将函数作为数据传递给其他函数或存储在数据结构中。通过使用函数指针我们可以实现更动态和可配置的程序设计同时避免代码的重复。函数指针数组进一步扩展了这种灵活性允许我们将多个函数指针组织在一个数组中以便在运行时根据需要选择和调用不同的函数。这在构建可插拔的模块和实现动态行为时特别有用。最后我们介绍了指向函数指针数组的指针这为我们提供了一种更高级的访问方式使得处理函数指针数组变得更加优雅。它可以应用于参数传递、动态函数调用、代码模块化以及对函数指针数组的排序等各种场景从而增强了程序的模块性、可维护性和性能。 今天的分享就到这里 如果觉得博主的文章还不错的话 请三连支持一下博主哦