七 指向函数指针数组的指针
指向函数指针数组的指针,是一个指针,指针指向存放函数指针的数组。
类型是:int (*(*)[5])(int, int)
1. #include <stdio.h> 2. int Add(int a, int b) 3. { 4. return a + b; 5. } 6. int Sub(int a, int b) 7. { 8. return a - b; 9. } 10. int Mul(int a, int b) 11. { 12. return a * b; 13. } 14. int Div(int a, int b) 15. { 16. return a / b; 17. } 18. int main() 19. { 20. int (*pa)(int, int) = Add;函数指针 21. int (*arr[4])(int, int) = { Add };函数指针数组,存放函数指针的数组 22. int (*(*arr)[4])(int, int) = &arr;//指向函数指针数组的指针 23. return 0; 24. }
八 回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
代码展示:
1. #include <stdio.h> 2. void menu() 3. { 4. printf("******1.Add 2.Sub*******\n"); 5. printf("******3.Mul 4.Div*******\n"); 6. printf("******0.exit *******\n"); 7. printf("**********************8****\n"); 8. } 9. int Add(int a, int b) 10. { 11. return a + b; 12. } 13. int Sub(int a, int b) 14. { 15. return a - b; 16. } 17. int Mul(int a, int b) 18. { 19. return a * b; 20. } 21. int Div(int a, int b) 22. { 23. return a / b; 24. } 25. void calc(int (*pf)(int, int)) 26. { 27. int a = 0; 28. int b = 0; 29. printf("请输入两个数字"); 30. scanf("%d %d", &a, &b); 31. int ret = pf(a, b); 32. printf("%d\n", ret); 33. } 34. int main() 35. { 36. int input = 0; 37. do 38. { 39. menu(); 40. printf("请选择:->"); 41. scanf("%d", &input); 42. switch (input) 43. { 44. case 1: 45. calc(Add); 46. break; 47. case 2: 48. calc(Sub); 49. break; 50. case 3: 51. calc(Mul); 52. break; 53. case 4: 54. calc(Div); 55. break; 56. case 0: 57. printf("退出计算机\n"); 58. break; 59. default: 60. printf("输入错误\n"); 61. break; 62. } 63. } while (input); 64. return 0; 65. }
8.1 排序
每一轮确定一个数字的位置,10个数字需要九轮才能排序完成。(冒泡排序,相邻两个两个的进行比较并交换位置)(在C语言初阶 数组知识点 里详细写了关于冒泡排序的知识点,友友们感兴趣的话可以看一下)
代码1展示:(整形冒泡排序)
1. #include <stdio.h> 2. void print(int arr[],int sz) 3. { 4. int i = 0; 5. for (i = 0; i < sz; i++) 6. { 7. printf("%d ", arr[i]); 8. } 9. } 10. void buttle_sort(int arr[], int sz) 11. { 12. int i = 0; 13. for (i = 0; i < sz - 1; i++)//确定打印趟数 14. { 15. int j = 0; 16. for (j = 0; j < sz - i - 1; j++)//确定每一趟需要比较的次数,每一趟会把最大的元素放在最后面 17. { 18. if (arr[j] > arr[j + 1]) 19. { 20. int tmp = arr[j]; 21. arr[j] = arr[j + 1]; 22. arr[j + 1] = tmp; 23. } 24. } 25. } 26. } 27. int main() 28. { 29. int arr[] = { 1, 3, 6, 2, 0, 9, 4, 8, 5, 7 }; 30. int sz = sizeof(arr) / sizeof(arr[0]); 31. buttle_sort(arr, sz); 32. print(arr, sz); 33. return 0; 34. }
qsort是一个库函数,快速排序的方法来实现的, 头文件是<stdlib.h>
qsort库函数,void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );传入的参数,一个是指针,一个整形,一个整形一个函数指针,base 数组首元素(就是数组名),num数组里有多少个元素,width每个元素的大小(单位是字节),compare比较两个指针指向的元素,小于 输出小于0的元素,等与 输出0,大于 输出大于0的元素 排序任意类型
无具体类型的指针,void*作用是 :void*的指针变量可以存放任意类型的指针,void*的指针不能直接进行解引用操作(进行解引用要进行强制转换)*(*int)pa';void*也不能进行+-整数;
代码2展示:(各种类型的排序)(qsort)
排序的内容可以是整形数组、浮点型数组、字符数组,结构体数组
把代码1用qsort表示:
使用qsort 函数,需要写一个compare函数(注意,返回类型是数字)
1. #include <stdio.h> 2. #include <stdlib.h> 3. void print(int arr[],int sz) 4. { 5. int i = 0; 6. for (i = 0; i < sz; i++) 7. { 8. printf("%d ", arr[i]); 9. } 10. } 11. //比较e1和e2指向的元素 12. int com_int(const void* e1, const void* e2) 13. { 14. return *(int*)e1 - *(int*)e2; 15. } 16. int main() 17. { 18. int arr[] = { 1, 3, 6, 2, 0, 9, 4, 8, 5, 7 }; 19. int sz = sizeof(arr) / sizeof(arr[0]); 20. qsort(arr, sz, sizeof(arr[0]), com_int); 21. print(arr, sz); 22. return 0; 23. }
比较结构体 score
1. #include <stdio.h> 2. #include <stdlib.h> 3. struct stu 4. { 5. char name[10]; 6. int age; 7. float score; 8. }; 9. 10. int cmp_stu_by_score(const void* e1, const void* e2) 11. { 12. if (((struct stu*)e1)->score > ((struct stu*)e2)->score)//浮点数不能减,因为返回的是int 13. { 14. return 1; 15. } 16. else if (((struct stu*)e1)->score < ((struct stu*)e2)->score) 17. { 18. return -1; 19. } 20. else 21. { 22. return 0; 23. } 24. } 25. 26. void print_stu(struct stu arr[], int sz) 27. { 28. int i = 0; 29. for (i = 0; i < sz; i++) 30. { 31. printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); 32. } 33. printf("\n"); 34. } 35. 36. int main() 37. { 38. struct stu arr[] = { {"zhangsan", 20, 87.5f},{"lisi", 22, 99.0f},{"wangwu", 10, 68.5f} };//按照成绩来排序 39. int sz = sizeof(arr) / sizeof(arr[0]); 40. qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_score); 41. print_stu(arr, sz); 42. return 0; 43. }
比较结构体 age
1. #include <stdio.h> 2. #include <stdlib.h> 3. struct stu 4. { 5. char name[10]; 6. int age; 7. float score; 8. }; 9. 10. int cmp_stu_by_age(const void* e1, const void* e2) 11. { 12. return ((struct stu*)e1)->age - ((struct stu*)e2)->age; 13. } 14. 15. void print_stu(struct stu arr[], int sz) 16. { 17. int i = 0; 18. for (i = 0; i < sz; i++) 19. { 20. printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); 21. } 22. printf("\n"); 23. } 24. 25. int main() 26. { 27. struct stu arr[] = { {"zhangsan", 20, 87.5f},{"lisi", 22, 99.0f},{"wangwu", 10, 68.5f} };//按照成绩来排序 28. int sz = sizeof(arr) / sizeof(arr[0]); 29. qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age); 30. print_stu(arr, sz); 31. return 0; 32. }
比较结构体 name
1. #include <stdio.h> 2. #include <stdlib.h> 3. struct stu 4. { 5. char name[10]; 6. int age; 7. float score; 8. }; 9. 10. int cmp_stu_by_name(const void* e1, const void* e2) 11. { 12. return strcmp(((struct stu*)e1)->name, ((struct stu*)e2)->name); 13. } 14. 15. void print_stu(struct stu arr[], int sz) 16. { 17. int i = 0; 18. for (i = 0; i < sz; i++) 19. { 20. printf("%s %d %f\n", arr[i].name, arr[i].age, arr[i].score); 21. } 22. printf("\n"); 23. } 24. 25. int main() 26. { 27. struct stu arr[] = { {"zhangsan", 20, 87.5f},{"lisi", 22, 99.0f},{"wangwu", 10, 68.5f} };//按照成绩来排序 28. int sz = sizeof(arr) / sizeof(arr[0]); 29. //qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_score); 30. //qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age); 31. qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name); 32. print_stu(arr, sz); 33. return 0; 34. }
strcmp(s1, s2),比较字符串的大小,两个字符串从左向右逐个字符相比(按ASCII的值大小相比),直到某一个字符不相等或者其中一个字符比较完毕才停止比较,字符的比较为ASCII码的比较(若字符串1大于字符串2,返回结果大于0,若字符串1小于字符串2,返回结果小于0,若字符串1等于字符串2,返回结果等于0.)
strcmp的头文件是<string.h>
用 冒泡排序 实现qsort()的功能
1. #include <stdio.h> 2. void print(int arr[], int sz) 3. { 4. int i = 0; 5. for (i = 0; i < sz; i++) 6. { 7. printf("%d ", arr[i]); 8. } 9. } 10. 11. void swap(char* buf1, char* buf2, int width) 12. { 13. int i = 0; 14. for (i = 0; i < width; i++) 15. { 16. char tmp = *buf1; 17. *buf1 = *buf2; 18. *buf2 = tmp; 19. buf1++; 20. buf2++; 21. } 22. } 23. 24. void bubble_sort(void* base, int sz, int width, int (*cmp)(const void* e1, const void* e2)) 25. { 26. int i = 0; 27. int j = 0; 28. for (i = 0; i < sz; i++) 29. { 30. for (j = 0; j < sz - 1 - i; j++) 31. { 32. if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) 33. { 34. swap((char*)base + j * width, (char*)base + (j + 1) * width, width);//一个字节一个字节的交换 35. } 36. } 37. } 38. } 39. 40. int com_int(const void* e1, const void* e2) 41. { 42. return *(int*)e1 - *(int*)e2; 43. } 44. int main() 45. { 46. int arr[] = { 1, 3, 6, 2, 0, 9, 4, 8, 5, 7 }; 47. int sz = sizeof(arr) / sizeof(arr[0]); 48. bubble_sort(arr, sz, sizeof(arr[0]), com_int); 49. print(arr, sz); 50. return 0; 51. }
排序的作者:不知道排序的类型
排序的使用者:知道待排序的类型,以及每种类型的排序方法。