用途:你可以逐个复制,自己敲代码练习,依次是:qsort排序int、qsort结构体按年龄、qsort结构体按名字、函数指针计算器
一、题型清单
- 基础:使用qsort排序int整型数组(回调cmp函数)
- 进阶1:使用qsort排序结构体数组,按age年龄升序
- 进阶2:使用qsort排序结构体数组,按name名字字典序排序(strcmp)
- 函数指针基础:最简单的函数指针变量演示
- 综合1:函数指针做函数参数,简易计算器(calc接收函数指针)
- 综合2:函数指针数组实现计算器(转移表,这个是考试高频大题)
二、语法知识点
- qsort库函数(用来自己比较大小,不同再自己写tmp了)
头文件: #include <stdlib.h>
函数原型:
void qsort(void* base, size_t num, size_t size, int (compar)(const void,const void*));
- base:数组起始地址
- num:元素个数
- size:单个元素字节大小
- compar:回调函数指针,由我们自己写比较规则
cmp函数规则:
返回负数 → p1排在p2前面;返回正数 → p2排前面;0代表相等
- void*通用指针
- void*只保存内存地址,不能直接解引用 *p
- 使用前强制转换成对应类型指针: (struct Stu*)p1
- 再解引用取值: (struct Stu)p1
- 结构体访问
((struct Stu)p1).age
等价于 ((struct Stu*)p1)->age
括号优先级:强制转换先做,再 . 访问成员
- 字符串比较 strcmp
头文件 #include <string.h>
strcmp(s1,s2) :按字典序比较字符串
s1<s2 返回负数;s1>s2返回正数;相等返回0
✅ 正好直接return给qsort
- 函数指针语法
int (*pf)(int,int);
- (*pf) :pf是指针; int ( , ) :指向的函数,参数两个int,返回int
- 函数名本身就是函数地址, pf = Add 和 pf = &Add 完全一样
- 调用: (*pf)(10,20) 等价 pf(10,20)
- 函数指针数组(转移表,重点!)
int (*pfArr[])(int,int) = {NULL,Add,Sub,Mul,Div};
数组里面每一个元素,都是一个 int(*)(int,int) 类型的函数指针。
三、完整可敲代码(分5段,一段一段写)
代码1:qsort排序int数组
c
#include <stdio.h>
#include <stdlib.h>
void print_arr(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf(“%d “, arr[i]);
}
printf(”\n”);
}
//比较函数,升序
int cmp_int(const void* p1, const void* p2)
{
return (int)p1 - (int)p2;
}
//降序写法 return (int)p2 - (ingxvt)p1;
void test1()
{
int arr[] = { 3,1,8,6,0,9,4,2,7,5 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
print_arr(arr, sz);
}
int main()
{
test1();
return 0;
}
代码2:qsort 结构体按age排序
c
#include <stdio.h>
#include <stdlib.h>
struct Stu
{
char name[20];
int age;
};
int cmp_stu_by_age(const void* p1, const void* p2)
{
return ((struct Stu)p1).age - ((struct Stu)p2).age;
}
void test3()
{
struct Stu arr[] = { {“zhangsan”, 18}, {“lisi”, 25}, {“wangwu”,12} };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);
}
int main()
{
test3();
return 0;
}
代码3:qsort 结构体按name名字排序(strcmp)
c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Stu
{
char name[20];
int age;
};
int cmp_stu_by_name(const void* p1, const void* p2)
{
return strcmp( ((struct Stu)p1).name , ((struct Stu)p2).name );
}
void test4()
{
struct Stu arr[] = { {“zhangsan”, 18}, {“lisi”, 25}, {“wangwu”,12} };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);
}
int main()
{
test4();
return 0;
}
代码4:函数指针基础 + 计算器版本1(函数指针做参数)
c
#include <stdio.h>
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”);
}
//pf是函数指针,接收运算函数地址
void calc(int (*pf)(int, int))
{
int x = 0, y = 0;
printf(“请输入两个操作数:”);
scanf(“%d %d”, &x, &y);
int r = pf(x, y);
printf(“结果=%d\n”, r);
}
int main()
{
int input = 0;
do
{
menu();
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;
}
代码5:函数指针数组计算器(转移表,重点大题)
c
#include <stdio.h>
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 (*pfArr[])(int, int) = { NULL, Add, Sub, Mul, Div };
int input = 0;
do
{
menu();
printf(“请选择:>”);
scanf(“%d”, &input);
if (input >= 1 && input <= 4)
{
int x = 0, y = 0;
printf(“请输入两个操作数:”);
scanf(“%d %d”, &x, &y);
int r = pfArr[input](x, y);
printf(“结果=%d\n”, r);
}
else if (input == 0)
{
printf(“退出计算器\n”);
}
else
{
printf(“选择错误\n”);
}
} while (input);
return 0;
}
额外小代码:最简函数指针演示
c
#include <stdio.h>
int Add(int x, int y)
{
return x + y;
}
int main()
{
int (*pf)(int, int) = Add;
int r = (*pf)(10, 20);
printf(“%d\n”, r);
return 0;
}
2611



被折叠的 条评论
为什么被折叠?



