目录

函数指针

解析两段代码

函数指针数组

设计一个计算器

回调函数

模拟实现qsort函数

指针数组笔试练习


函数指针

存放函数地址的指针      int(*p)()

int Add(int x, int y)
{return x + y;
}
int main()
{int (*p)(int a, int b) = &Add;printf("%p \n", Add);printf("%p \n", &Add);return 0;
}

 函数指针——存放函数地址的指针

&函数名——取得是函数的地址

int Add(int x, int y)
{return x + y;
}
int main()
{int (*p)(int, int) = Add;int ret1 = (*p)(1, 3);int ret2 = p(1, 3);int ret3 = Add(1, 3);printf("ret1= %d ret2 = %d ret3 = %d \n", ret1,ret2,ret3);return 0;
}

通过代码我们可以直接发现ret1 ret2 ret3得到的答案是相同的,Add的地址可以放入p中。

ret1和ret2结果也相同说明这里的解引用*只是为了方便理解

解析两段代码

//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int)

函数指针数组

把函数的地址存放到一个数组之中,这样的数组叫函数指针数组

设计一个计算器

实现加减乘除

int Add(int x, int y)
{return x + y;
}
int Sub(int x, int y)
{return x - y;
}
int Mul(int x, int y)
{return x * y;
}
int Div(int x, int y)
{return x / y;
}
void menu()
{printf("**************************\n");printf("**** 1. Add    2. Sub ****\n");printf("**** 3. Mul    4. Div ****\n");printf("****     0. Exit      ****\n");printf("**************************\n");
}
int main(){int (*pf[5])(int, int) = { 0,Add, Sub,Mul,Div };int input = 0;int x = 0;int y = 0;do{menu();scanf("%d", &input);printf("请选择:>");switch (input){case 1:printf("请输入两个操作数\n");scanf("%d%d", &x, &y);printf("输入完毕,结果是:\n");printf("%d\n", Add(x, y));break;case 2:printf("请输入两个操作数\n");scanf("%d%d", &x, &y);printf("输入完毕,结果是:\n");printf("%d\n", Sub(x, y));break;case 3:printf("请输入两个操作数\n");scanf("%d%d", &x, &y);printf("输入完毕,结果是:\n");printf("%d\n", Mul(x, y));break;case 4:printf("请输入两个操作数\n");scanf("%d%d", &x, &y);printf("输入完毕,结果是:\n");printf("%d", Div(x, y));break;case 0:printf("退出\n");break;default:printf("输入有误,请重新输入\n");break;}} while (input);return 0;}

回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一 个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该 函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或 条件进行响应。

模拟实现qsort函数

先用qsort实现

struct LC
{char name[30];int age;int grade;
};
int compare(const void* a, const void* b)
{return ((struct LC*)a)->grade - ((struct LC*)b)->grade;
}int main()
{struct LC information[5] = {{"张三",20,65},{"李四",19,71},{"王五",27,85}, {"赵六",17,69},{"钱七",18,90}};qsort(information, sizeof(information) / sizeof(information[0]), sizeof(information[0]), compare);for (int i = 0; i < 5; i++){printf("%s  ", information[i].name);}return 0;
}

模拟实现qsort

struct LC
{char name[30];int age;int grade;
};/*因为指针就收的地址是第一个字节,所以需要挨个交换*/
void swap(char* a, char* b, int width)
{for (int i = 0; i < width; i++){char tmp = *b;*b = *a;*a = tmp;a++;b++;}
}
int compare(const void* a, const void* b)
{return ((struct LC*)a)->grade - ((struct LC*)b)->grade;
}
//1
void my_qsort(void* base, int number, int size, int(*compare)(const void*, const void*))
{//2int i = 0, j = 0;for (i = 0; i < number - 1; i++){for (j = 0; j < number - 1 - i; j++){//3if (compare((char*)base + j * size, (char*)base + (j + 1) * size) > 0){//如果返回值大于0,说明前面的值比后面大,所以我们需要交换前后两个值swap((char*)base + j * size, (char*)base + (j + 1) * size, size);}}}
}int main()
{struct LC information[5] = { {"张三",20,65},{"李四",19,71},{"王五",27,85}, {"赵六",17,69},{"钱七",18,90} };my_qsort(information, sizeof(information) / sizeof(information[0]), sizeof(information[0]), compare);for (int i = 0; i < 5; i++){printf("%s  ", information[i].name);}return 0;

还可以尝试别的类型

指针数组笔试练习

strlen  是库函数 计算字符串长度,以\0结尾

sizeof  是操作符  用来计算变量或者对象、类型所占字节的多少

【C语言】指针进阶(2)相关推荐

  1. C语言指针进阶(2)

    上一篇一起探讨了指针进阶的字符指针.指针数组和数组指针.这一篇我们继续来学习C语言指针进阶的第二部分,主要内容包括数组传参和指针传参.函数指针和函数指针数组. 目录 数组传参.指针传参 一维数组传参 ...

  2. 解密英文藏头诗C语言,《C语言指针进阶》PPT课件.ppt

    2020年3月26日 第1页 第11章指针进阶 2020年3月26日 第2页 本章要点 指针数组和指向指针的指针是如何被定义和使用的 指针如何作为函数的返回值 指向函数的指针的意义是什么 什么是结构的 ...

  3. C进阶_C语言_函数与指针_C语言指针进阶

    上一篇博客http://t.csdn.cn/GYCiM 我们了解了指针相关知识,今天来了解函数和指针的关系. 目录 函数指针 函数指针数组 指向函数指针数组的指针 回调函数 qsort 冒泡排序模拟实 ...

  4. 带你刷笔试关的小怪|详解指针习题和面试题【C语言/指针/进阶】

    文章目录 前言 9. 指针和数组笔试题解析 复习回顾 一维数组 字符数组 二维数组 10. 指针笔试题 笔试题1: 笔试题2 笔试题3 笔试题4 笔试题5 笔试题6 笔试题7 (#)笔试题8 结语 前 ...

  5. C语言指针进阶(1.一阶与二阶指针)

    目录 一.一阶指针与二阶指针 一.一阶指针 二.二阶指针以及高阶指针 一.一阶指针与二阶指针 一.一阶指针 字符指针char*,浮点指针double* 等等类比 整数指针 int* 1.指针是用来存取 ...

  6. C语言———指针进阶3

    目录 6.函数指针数组: 7.指向函数指针数组的指针: 8..回调函数 : 6.函数指针数组: 函数指针数组是存放函数指针的数组,数组中每个元素的类型都是函数指针类型. 因为,Add是加法函数,,Su ...

  7. C语言~指针进阶(1)

    一维数组指针: 数组名:可以代表首地址,那么咱们就可以用指针指向数组. 虽然数组名可以代表一个元素首地址,但是它是个常量,不能自增或者自减!但是可以创建一个指针指向数组,然后++. int arr[1 ...

  8. 字符指针?指针数组?数组指针?《C语言指针进阶第一重奏》

    目录 一.字符指针 1.1字符指针的认识 1.2字符指针存放字符串 1.3字符指针的使用 二.指针数组 2.1指针数组的认识 三.数组指针 3.1数组指针的认识 3.2数组名和&数组名的区别 ...

  9. C语言指针进阶(中)

    提示: 上集内容小复习

  10. C语言——指针(进阶版)

                            目录 指针的进阶 1.字符指针 2.指针数组 3.数组指针 3.1 数组指针的定义 3.2数组指针的使用 4.动态内存分配与指向它的指针变量 4.1 什 ...

最新文章

  1. php如何对数组进行分组,如何在PHP中对数组进行分组排序
  2. 工信部 学习类app_工信部整治APP侵权行为,私自收集个人信息等8类问题被点名...
  3. centos7 安装mysql 解决:Failed to restart mysqld.service: Unit not found
  4. Nat. Biotech.|药物设计的AI生成模型
  5. R语言数据包自带数据集之survival包的colon数据集字段解释、数据导入实战
  6. SWT让耗时的操作后台运行
  7. 寻找兄弟单词(2012.5.6百度实习)
  8. 三、在应用中升级----网络编程部分
  9. keepalived实现nginx的高可用
  10. openstack cluster 封装
  11. margin为负值的几种情况
  12. 设计模式:高性能IO之Reactor模式
  13. eclipse里source的快捷方法_教你如何在Linux中设置快捷方式图标
  14. 第 3 章 JVM 与 GC
  15. 常用正则表达式归类贴
  16. Mysql 单表、连表 in 子查询条件拼接
  17. Pytorch基础知识(7)单目标检测
  18. 机器学习 一元非线性回归模型
  19. Powerdesigner pdm视图看不到表注释comment问题
  20. c语言topic函数,ROS学习笔记(一) 话题topic的定义与使用(publisher 和 subscriber)

热门文章

  1. Torchtext下的AG_NEWS数据集进行分类(官方文档代码)
  2. DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN
  3. Ajax入门介绍篇:Ajax开发基础
  4. 为人处事说话技巧思维
  5. 【LaTeX】LaTeX新手入门教程-基础排版
  6. 第九届广东省大学生程序设计竞赛排名
  7. python读取grib格式数据
  8. 青龙面板——每日自动拿京豆
  9. R语言 coalesce 函数
  10. 中国象棋将帅问题的另类解法