首页 > 其他分享 >理解C语言之深入理解指针(四)

理解C语言之深入理解指针(四)

时间:2024-10-02 10:18:17浏览次数:8  
标签:return int void ret C语言 理解 printf sizeof 指针

目录

1. 回调函数是什么?

2. qsort使⽤举例

2.1 使⽤qsort函数排序整型数据

2.2 使⽤qsort排序结构数据

3. qsort函数的模拟实现


1. 回调函数是什么?

        回调函数就是⼀个通过函数指针调⽤的函数。

         如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条 件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应。 第13讲中我们写的计算机的实现的代码中,红⾊框中的代码是重复出现的,其中虽然执⾏计算的逻辑 是区别的,但是输⼊输出操作是冗余的,有没有办法,简化⼀些呢? 因为红⾊框中的代码,只有调⽤函数的逻辑是有差异的,我们可以把调⽤的函数的地址以参数的形式 传递过去,使⽤函数指针接收,函数指针指向什么函数就调⽤什么函数,这⾥其实使⽤的就是回调函 数的功能。

//使⽤回调函数改造前 

#include <stdio.h>

int add(int a, int b)
{
 return a + b;
}

int sub(int a, int b)
{
 return a - b;
}

int mul(int a, int b)
{
 return a * b;
}

int div(int a, int b)
{
 return a / b;
}

int main()
{
 int x, y;
 int input = 1;
 int ret = 0;
 do

 {
 

printf("*************************
\n");
 printf(" 1:add 
 2:sub \n");
 printf(" 3:mul 
 4:div \n");
 

printf("*************************
\n");
 printf("请选择:");
 scanf("%d", &input);
 switch (input)
 {
 case 1:
 printf("输⼊操作数:");
 scanf("%d %d", &x, 
&y);
 ret = add(x, y);
 printf("ret = %d\n", 
ret);
 break;
 case 2:
 printf("输⼊操作数:");
 scanf("%d %d", &x, 
&y);
 ret = sub(x, y);
 printf("ret = %d\n", 
ret);
 break;
 case 3:
 printf("输⼊操作数:");
 scanf("%d %d", &x, 
&y);
 ret = mul(x, y);
printf("ret = %d\n", 
ret);
 break;
 case 4:
 printf("输⼊操作数:");
 scanf("%d %d", &x, 
&y);
 ret = div(x, y);
 printf("ret = %d\n", 
ret);
 break;
 case 0:
 printf("退出程序\n");
 break;
 default:
 printf("选择错误\n");
 break;
 }
 } while (input);
 return 0;
}
//使⽤回到函数改造后 

#include <stdio.h>

int add(int a, int b)
{
 return a + b;
}

int sub(int a, int b)
{
 return a - b;
}

int mul(int a, int b)
{
 return a * b;
}

int div(int a, int b)
{
 return a / b;
}

void calc(int(*pf)(int, int))
{
 int ret = 0;
 int x, y;
 printf("输⼊操作数:");
 scanf("%d %d", &x, &y);
 ret = pf(x, y);
 printf("ret = %d\n", ret);
}

int main()
{
 int input = 1;
 do

 {
 

printf("*************************
\n");
 printf(" 1:add 
 2:sub \n");
 printf(" 3:mul 
 4:div \n");
 

printf("*************************
\n");
 printf("请选择:");
 scanf("%d", &input);
 switch (input)
 {
 case 1:
 calc(add);
 break;
 case 2:
 calc(sub);
 break;
 case 3:
 calc(mul);
 break;
 case 4:
 calc(div);
 break;
 case 0:
 printf("退出程序\n");
break;
 default:
 printf("选择错误\n");
 break;
 }
 } while (input);
 return 0;
}

2. qsort使⽤举例

2.1 使⽤qsort函数排序整型数据

#include <stdio.h>

//qosrt函数的使⽤者得实现⼀个⽐较函数 

int int_cmp(const void * p1, const void * p2)
{
 return (*( int *)p1 - *(int *) p2);
}

int main()
{
 int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
 int i = 0;
 
 qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
 for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
 {
printf( "%d ", arr[i]);
 }
 printf("\n");
 return 0;
}

2.2 使⽤qsort排序结构数据

struct Stu //学⽣

{
 char name[20];//名字 
 int age;//年龄 
};

//假设按照年龄来⽐较 

int cmp_stu_by_age(const void* e1, const void* e2)
{
 return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}

//strcmp - 是库函数,是专⻔⽤来⽐较两个字符串的⼤⼩的 

//假设按照名字来⽐较 

int cmp_stu_by_name(const void* e1, const void* e2)
{
 return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}

//按照年龄来排序 

void test2()
{
 struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };
 int sz = sizeof(s) / sizeof(s[0]);
 qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}

//按照名字来排序 

void test3()
{
 struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };
 int sz = sizeof(s) / sizeof(s[0]);
 qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}

int main()
{
test2();
 test3();
 return 0;
}

3. qsort函数的模拟实现

使⽤回调函数,模拟实现qsort(采⽤冒泡的⽅式)。

 注意:这⾥第⼀次使⽤ void* 的指针,讲解 void* 的作⽤。

#include <stdio.h>

int int_cmp(const void * p1, const void * p2)
{
 return (*( int *)p1 - *(int *) p2);
}

void _swap(void *p1, void * p2, int size)
{
 int i = 0;
 for (i = 0; i< size; i++)
 {
 char tmp = *((char *)p1 + i);
 *(( char *)p1 + i) = *((char *) p2 + i);
 *(( char *)p2 + i) = tmp;
 }
}

void bubble(void *base, int count , int size, int(*cmp )(void *, void *))
{
 int i = 0;
 int j = 0;
 for (i = 0; i< count - 1; i++)
 {
 for (j = 0; j<count-i-1; j++)
 {
 if (cmp ((char *) base + j*size , (char *)base + (j + 1)*size) > 0)
 {
 _swap(( char *)base + j*size, (char *)base + (j + 1)*size, 
size);
 }
 }
 }
}

int main()
{
 int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
 int i = 0;
 bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);
 for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++)
 {
 printf( "%d ", arr[i]);
 }
 printf("\n");
 return 0;
}

标签:return,int,void,ret,C语言,理解,printf,sizeof,指针
From: https://blog.csdn.net/do_yo/article/details/142667173

相关文章

  • 【深度学习基础模型】卷积神经网络(Convolutional Neural Networks, CNN)详细理解并附实
    【深度学习基础模型】卷积神经网络(ConvolutionalNeuralNetworks,CNN)详细理解并附实现代码。【深度学习基础模型】卷积神经网络(ConvolutionalNeuralNetworks,CNN)详细理解并附实现代码。文章目录【深度学习基础模型】卷积神经网络(ConvolutionalNeuralNetworks,......
  • C语言开发windows程序主要程序结构
    一、两个函数1.WinMain,WindowsAPI主函数。本次示例中WinMain包含的三个内容: +.注册窗口 +.创建窗口 +.消息循环2.窗口过程(WndProc) 窗口过程,通过窗口过程(WndProc)与用户交互和管理窗口。二、Windows程序示例基于C语言开发的windows图形界面程序/*** title:Windows程......
  • MySQL 的复制延迟:理解与解决方案
    MySQL的复制延迟:理解与解决方案一、什么是MySQL的复制延迟?在MySQL数据库中,复制是一种将数据从一个数据库服务器(主服务器)复制到一个或多个数据库服务器(从服务器)的机制。复制延迟指的是主服务器上的数据更改与这些更改在从服务器上反映出来之间的时间差。例如,当在主服务器上......
  • 个人感悟##C语言中的得与失
    个人练习感悟1.三个任意整数从小到大排序#include<stdio.h>#include<stdlib.h>intmain(){inta,b,c;printf(“我可以为您进行从大到小排序,请任意输入三个的整数:”);scanf(“%d%d%d”,&a,&b,&c);if(a>b&&a>c)if(b>c)printf(“%d,%d,%d”,a,b,c);elseif(b<c)......
  • C语言 typedef
    概念在C语言中,typedef是一个关键字,用于为已有的数据类型定义一个新的别名。它本身并不创建新的数据类型,而是给现有的类型赋予一个更方便、更易理解或更符合项目特定需求的名字。基本用法基本数据类型别名例如,为unsignedint定义一个新的别名uint:typedefunsignedint......
  • C语言 结构体
    结构体的概念在C语言中,结构体(struct)是一种用户自定义的数据类型,用于将不同类型的数据组合在一起,形成一个逻辑上相关的整体。它类似于一个容器,可以容纳多种不同类型的数据项。结构体的定义结构体的定义语法如下:struct结构体名{成员类型1成员名1;成员类型2成......
  • C语言 形参和实参
    在C语言中,强制类型转换(强转)可能会导致精度发生变化,具体情况取决于转换的类型。数值类型转换浮点数转换为整数当把浮点数强制转换为整数时,小数部分会被直接截断,精度必然会发生变化。例如:floatnum=3.14;intresult=(int)num;//此时result的值为3,小数部分0.14被截断......
  • c语言中的链接性和作用域
    什么是链接性链接性指的是标识符(如变量、函数)在多个翻译单元(通常是多个源文件)之间共享和可见的能力。链接性决定了标识符的作用范围,即它能在多大范围内被访问或引用链接性无链接性:标识符只能在局部作用域内使用,通常用于局部变量内部链接性:标识符只能在定义它的文件内使用,使......
  • C++中指针和数组相关的运算符优先级
    概述本文深入介绍了与指针和数组相关的运算符优先级,利用代码示例展示了当左结合和右结合运算符同时存在时的结合方式,同时也演示了如何使用()来强制人为指定结合顺序。指针、数组相关的运算符优先级下表展示了相关运算符的优先级,有4个级别,同级别内的运算符按照结合性依次调用。......
  • 实验1 C语言输入输出和简单程序编写
    1.实验任务1#include<stdio.h>intmain(){printf("oo\n");printf("<H><H>\n");printf("IIII\n");return0;} 2.实验任务2//从键盘上输入三个数据作为三角形边长,判断其能否构成三角形//构成三......