回调函数
//回调函数就是通过函数指针调用的函数 //这个在之前的转移表-计算器里面很明显,通过函数指针数组内的函数指针进行函数的调用 // // // 将这四段代码分装成一个函数,一个代码将这4个问题都解决 int Add(int x, int y) { return x + y; } int Sub(int x, int y) { return x - y; } int Mull(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.mull 4.div***********\n"); printf("********* 0.exit *************\n"); printf("**************************************\n"); } void Calc(int (*pf)(int, int))//因为传过来的是函数的地址,那么就要用函数指针进行接收 { int x = 0, y = 0,ret=0; printf("请输入两个操作数"); scanf("%d %d", &x, &y); ret = pf(x, y);//当pf接收到的是加法函数的地址的时候,我们直接用pf来调用 //对于函数名就是函数的地址,用指针变量存起来的就是函数地址,那么指针变量的名字就是函数变量的地址 //那么可以直接用指针变量的名字进行调用 printf("%d\n", ret); } int main() { int ret = 0; int input = 0; int x = 0, y = 0; do { menu();//菜单 printf("请选择:"); scanf("%d", &input); switch (input) { case 1: Calc(Add); //将加法函数的地址传过去--函数名是地址 break; case 2: Calc(Sub); break; case 3: Calc(Mull); break; case 4: Calc(Div); break; case 0: printf("退出计算器\n"); break; default: printf("选择错误,重新选择\n"); break; } } while (input); return 0; } //这4个代码的差异就是运算的方式不同 // // Calc是中间商,Add这些计算的函数是回调函数 // // 通过函数调用另一个函数进行调用 // //当你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其 //所指向的函数时,被调用的函数就是回调函数 //这个代码里面回调函数就是Add,Sub,Mull,Div
回忆冒泡函数
//回忆冒泡排序---对一组整数进行排序 //void bubble_sort(int arr[], int sz)//接受一个整型数组 //{ // //趟数 // for (int i = 0; i < sz-1; i++) // { // //一趟内部的两两比较 // for (int j = 0; j < sz - 1 - i; j++) // { // if (arr[j] > arr[j + 1]) // { // int tmp = arr[j]; // arr[j] = arr[j + 1]; // arr[j + 1] = tmp; // } // } // } //} //print(int arr[], int sz) //{ // for (int i = 0; i < sz; i++) // { // printf("%d ", arr[i]); // } //} //int main() //{ // int arr[] = { 3,1,7,9,4,2,6,8,0 }; // //进行排序--升序 // int sz = sizeof(arr) / sizeof(arr[0]); // // //冒泡排序核心思想,两两数字进行比较,不满足我们要求的顺序的话我们可以对其进行交换 // //满足我们要求的顺序的话我们就换下一对数字进行比较 // // //冒泡排序进行排序 // bubble_sort(arr,sz); // print(arr,sz); // return 0; //} //对于冒泡排序的话,只能排序整型数组 //对于其他类型的数组无法排序 //字符串数组、字符数组、结构体数组、浮点数数组
strcmp----字符串的大小比较
/字符串的比较 //应该使用strcmp进行比较 //int strcmp(const char* str1, const char* str2); //char str1[]="Hello"; //char str2[]="hello"; //strcmp(str1, str2)); // 如果 strcmp 返回值大于 0, // 则表示第一个字符串(str1)在比较中大于第二个字符串(str2)。 //
a,b,c,d,c,e,f
a,b,c,q
因为d的ASCII小于q的,所以第一行的字符串就小于第二行的字符串
strcmp比较的不是长度,比较的是对应位置的字符ASCII大小的
qsort的结构
而接下来介绍的qsort能适用于任意类型的数据的排序 void qsort(void* base,//指向待排序数组第一个元素的指针 size_t num, //base指向的数组中的元素个数 size_t size, //base指向的数组中每个元素的大小 int(*com)(const void*, const void*)//函数指针--传递函数的地址 // );
利用qsprt进行整型数组的排序
//对于冒泡排序比较不同的类型的数据时,两个循环没有什么差异,但是对于不同的数据进行比较就有着差异 //对于整数是进行比较大小,但是并不是所有的数据能能用比'>''<'进行比较 //既然不同数据的元素比较是有差异的,那么就直接把两个元素比较的代码抽离出来 //谁要调用qsort来进行比较排序,那就让谁提供比较的函数 //下面的函数比较的是p1指向的元素和p2指向的元素 //对函数 //p1指向的元素比p2指向的元素小的时候,返回的是小于0的数 //p1指向的元素等于p2指向的元素的时候,返回的是0 //p1指向的元素比p2指向的元素打的时候,返回的是大于0的数 //咱么为了使用qsort函数,我们必须提供一个比较2个整型的比较函数 //格式int cmp_int(const void*p1, const void*p2),那么这个函数的名字就是qsort函数的第四个条件 //int cmp_int(const void*p1, const void*p2) //{ // //p1就指向了这个数组里面的3,p2指向的就是1 // /*if(*p1>*p2)*///不能这么写,因为在函数的参数里面,p1的类型是void*,p2是void* // //void *指针不能进行解引用操作 // //将p1的类型强制转换成int*,再进行解引用就行了 *(int*)p1 // //比较的三种情况 // if (*(int*)p1 > *(int*)p2) // { // return 1; // } // else if (*(int*)p1 < *(int*)p2) // { // return -1; // } // else // { // return 0; // } // //} //void print(int arr[], int sz) //{ // for (int i = 0; i < sz; i++) // { // printf("%d ", arr[i]); // } //} test这个函数测试qsort来排序整型数据 //void test1() //{ // int arr[] = { 3,1,7,9,4,2,6,8,0 }; // int sz = sizeof(arr) / sizeof(arr[0]); // qsort(arr, sz, sizeof(arr[0]), cmp_int); // //(数组首元素地址,数组长度,每个元素字节大小,进行比较大小的函数) // print(arr, sz);//打印排序完后的数组 //} //int main() //{ // test1(); // return 0; //} //提供想要排序的数组,计算数组元素个数 //再利用qsort进行排序 //再利用qsort进行排序的时候,要提供数组首元素的地址、数组长度、数组每个元素的字节大小、 //最后再提供一个比较的函数的函数名,这个函数有固定的写法 //int cmp_int(const void*p1, const void*p2) //因为p1和p2的类型都是void*,不能对其进行解引用进行比较, //所以我们必须将其强制类型转换,(int*)p1 //再对其进行解引用*(int*)p1 //再将*(int*)p1与*(int*)p2进行比较 //前者大于后者就返回大于0的数 //前者小于后者就返回小于0的数 //前者等于后者就返回0 //对于qsort函数来说,我们只需要额外构建一个比较函数就能利用qsort进行快速排列
对于qsort函数来说,我们只需要额外构建一个比较函数就能利用qsort进行快速排列
//对下面代码进行简化 // test1 int cmp_int(const void* p1, const void* p2) { return *(int*)p1 - *(int*)p2; } //因为这里比较的是整数,那么我们直接作差返回 void print(int arr[], int sz) { for (int i = 0; i < sz; i++) { printf("%d ", arr[i]); } } //test这个函数测试qsort来排序整型数据 void test1() { int arr[] = { 3,1,7,9,4,2,6,8,0 }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_int); //(数组首元素地址,数组长度,每个元素字节大小,进行比较大小的函数) print(arr, sz);//打印排序完后的数组 } int main() { test1(); return 0; }
利用qsprt进行结构体的排序
/*void qsort(void* base,//指向待排序数组第一个元素的指针 size_t num, //base指向的数组中的元素个数 size_t size, //base指向的数组中每个元素的大小 int(*com)(const void*, const void*)//函数指针--传递函数的地址 // );*/ //利用qsort函数对结构体进行排序 struct Stu//创建一个结构体 { char name[20]; int age; }; //按照名字比较两个结构体的数据 int cmp_stu_by_name(const void* p1, const void* p2)//p1和p2分别指向数组中的结构体 { //先将p1强制类型转换 //(struct Stu*)p1---结构体指针-----不能直接指向成员 错误写法:(struct Stu*)p1-> //要先括起来,将强制类型转换后的结构阔起来,才能找到成员 //((struct Stu*)p1)->name, ((struct Stu*)p2)->name // //两个名字是字符串,字符串比较是采用strcmp函数的 return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name); //因为strcmp函数的返回值和我们期望的qsort的第四个比较函数的返回值一样的, //所以我们直接将strcmp的值返回 //strcmp要包含头文件的include <string.h> } void print(struct Stu arr[], int sz) { for (int i = 0; i < sz; i++) { printf("%s ", arr[i].name); } } void test2() { struct Stu arr[] = { {"zhangsan",20},{"lisi",35},{"wangwu",18}};//给了三个人的信息 //利用qsort对数组内的信息进行排序 int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);//传递的函数是进行比较两个结构体对象 //但是我们现在是按照名字比较还是年龄比较呢? print(arr, sz); } int main() { test2(); return 0; }
//按照年龄排序 struct Stu//创建一个结构体 { char name[20]; int age; }; void print(struct Stu arr[], int sz) { for (int i = 0; i < sz; i++) { printf("%d ", arr[i].age); } }//打印结果:18 20 35 void cmp_stu_by_age(const void* p1, const void* p2) { //return strcmp(((struct Stu*)p1)->age, ((struct Stu*)p2)->age); //因为age是两个整数,所以不需要用strcmp了 return ((struct Stu*)p1)->age-((struct Stu*)p2)->age; //将他们的值进行大小比较,直接返回 //前者大于后者直接返回大于0的数 //前者小于后者直接返回小于0的数 //前者等于后者直接返回0 } void test3() { struct Stu arr[] = { {"zhangsan",20},{"lisi",35},{"wangwu",18} }; int sz = sizeof(arr) / sizeof(arr[0]); qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age); print(arr, sz); } int main() { test3(); return 0; }
C语言---深入指针(4)(二)https://developer.aliyun.com/article/1544403