云计算百科
云计算领域专业知识百科平台

C语言——深度理解指针(5)

1. 回调函数是什么?

回调函数就是⼀个通过函数指针调⽤的函数。
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,被调⽤的函数就是回调函数。回调函数不是由该函数的实现⽅直接调⽤,⽽是在特定的事件或条件发⽣时由另外的⼀⽅调⽤的,⽤于对该事件或条件进⾏响应.。

下面我们用代码实现一个加法运算:

int add(int a, int b)//加法运算
{
return a + b;
}

void calc(int(*pf)(int, int))//用calc调用add函数
{
int ret = 0;
int x, y;
scanf_s("%d %d", &x, &y);
ret = pf(x, y);
printf("%d\\n", ret);
}

int main()
{
calc(add);
return 0;
}

上面代码中,我们没有直间使用add函数,而是把add的指针给了calc函数,间接的调用了add函数。这就是回调函数。

2. qsort 使⽤举例

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

首先我们先来认识一下什么是qsort函数:qsort 是 C 标准库中提供的快速排序函数,用于对数组进行排序。它能够对任意类型的数据进行排序,通过用户自定义的比较函数实现灵活的排序规则。
qsort函数的头文件stdlib
qsort函数,需要提供四个数据:

void qsort(
void *base, // 数组首元素地址
size_t nmemb, // 数组元素个数
size_t size, // 每个元素的大小(字节)
int (*compar)(const void *, const void *) // 比较函数的指针
);

用qsort函数进行升序运算
1、排序对象是int时

#include <stdio.h>
#include <stdlib.h>//qsort函数的头文件
//qosrt函数的使⽤者得实现⼀个⽐较函数
int int_cmp(const void* p1, const void* p2)
{
return (*(int*)p1 *(int*)p2);
//因为p1和p2原先定义的时候是void*,所以不可以直接解引用,因为数组中元素类型是int,所以要先强制转化成int*后在解引用
}
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;
}

const void* p1: 指向数组中第一个待比较元素的指针。
const void* p2: 指向数组中第二个待比较元素的指针。

比较函数需返回整数(也就是p1指向的值-p2指向的值):
负数:第一个参数应排在第二个参数之前。
0:两参数相等。
正数:第一个参数应排在第二个参数之后

2、排序对象是char类型时

#include <stdio.h> // 用于输入输出
#include <stdlib.h> // 用于qsort函数
// 比较函数,用于比较两个字符的大小
int compare_chars(const void* a, const void* b) {
char char_a = *(const char*)a;
char char_b = *(const char*)b;
return char_a char_b;
}
int main()
{
char arr[] = { 'd', 'a', 'c', 'b', 'e' };
int size = sizeof(arr) / sizeof(arr[0]);
qsort(arr, size, sizeof(char), compare_chars);// 使用 qsort 对字符数组进行排序
for (int i = 0; i < size; i++) // 打印排序后的字符数组
{
printf("%c ", arr[i]);
}
return 0;
}

3、排序对象是字符串类型时

#include <stdio.h> // 用于输入输出
#include <stdlib.h> // 用于qsort函数
#include <string.h> // 用于strcmp函数
int compareStrings(const void* p1, const void* p2) {
// 将void指针转换为指向字符串指针的指针
char str1[] = "* (char*)p1";
char str2[] = "* (char*)p2";
return strcmp(str1, str2);// 使用strcmp比较字符串
}
int main()
{
char* strings[] = {"banana","apple","orange","grape","pear"};// 定义一个字符串数组
int numStrings = sizeof(strings) / sizeof(strings[0]);
qsort(strings, numStrings, sizeof(char*), compareStrings);// 使用qsort对字符串数组进行排序
for (int i = 0; i < numStrings; i++)
{
printf("%s\\n", strings[i]);// 打印排序后的结果
}
return 0;
}

注意字符串比较要用:strcmp函数

4、排序对象是浮点型类型时

#include <stdio.h>
#include <stdlib.h>
int compare_floats(const void *a, const void *b) // 浮点数比较函数
{
float fa = *(const float*)a;
float fb = *(const float*)b;
// 处理浮点数精度问题
if (fa < fb)
{
return 1;
}
if (fa > fb)
{
return 1;
}
return 0;
}
int main() {
float numbers[] = {3.14f, 1.59f, 2.65f, 3.58f, 9.79f, 3.23f};
int size = sizeof(numbers) / sizeof(numbers[0]);
// 使用qsort排序
qsort(numbers, size, sizeof(float), compare_floats);
// 打印排序结果
for (int i = 0; i < size; i++)
{
printf("%.2f ", numbers[i]);
}
return 0;
}

2.2 使⽤qsort排序结构数据

排序对象是结构体函数

#include <stdio.h> // 用于输入输出
#include <stdlib.h> // 用于qsort函数
#include <string.h> // 用于strcmp函数
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;
}

补充:结构体成员访问操作符 -> (通过指针间接访问结构体变量的成员)

struct Stu //定义一个嵌套函数
{
char name[20];//名字
int age;//年龄
};
int main()
{
struct Stu s = { "zhangsan", 20 };
struct Stu* x = &s;
printf("%d\\n", x->age);
return 0;
}

在这里插入图片描述

. 操作符用于直接访问结构体变量的成员

struct Stu //定义一个嵌套函数
{
char name[20];//名字
int age;//年龄
};
int main()
{
struct Stu s[]= {"zhangsan", 20};
printf("%d\\n", s.age);
return 0;
}

在这里插入图片描述

赞(0)
未经允许不得转载:网硕互联帮助中心 » C语言——深度理解指针(5)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!