当前位置: 首页 > news >正文

C 学习笔记 —— 函数指针

函数指针

上面的第二个char (* f) (int);写法就是函数指针的声明;
首先,什么是函数指针?假设有一个指向 int类型变量的指针,该指针储存着这个int类型变量储存在内存位置的地址。 同样,函数也有地址,因为函数的机器语言实现由载入内存的代码组成。指向函数的指针中储存着函数代码的起始处的地址。

函数的指针作用

通常函数的指针作为 另一个函数的参数。
也就是当你想将一个函数作为参数传给另一个函数的时候,比如
我想在一个函数中使用其他任意函数,那么我就需要将其他函数作为参数传进来,如下:
void show(void (* fp)(char *), char * str);

比如C语言中<stdlib.h>中有个qsort
他的函数原型为

void qsort(void *base, int nelem, int width, int (*fcmp)(const void *,const void *))

各参数:

  1. 待排序数组首地址(可直接输入待排序数组名,或是指向数组的指针)
  2. 数组中待排序元素数量(可以用sizeof()来求)
  3. 各元素的占用空间大小(可以用sizeof(arr[0])来求)
  4. 指向函数的指针

qsort()函数可以处理任意类型的数组,但是要告诉 qsort()使用哪个函数来比较元素。为此, qsort()函数的参数列表中,有一个 参数接受指向函数的指针。然后,qsort()函数使用该函数提供的方案进行排序,无论这个数组中的元素是整数、字符串还是结构。例如,排序数组涉及比较两个元素,以确定先后。如果 元素是数字,可以使用>运算符;如果元素是字符串或结构,就要调用函数 进行比较

赋值

给函数指针赋值

void (*pf)(char *); //函数指针的声明
void ToUpper(char *); 
void ToLower(char *); 
int round(double); pf = ToUpper;   // 有效,ToUpper是该类型函数的地址 
pf = ToLower;   // 有效,ToUpper是该类型函数的地址 
pf = round;    // 无效,round与指针类型不匹配 
pf = ToLower();  // 无效,ToLower()不是地址

使用

void ToUpper(char *); 
void ToLower(char *); 
void (*pf)(char *); 
char mis[] = "Nina Metier"; 
pf = ToUpper; 
(*pf)(mis);  // 使用方式一:把ToUpper 作用于(语法1) 
pf = ToLower; 
pf(mis);   // 使用方式二:把ToLower 作用于(语法2)

这两种表示法其实等价,只不过第二种方式不是很好看。所以尽量使用第一种使用方式。

下面我们看一个具体实例:

// func_ptr.c -- uses function pointers
#include <stdio.h>
#include <string.h>
#include <ctype.h>void show(void (* fp)(char *), char * str);
void ToUpper(char *);   // convert string to uppercase
void ToLower(char *);   // convert string to uppercase
void Transpose(char *); // transpose cases
void Dummy(char *);     // leave string unalteredint main(void)
{void (*pfun)(char *); // points a function having a char * argument and no return valuechar choice = 'l';char line[] = "fanganFDNGlajf";char copy[81];switch (choice)  // switch sets pointer{case 'u' : pfun = ToUpper;   break; //给函数指针赋值case 'l' : pfun = ToLower;   break;case 't' : pfun = Transpose; break;case 'o' : pfun = Dummy;     break;}strcpy(copy, line);// make copy for show()show(pfun, copy);  // use selected functionreturn 0;
}void ToUpper(char * str)
{while (*str){*str = toupper(*str);str++;}
}void ToLower(char * str)
{while (*str){*str = tolower(*str);str++;}
}
void Transpose(char * str)
{while (*str){if (islower(*str))*str = toupper(*str);else if (isupper(*str))*str = tolower(*str);str++;}
}void Dummy(char * str)
{// leaves string unchanged
}// 定义函数,将一个函数指针作为第一个参数
void show(void (* fp)(char *), char * str)
{(*fp)(str); // apply chosen function to str,调用传入的函数puts(str);  // display result
}

最后我们可以看到函数名有四种用法
在这里插入图片描述

相关文章:

C 学习笔记 —— 函数指针

函数指针 上面的第二个char (* f) (int);写法就是函数指针的声明&#xff1b; 首先&#xff0c;什么是函数指针&#xff1f;假设有一个指向 int类型变量的指针&#xff0c;该指针储存着这个int类型变量储存在内存位置的地址。 同样&#xff0c;函数也有地址&#xff0c;因为函…...

FastDDS-3. DDS层

3. DDS层 eProsima Fast DDS公开了两个不同的API&#xff0c;以在不同级别与通信服务交互。主要API是数据分发服务&#xff08;DDS&#xff09;数据中心发布订阅&#xff08;DCPS&#xff09;平台独立模型&#xff08;PIM&#xff09;API&#xff0c;简称DDS DCPS PIM&#xf…...

9.2 IGMPv2

实验目的 &#xff08;1&#xff09; 熟悉IGMPv2的应用场景 &#xff08;2&#xff09; 掌握IGMPv2的配置方法 实验拓扑 实验拓扑如图9-17所示&#xff1a; 图9-17&#xff1a;IGMPv2 实验步骤 配置IP地址&#xff08;请参考上一个实验&#xff09;运行IGP&#xff…...

巨头混战,抢着“兜底”自动驾驶安全

诚然&#xff0c;中国汽车行业的发展绝对不会拘泥于电动化&#xff0c;必定会在电动化的基础上&#xff0c;迎接下半场的快速智能化。 2021年6月&#xff0c;长城汽车线控底盘全球首次发布。 彼时&#xff0c;长城汽车技术副总裁宋东先宣布&#xff0c;整合了线控转向、线控制…...

RightCapital 第一轮面试题

现在我们就马上开始吧&#xff01; 答案在文末 JavaScript 是一门单线程的静态类型语言&#xff08;单选题&#xff09; 正确 错误 在 JavaScript 中下面哪种类型的值是不可变的&#xff08;immutable&#xff09;&#xff08;单选题&#xff09; Object Symbol Array Date …...

Python曲线肘部点检测-膝部点自动检测

文章目录一. 术语解释二. 拐点检测肘部法则是经常使用的法则。很多时候&#xff0c;可以凭人工经验去找最优拐点&#xff0c;但有时需要自动寻找拐点。最近解决了一下这个问题&#xff0c;希望对各位有用。一. 术语解释 **肘形曲线(elbow curve)**类似人胳膊状的曲线&#xff…...

【算法题】最大矩形面积,单调栈解法

力扣&#xff1a;84. 柱状图中最大的矩形 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 题意很简单&#xff0c;翻译一下就是&#xff1a;求该图中…...

活动策划|深度分析年货节活动该如何策划!

四月初&#xff0c;不平凡的初春开始恢复往日的平静。对于新零售行业&#xff0c;疫情的缓解也逐渐平稳生态链的运转。2020年新零售的格局在洗礼后&#xff0c;业务的聚焦点也从前端促销转移到后端履约的体验闭环&#xff0c;同时很大程度的推进企业在危机公关下的应对。618大促…...

Idea启动遇到 Web server failed to start. Port 8080 was already in use. 报错

Idea启动遇到问题-记录 报错英文提示&#xff1a; APPLICATION FAILED TO START Description: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to liste…...

Python3中zip()函数知识点总结

1.引言 在本文中&#xff0c;我将带领大家深入了解Python中的zip()函数&#xff0c;使用它可以提升大家的工作效率。 闲话少说&#xff0c;我们直接开始吧&#xff01; 2. 基础知识 首先&#xff0c;我们来介绍一些基础知识点&#xff1a; Python中的某些数据类型是不可变的…...

过滤器,监听器,拦截器的原理与在Servlet和Spring的应用

在Java Web的开发中&#xff0c;最原始和初期的学习都是从Servlet开始的&#xff0c;Servlet是Java最为耀眼的技术&#xff0c;也是Java EE的技术变革。目前大火主流的框架spring boot也的spring mvc部分也是基于拓展servlet完成的。回到之前的文章spring 实现了对servlet的封装…...

minio spring boot 秒传、分片上传、断点续传文件实现

此处后端使用的是前期封装的自定义starter&#xff0c;具体链接可参考&#xff1a;minio对象存储spring boot starter封装组件 这里主要针对前期封装的组件&#xff0c;做一个简单的应用&#xff0c;前端直传可查看之前的文章 秒传 秒传的逻辑比较简单&#xff0c;在前传上传…...

MTK平台使用Omnipeek分析空口协议讲解

讲解这个之前,我们先来了解下beacon/robe Request/Probe Response 三种帧 beacon帧 信标帧,由AP以一定的时间间隔周期性发出,以此来告诉外界自己无线网络的存在。 Beacon帧作为802.11中一个周期性的帧,Beacon周期调高,对应睡眠周期拉长,故节能(即越来休息100ms再起来…...

string和自动推断类型

欢迎来观看温柔了岁月.c的博客目前设有C学习专栏C语言项目专栏数据结构与算法专栏目前主要更新C学习专栏&#xff0c;C语言项目专栏不定时更新待C专栏完毕&#xff0c;会陆续更新C项目专栏和数据结构与算法专栏一周主要三更&#xff0c;星期三&#xff0c;星期五&#xff0c;星…...

【软件测试】从功能到自动化测试,测试人的进阶之路细节,这些必不可少......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 测试流程&#xff0…...

C语言青蛙跳台阶【图文详解】

青蛙跳台阶前言1. 题目介绍2. 解题思路3. 利用图片来演示青蛙跳台阶的原理4. 如何用C语言实现青蛙跳台阶前言 在本文&#xff0c;我们要与一只活泼可爱的小青蛙合作&#xff0c;带领着它跳上台阶&#xff0c;这个小家伙精力充沛&#xff0c;特别擅长于跳跃。我们要让它做我们的…...

笔记(五)——list容器的基础理论知识

list容器是一个双向链表容器&#xff0c;可以高效地进行插入删除元素&#xff0c;但是不能随机存取元素&#xff08;不支持at()和[]操作符&#xff09;。一、list容器的对象构造方法list对象采用模板类的默认构造形式例如list<T> lst&#xff1b;#include<iostream>…...

浅谈网络中接口幂等性设计问题

所谓幂等性设计&#xff0c;就是说&#xff0c;一次和多次请求某一个资源应该具有同样的副作用。用数学的语言来表达就是&#xff1a;f(x) f(f(x))。 在数学里&#xff0c;幂等有两种主要的定义。 在某二元运算下&#xff0c;幂等元素是指被自己重复运算&#xff08;或对于函数…...

《C Primer Plus》第13章复习题与编程练习

《C Primer Plus》第13章复习题与编程练习复习题1. 下面的程序有什么问题&#xff1f;2. 下面的程序完成什么任务&#xff1f;&#xff08;假设在命令行环境中运行&#xff09;3. 假设程序中有下列语句&#xff1a;4. 编写一个程序&#xff0c;不接受任何命令行参数或接受一个命…...

计算机SCI论文应该怎么作图? - 易智编译EaseEditing

计算机SCI论文&#xff0c;作图时要注意以下几个方面的问题&#xff1a; 1.图片的格式要tiff或者eps&#xff1b; 2.文件大小不能超过10M&#xff1b; 3.长和宽也给出了具体要求&#xff1b; 4.色彩模式要RGB或者灰度图&#xff1b; 5.文中的文字字体和大小&#xff1b; …...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

均衡后的SNRSINR

本文主要摘自参考文献中的前两篇&#xff0c;相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程&#xff0c;其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt​ 根发送天线&#xff0c; n r n_r nr​ 根接收天线的 MIMO 系…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

前端中slice和splic的区别

1. slice slice 用于从数组中提取一部分元素&#xff0c;返回一个新的数组。 特点&#xff1a; 不修改原数组&#xff1a;slice 不会改变原数组&#xff0c;而是返回一个新的数组。提取数组的部分&#xff1a;slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...