C语言第十一课

主要内容:函数指针

一、函数指针的定义

int  maxValue(int  a,int  b)

{

return   a > b ? a : b;

}

函数名和数组名一样是地址,存在在代码区

int  maxValue(int  a,int  b)

int  (*p)(int,int)=  NULL

函数指针定义,p是变量,其他是类型(通常没有形参a,b)

p = maxValue(函数指针的使用:赋值函数名)

int  m = p(3,5)(指针可当函数用)

练习:定义两个函数,一个求最大值,一个求和,用户从控制台输入两个整数,在从控制台输入max或sum分别求3和5的最大值或和,(提示:定义一个函数指针,根据输入内容指向不同的函数,最后一次调用完成)

int  maxValue ( int a, int  b )    / / 求最大值的函数

{

return  a > b ? a : b;

}

int  sumValue ( int a, int b )     / / 求和的函数

{

return  a + b;

}

int  main( int argc, const char *argv[])

{

void (*p) (int , int) = NULL;                           / / 定义一个指针变量

int   a  , b;                                                     / / 定义两个需要用的整型变量

printf(" 请输入两个整数: ");                        / / 让用户输入两个整数

scanf(" %d%d ",&a,&b);                               / / 标准的输入函数

printf(" 请输入sum或者max: ");                 / /  让用户输入sum或者max

char  *name = malloc(sizeof(char) * 10);     / /  申请char类型的乘以10的内存空间

scanf(" %s ", name);

/ / 判断用户输入的是sum还是max

if (strcmp(name, " sum ") == 0){

p = sumValue;

}else if (strcmp(name, " max ") == 0){

p = maxValue;

}else {

printf(" 输入错误,失败 ");

}

free (name);        / /  释放内存,一定不能忘

int  result = p(a, b);
/ /  定义result接收结果

printf(" %d ", result);
/ /  输出结果

}

二、回调函数

函数指针做参数

int  getValue(int  a, int  b, int  (*p)(int , int));

getValue: 函数名

int (*p)(int ,int): 函数指针做getValue函数的参数

int  value = getValue(3, 5, maxValue);(函数调用:getValue函数执行过程中再调用(回调)maxValue)

如图所示:

练习:写一函数查找成绩在90分以上的学生,是用回调函数在姓名后面加“高富帅”

typedef  struct {           / /  定义一个结构体

char name[20];

int  age;

float  score;

} Student;

void  printfStudent(Student  *stu, int  count);

void  printfStudent(Student  *stu, int  count)   / /  声明并编写一个打印结构体数组的函数

{

for(int  i = 0; i < count ; i++){

printf("%s %d %.2f", (stu + i) ->name, (stu + i) ->age, (stu + i) ->score);

}

}

/ / 声明并编写查找90分以上的学生并在姓名后面加“高富帅”

void  changeStudent(Student  *stu, int count,  void (*p)(Student  *));

void  changeStudent(Student  *stu, int count,  void(*p)(Student  *))

{

for (int  i = 0; i < count ; i++){

if ((stu + i) ->score >= 90){

p(stu + i);

}

}

}

void  changeName(Student *stu);

void  changeName(Student *stu)

{

strcat (stu ->name, " 高富帅 ");

}

int  main(int argc, const char*argv[]){

Student  student = {
/ / 定义结构体变量

{" 方世玉 ", 26,  92},

{" 令狐冲 ", 30,  89},

{" 韦小宝 ", 27,  99},

{" 花仙子 ", 20,  80},

{" 大教主 ", 24,  80}

};

int  count  = sizeof(student) / sizeof(Student);  / / 求结构体数组的长度

printfStudent(stuent, count);
 / / 打印没查找前的结构体数组

changeStudent(student, count, changeName); / / 判断是否符合条件90分以上的进行改变

printfStudent(student,  count)  / / 打印查找后的结构体数组

}

三、动态排序

排序需求不定,无法预测的需求变更

void  sortArray(int  *array,  int  count)

{

for (int i = 0; i < count - 1; i++){

for (int j = 0; j < count - 1 - i; j++){

if (条件(需求)) {

交换

}

}

}

}

决定排序方式的重要语句封装成函数在此回调

int 数组动态排序

typedef  BOOL(* PFUNC)(int , int);   / / 为函数指针类型起名为PFUNC

void  sortArray(int  *array, int count , PFUNC  p);  / / 动态函数排序声明

示例:

/ / 1:创建一个结构体

typedef  struct {

char  name[20];

int  age;

float  score;

} Student;

/ / 3:打印学生结构体数组的函数

void  printfStudent(Student  *stu,  int  count);

void  printfStudent(Student  *stu,  int  count)

{

for (int  i = 0; i < count; i++){

printf("%s %d %.2f",(stu + i) ->name, (stu + i) ->age,  (stu + i) ->score);

}

printf("\n");

}

/ / 5:写一个函数根据分数从小到大排序

void   paiXuStudent(Student  *stu,  int  count,  BOOL (*PFUNC)(Student  *stu1,  Student  *stu2));

void   paiXuStudent(Student  *stu,  int  count,  BOOL (*PFUNC)(Student  *stu1,  Student  *stu2))

{

for (int  i = 0; i < count - 1; i++){

for (int  j = 0; j < count - 1 - i; j++){

if (PFUNC((stu + j), (stu + j + 1))){

Student  temp;

temp = *(stu + j);

*(stu + j) = *(stu + j + 1);

*(stu + j + 1) = temp;

}

}

}

}

/ / 6:定义一个按分数比较大小的函数

BOOL  biJiaoScore(Student  *stu1,  Student  *stu2);

BOOL  biJiaoScore(Student  *stu1,  Student  *stu2)

{

return  stu1 ->score  >  stuff ->score;

}

/ / 定义一个按年龄排序的函数

BOOL  compareAge(Student  *stu1, Student  *stu2);

BOOL  compareAge(Student  *stu1, Student  *stu2)

{

return  stu1 ->age  >  stuff ->age

}

int  main(int  argc, char  * argv[]){

/ / 2:创建学生结构体数组

Student  *student = {

{"索隆",  22,  93},

{"香吉士",  21,  97},

{"犬夜叉",  20,  80},

{"路飞",  19,  70}

};

/ / 4:排序前调用打印函数打印结构体数组

int  count = sizeof(student) / sizeof(Student);

printfStudent(student, count);

/ / 7:调用函数

paiXuStudent(student,  count , biJiaoScore);

/ / paiXuStudent(student,  count , compareAge);按年龄排序(只需传入函数就可)

/ / 8:打印排序后的结构体数组

printfStudent(student,  count);

}

时间: 2024-10-06 19:55:50

C语言第十一课的相关文章

嵌入式 Linux C语言(十一)——C语言模块化编程

嵌入式 Linux C语言(十一)--C语言模块化编程 一.C语言模块化编程 所谓模块化编程,就是指一个程序包含多个源文件(.c 文件和 .h 文件),每个模块即是一个.c文件和一个.h文件的结合,头文件(.h)中是对于该模块接口的声明.C语言模块化编程中对.c..h文件的潜规则: 1..c 文件主要负责实现,也就是定义函数:.h 文件主要负责声明,比如函数声明.宏定义等,结构的定义.自定义数据类型一般也放在头文件中,不能在.h文件中定义变量.将一个功能模块的代码单独编写成一个.c文件,然后把该

【C++探索之旅】第一部分第十一课:小游戏,猜单词

内容简介 1.第一部分第十一课:小游戏,猜单词 2.第一部分第十二课预告:指针一出,谁与争锋 小练习 上一课<[C++探索之旅]第一部分第十课:文件读写,海阔凭鱼跃>中我们学习了读写文件的知识. 第一部分的课程也快接近尾声了,下一课我们会学习很重要的指针的知识.之后,我们就进入第二部分:面向对象编程了.哈哈哈,激动不? 目前为止,我们也学了不少内容:编译基本原理,IDE,变量,函数,条件语句,循环语句,引用,数组,文件读写,等等.你应该为自己感到自豪. 俗语说得好:实践是最好的老师.我们学了那

BeagleBone Black板第十一课: PWM子系统简介

BBB板第十一课: PWM子系统简介 查看多达4000多页的AM335X 英文手册,找到其中的15章节PWMSS,我英文学不好,翻译其中的意思真难,建议高手帮翻译一下那4000多页的手册贡献给大家. 在这里简单说下几个专业名词: PWMMSS全称Pulse-Width Modulation Subsystem 脉冲宽度调制子系统,由eHRPWM.eCAP和eQEP三个模块组成,简单的说就是三种工作模式. 下面的图为PWM子系统图(来自4000多页的手册) 1.eHRPWM全称Enhanced H

Kali Linux Web 渗透测试视频教程—第十一课-扫描、sql注入、上传绕过

Kali Linux Web 渗透测试视频教程—第十一课-扫描.sql注入.上传绕过 文/玄魂 原文链接:http://www.xuanhun521.com/Blog/2014/10/25/kali-linux-web-%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B%E7%AC%AC%E5%8D%81%E4%B8%80%E8%AF%BE-%E6%89%AB%E6%8F%8Fsql%E6%B3%A8%

iOS学习笔记---c语言第十一天

函数指针 一.函数指针定义 //函数声明:声明我是一个什么函数 //求两个数的和 //函数的类型:int (int x,int y) //即:我是一个返回值为整型,有两个整型参数的函数. //函数名是 sum int sum(int x,int y); 函数指针定义p是变量,其他是类型(通常没有形参a,b) //函数指针类型 int (*)(int x,int y) //描述:指向 返回值为 int 两个int参数 的 指针类型 //函数指针变量: p //初始值 : sum printf("%

《快乐编程大本营》java语言训练班 2课:java的变量

<快乐编程大本营>java语言训练班 2课:java的变量 1变量介绍 2变量分类,数值变量 3变量分类-字符串变量 4变量分类-布尔变量 5变量分类-对象 http://code6g.com/pxphp/px/ban2.php?_lmbh1=001&_lmbh2=001001&_lmbh3=001001002提供一对一辅导服务,编程问题找牛哥: 原文地址:http://blog.51cto.com/13149944/2316187

linux就该这么学第十一课

linux就该这么学第十一课 网络配置的四种方式: 1.vim /etc/sysconfig/network-scripts/ifcfg-eno 2.nmtui 图形化配置 3.nm-connection-editor图形化配置 4.右上角的图形化网络图标设置 RHEL7:nmtui RHEL5/6:setup 网络会话 查看网络 nmcli connection show 创建网络会话 nmcli connection add con-name company ifname eno167777

Python第二十一课(反射/元类)

Python第二十一课(反射/元类)    >>>思维导图>>>中二青年 反射reflect 什么是反射, 其实是反省,自省的意思 反射指的是一个对象应该具备,可以检测,修改,增加自身属性的能力 反射就是通过字符串操作属性 涉及的四个函数,这四个函数就是普通的内置函数 没有双下划綫,与print等等没有区别 hasattr getattr setattr delattr p = Person("jack",18,"man") #

C语言-第33课 - 认清函数的真面目

第33课 - 认清函数的真面目 一.概念 函数的由来 程序 = 数据 + 算法 C程序 = 数据 + 函数 我们下面分析一下汇编语言,汇编语言是从上到下顺序执行的,汇编为了循环执行,就有了跳转指令.通过来回的跳转,就存在了不同的功能模块,这也就是我们C语言中的函数的原型. 函数的意义 模块化程序设计: C语言中的模块化: 面向过程的程序化设计 (1) 面向过程是一种以过程为中心的编程思想. (2) 首先将复杂的问题分解为一个个容易解决的问题. (3) 分解过后的问题可以按照步骤一步步完成. (4