前言

在C语言中,指针函数和函数指针是强大且常用的工具。它们允许我们以更灵活的方式处理函数和数据,进而扩展程序的功能。

本文将介绍指针函数和函数指针的概念,并讲解一些常见的应用示例。

一、人物简介

  • 第一位闪亮登场,有请今后会一直教我们C语言的老师 —— 自在。

  • 第二位上场的是和我们一起学习的小白程序猿 —— 逍遥。

二、指针函数

  • 指针函数是返回指针的函数,它的声明和定义与普通函数类似,但返回类型是一个指针类型。

  • 指针函数可以用于返回数组、字符串或动态分配的内存等。

  • 示例代码

#include <stdio.h>

int* getArray() {
static int arr[] = {1, 2, 3, 4, 5};
return arr;
} int main() {
int* ptr = getArray(); printf("Array elements: ");
for (int i = 0; i < 5; i++) {
printf("%d ", ptr[i]);
} return 0;
}
  • 在上面的示例中,getArray()函数返回一个指向静态整数数组的指针

  • main()函数中,我们通过指针访问并打印数组的元素

  • 输出结果

Array elements: 1 2 3 4 5

三、函数指针

  • 函数指针是指向函数的指针变量。

  • 通过函数指针,我们可以将函数作为参数传递给其他函数、在运行时动态选择要调用的函数等。

  • 示例代码

#include <stdio.h>

/* 加法运算 */
int add(int a, int b) {
return a + b;
} /* 减法运算 */
int subtract(int a, int b) {
return a - b;
} void calculate(int (*operation)(int, int), int a, int b) {
int result = operation(a, b);
printf("Result: %d\n", result);
} int main() {
int x = 10, y = 5; calculate(add, x, y);
calculate(subtract, x, y); return 0;
}
  • 在上面的示例中,calculate()函数接受一个函数指针参数operation,该参数指向一个具有两个整数参数和整数返回值的函数。

  • main()函数中,我们使用calculate()函数来执行加法和减法运算。

  • 运行结果

Result: 15
Result: 5

四、指针函数的应用

指针函数在以下情况下特别有用:

  • 动态分配内存:指针函数可以返回动态分配的内存,允许在运行时灵活地分配和释放内存。

  • 返回数组或字符串:通过指针函数,可以方便地返回数组或字符串,而无需将它们作为函数参数传递或使用全局变量。

  • 示例代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h> char* createString() {
char* str = (char*)malloc(sizeof(char) * 10);
strcpy(str, "Hello");
return str;
} int main() {
char* ptr = createString();
printf("String: %s\n", ptr);
free(ptr); return 0;
}
  • 在上面的示例中,createString()函数动态分配了一个大小为10的字符数组,并将字符串"Hello"复制到该数组中。

  • 然后,它返回该数组的指针。在main()函数中,我们打印并释放该字符串。

String: Hello

五、函数指针的应用

函数指针具有以下应用场景:

  • 回调函数:函数指针可用于实现回调机制,其中一个函数作为参数传递给另一个函数,并在需要时被调用。

  • 运行时函数选择:函数指针允许根据运行时的条件选择要调用的函数,从而实现动态的程序行为。

  • 示例代码

#include <stdio.h>

void greet_english() {
printf("Hello!\n");
} void greet_spanish() {
printf("Hola!\n");
} void greet_french() {
printf("Bonjour!\n");
} int main() {
int choice; // 声明函数指针,并初始化为NULL
void (*greet)() = NULL; printf("请选择要使用的语言:\n");
printf("1. 英语\n");
printf("2. 西班牙语\n");
printf("3. 法语\n");
printf("\n请输入对应的数字:");
scanf("%d", &choice);
printf("\n");
// 根据用户的选择设置函数指针
if (choice == 1) {
greet = greet_english;
} else if (choice == 2) {
greet = greet_spanish;
} else if (choice == 3) {
greet = greet_french;
} else {
printf("无效的选择!\n");
return 0;
} // 如果函数指针不为NULL,则调用相应的函数
if (greet != NULL) {
greet();
} return 0;
}
  • 在这个例子中,我们定义了三个不同的打招呼函数:greet_englishgreet_spanishgreet_french
  • main函数中,我们声明了一个函数指针greet,并将其初始化为NULL
  • 用户可以选择要使用的语言,然后根据选择将函数指针greet设置为相应的函数地址。
  • 最后,如果函数指针不为NULL,则调用相应的函数。
  • 运行结果
请选择要使用的语言:
1. 英语
2. 西班牙语
3. 法语 请输入对应的数字:3 Bonjour!

小结

通过这篇文章,我们学会了

1、指针函数的概念

2、函数指针的概念

3、指针函数的应用

4、函数指针的应用

欢迎各位 点赞 收藏 评论,如有错误请留言指正,非常感谢!

逍遥自在学C语言 | 指针函数与函数指针的更多相关文章

  1. 逍遥自在学C语言 | 第一个C语言程序 九层之台起于垒土

    一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一起学习的小白程序猿 -- 逍遥. 二.C语言简介 C语言是一种高级语言,运行效率仅次于汇编,支持跨平 ...

  2. 逍遥自在学C语言 | 变量、常量与数据类型

    前言 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一起学习的小白程序猿 -- 逍遥. 二.基本数据类型 1.整型 C语言中的整型数据如下表所示: ...

  3. 逍遥自在学C语言 | 算数运算符

    前言 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一起学习的小白程序猿 -- 逍遥. 二.算数运算符简介 C语言的算数运算符,是用来完成基本的算术 ...

  4. 逍遥自在学C语言 | 逻辑运算符

    前言 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一起学习的小白程序猿 -- 逍遥. 二.构成和表示方式 逻辑运算符是用来比较和操作布尔值的运算符 ...

  5. 逍遥自在学C语言 | 关系运算符

    前言 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一起学习的小白程序猿 -- 逍遥. 二.构成和表示方式 关系运算符的作用是判断符号两边大小的关系 ...

  6. 逍遥自在学C语言 | 位运算符的基础用法

    前言 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一起学习的小白程序猿 -- 逍遥. 二.构成和表达方式 位运算符是一组用于在二进制数之间进行操作 ...

  7. 逍遥自在学C语言 | 位运算符&的高级用法

    前言 在上一篇文章中,我们介绍了&运算符的基础用法,本篇文章,我们将介绍& 运算符的一些高级用法. 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位 ...

  8. 逍遥自在学C语言 位运算符 "|" 的5种高级用法

    前言 在上一篇文章中,我们介绍了&运算符的高级用法,本篇文章,我们将介绍| 运算符的一些高级用法. 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是 ...

  9. 逍遥自在学C语言 | 位运算符^的高级用法

    前言 在上一篇文章中,我们介绍了|运算符的高级用法,本篇文章,我们将介绍^ 运算符的一些高级用法. 一.人物简介 第一位闪亮登场,有请今后会一直教我们C语言的老师 -- 自在. 第二位上场的是和我们一 ...

  10. 逍遥自在学C语言 | 赋值运算符

    前言 在C语言中,赋值运算符用于将一个值赋给变量 这个过程分为两个步骤: 计算赋值运算符右侧的表达式 将结果赋给左侧的变量. C语言提供了多个不同的赋值运算符,包括基本的赋值运算符.复合赋值运算符以及 ...

随机推荐

  1. Flutter 下载篇 - 叁 | 网络库切换实践与思考

    前言 本文是关于使用flutter_download_manager下载功能的实践和探索.我们将基于flutter_download_manager的功能扩展,改造成自己想要的样子.在阅读本文之前,建 ...

  2. 在Android应用中通过Chaquopy使用Python

    在Android应用中通过Chaquopy使用Python [译] 通过Python脚本和包为Android应用带来更多的功能 翻译自https://proandroiddev.com/chaquop ...

  3. 有关SpringMVC的一些知识点

    Spring的获取对象 1.获取原生对象,直接在在方法李传http相关的对象.2.接受简单数据类型,接受简单数据类型(八种基本类型)参数直接在handler方法里声明,会自动把相同类型进行绑定,但是接 ...

  4. pandas安装1

    Python 官方标准发行版并没有自带 Pandas 库,因此需要另行安装.除了标准发行版外,还有一些第三方机构发布的 Python 免费发行版, 它们在官方版本的基础上开发而来,并有针对性的提前安装 ...

  5. [Java/LeetCode]算法练习:二进制间距(868/simple)

    1 题目描述 题目来源: https://leetcode-cn.com/problems/binary-gap/ 给定一个正整数 n,找到并返回 n 的二进制表示中两个 相邻 1 之间的 最长距离 ...

  6. The first week match's mistake-2

    旋转排列 (https://www.luogu.com.cn/problem/B3688) 解读一下题目: 要求从给定的数组拿出最后一个数字后 看看变化后的数组的最后一个数字是否是要求的数字 想到用栈 ...

  7. Spring源码系列(补充):详解ApplicationContext

    前言 在之前的文章中,我们已经对Spring源码中的一些核心概念进行了分析.由于篇幅限制,我们并没有详细解释ApplicationContext类所继承的父接口及其作用.因此,本文将单独为Applic ...

  8. 真实场景sql优化持续更新(老司机必备)

    概述 下述场景,均来自实际产品线上经验,出于保密考量,所有需求场景都是仿造的,模拟遇到过的真实场景. 场景一: 统计数据(Order by 不具备唯一性导致的分页数据混乱) 需求 在实际业务场景中,我 ...

  9. C# Nuget版本号排序

    Nuget包版本号和我们软件应用版本号一样,不过因为稳定性等的考虑,组件版本有更高的要求.预发布版本使用频率更高 版本号介绍,详见我朋友胡承老司机的博客:Nuget包的版本规范 (qq.com) 我这 ...

  10. 获取电脑的网络连接状态(三)Ping

    网络连接判断,使用ping测试获取: 1 private static async Task<bool> IsPingSuccess() 2 { 3 try 4 { 5 using (Pi ...