「2」指针进阶——详解

简介: 🐰指向函数指针数组的指针(很少用,了解)🐰回调函数(通过函数指针调用函数)🐰快速排序🌸冒泡排序🌸qsort()🐰用冒泡排序类似实现qsort

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰指向函数指针数组的指针(很少用,了解)

🐰回调函数(通过函数指针调用函数)

🐰快速排序

🌸冒泡排序

🌸qsort()

🐰用冒泡排序类似实现qsort


🐰指向函数指针数组的指针(很少用,了解)

1. #include<stdio.h>
2. void Add(int ,int)
3. {
4.     printf("%d\n",1+1);
5. }
6. void Sub(int ,int)
7. {
8.     printf("%d\n",1-1);
9. }
10. int main()
11. {
12.     int (*pf)(int,int)=Add;//函数指针
13.     int (*pfArr[4])(int,int)={Add,Sub};//函数指针数组
14.     int (*(*ppfArr)[4])(int,int)=&pfArr;//ppfArr就是指向函数的指针数组的指针
15.     return 0;
16. }

🐰回调函数(通过函数指针调用函数)

通过回调函数实现 两个操作数的加减乘除:

1. #include<stdio.h>
2. void Calc(int(*pf)(int,int))
3. {
4.     int x=0,y=0;
5.     printf("请输入两个操作数\n");
6.     scanf("%d %d",&x,&y);
7.     int ret=pf(x,y);
8.     printf("%d\n",ret);
9. }
10. int Add(int x,int y)
11. {
12.     return x+y;
13. }
14. int Sub(int x,int y)
15. {
16.     return x-y;
17. }
18. int Mul(int x,int y)
19. {
20.     return x*y;
21. }
22. int Div(int x,int y)
23. {
24.     return x/y;
25. }
26. void menu(void)
27. {
28.     printf("****    两位数的计算器     ****\n");
29.     printf("****    1.Add   2.Sub   ****\n");
30.     printf("****    3.Mul   4.Div   ****\n");
31.     printf("****    0.exit          ****\n");
32. }
33. int main()
34. {
35. 
36.     int input=0;
37.     do
38.     {
39.         menu();
40.         printf("请选择\n");
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("exit\n");
58.                 break;
59.             default:
60.                 printf("输入错误\n");
61.         }
62.     }while(input);
63. }

🐰快速排序

qsort是一个库函数,是用来排序(使用的快速排序的方法)

1.库函数里的,可以直接使用        2.可以排序任意类型的数据

🌸冒泡排序

B6E11D17-7AE8-43CD-A2E9-7420DB60AA8B.gif

1.  #include<stdio.h>
2. 
3. void Bubble(int arr[],int len)
4. {
5.     int i=0,j=0;
6.     for(i=0;i<len-1;i++)
7.     {
8.         for(j=0;j<len-1-i;j++)
9.         {
10.             if(arr[i]>arr[j+1])
11.             {
12.                 int temp=arr[j];
13.                 arr[j]=arr[j+1];
14.                 arr[j+1]=temp;
15.             }
16.         }
17.     }
18. }
19. void Print(int arr[],int len)
20. {
21.     for(int i=0;i<len;i++)
22.     {
23.         printf("%d ",arr[i]);
24.     }
25.     printf("\n");
26. }
27. int main()
28. {
29.     int arr[]={3,2,1,5,7,8,9,0};
30.     int len=sizeof(arr)/sizeof(arr[0]);
31.     Bubble(arr,len);
32.     Print(arr,len);
33. }

🌸qsort()

qsort的原型:void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));

1. void qsort (void* base//指向了待排序数组的第一个元素的地址
2.             , size_t num(无符号整形)//待排序的元素个数
3.             , size_t size(无符号整形)//每个元素的大小,单位是字节
4.             ,int (*compar)(const void*,const void*)//这里是一个函数指针,指向一个函数,这个函数可以比较2个元素的大小
5.             );

比较函数:就是函数指针campar指向的函数,因为使用qsort时,要自己定义比较函数,以下是常见的比较函数

1. 比较整形变量时
2. int cmp_int(const void* e1, const void* e2)
3. {
4. return *(int*)e1 - *(int*)e2;
5. }
1. 比较浮点型变量时
2. int cmp_float(const void* e1, const void* e2)
3. {
4. return (int)(*(float*)e1 - *(float*)e2);
5. }
1. 比较字符串变量时
2. int cmp_str_size(const void* e1, const void* e2)
3. {
4. return strcmp((char*)e1,(char*)e2);
5. }
1. 比较字符串长度时
2. int cmp_str_len(const void* e1, const void* e2)
3. {
4. return strlen((char*)e1)-strlen((char*)e2);
5. }
1. 比较结构体变量时
2. int cmp_by_age(const void*e1, const void*e2)
3. {
4. return (int)((stu*)e1)->weight - ((stu*)e2)->weight));
5. }

cmp函数的返回值:返回值<0(不进行置换),>0(进行置换),0(不进行置换)。记得返回的结果一定是整形的,如果不是需要强制转为整形的

‼️注:void*的指针不能解引用,也不能算术运算

下面是使用qsort排序整形变量和结构体变量的原码:

1. #include<stdio.h>
2. #include<stdlib.h>
3. #include<string.h>
4. int cmp_int(const void* e1,const void* e2)//对整形比较
5. {
6.     return *(int*)e1-*(int*)e2;
7. }
8. 
9. void test_1()
10. {
11.     int arr[]={2,3,4,5,6,7,1};
12.     int sz=sizeof(arr)/sizeof(arr[0]);//计算出数组下标,就不用手动去数有多少个元素了
13.     //这里需要提供一个比较函数,这个比较函数能够比较2个整数的大小
14.     //qsort默认为升序
15.     qsort(arr,sz,sizeof(arr[0]),cmp_int);
16.     for(int i=0;i<sz;i++)
17.     {
18.         printf("%d ",arr[i]);
19.     }
20. }
21. struct stu//定义了一个包含字符类型,整形,浮点型的结构体
22. {
23.     char name[20];
24.     int age;
25.     float weight;
26. };
27. int sort_by_name(const void* e1,const void* e2)//对字符串的比较
28. {
29.     return strcmp(((struct stu*)e1)->name,((struct stu*)e2)->name);
30. }
31. 
32. int sort_by_age(const void* e1,const void* e2)//对整形的比较
33. {
34.     return ((struct stu*)e1)->age-((struct stu*)e2)->age;
35. }
36. 
37. int sort_by_weight(const void* e1,const void* e2)//对浮点型比较
38. {
39.     return ((struct stu*)e1)->weight-((struct stu*)e2)->weight;
40. }
41. void test_2()//对结构体进行排序
42. {
43.     struct stu s[3]={{"zhangsan",23,65.5},{"lisi",27,56.5},{"wangwu",24,64}};
44.     int sz=sizeof(s)/sizeof(s[0]);
45.     qsort(s, sz, sizeof(s[0]), sort_by_name);//对名字排序
46.     for(int i=0;i<sz;i++)//输出排序后的结果
47.     {
48.         printf("%s ",s[i].name);
49.     }
50.     printf("\n");
51.     qsort(s, sz, sizeof(s[0]), sort_by_age);//对年龄排序
52.     for(int i=0;i<sz;i++)
53.     {
54.         printf("%d ",s[i].age);
55.     }
56.     printf("\n");
57.     qsort(s, sz, sizeof(s[0]), sort_by_weight);//对体重排序
58.     for(int i=0;i<sz;i++)
59.     {
60.         printf("%.2f ",s[i].weight);
61.     }
62.     printf("\n");
63. }
64. int main()
65. {
66.     test_1();
67.     test_2();
68.     return 0;
69. }

🐰用冒泡排序类似实现qsort

qsort()的底层是快速排序,但是没有学过快速排序,可以使用冒泡排序来代替

1. #include<stdio.h>
2. void swap(char* buf1,char*buf2,int width)
3. //为什么不直接进行交换,而是交换每个字节的内容?这是因为这交换的不只是整形变量,这里还可以交换其它类型的变量
4. 
5. {
6.     for(int i=0;i<width;i++)
7.     {
8.         char temp=*buf1;
9.         *buf1=*buf2;
10.         *buf2=temp;
11.         buf1++;
12.         buf2++;
13.     }
14. }
15. void buble_sort(void* base,int sz,int width,int (*cmp)(const void*e1,const void*e2))//这里的函数指针可以方便调用各种类型比较,不同类型的变量比较,可以调用不同类型的比较函数
16. {
17.     int i=0,j=0;
18.     //sz个元素就有sz-1趟
19.     for(i=0;i<sz-1;i++)
20.     {
21.         for(j=0;j<sz-1-i;i++)
22.         {
23.             //两个元素的比较
24.             //arr[j] arr[j+1]
25.             if(cmp((char*)base+j*width,(char*)base+(j+1)*width)>0)//为什么将base强制转化为(char*)呢?假如比较的是整形变量,我们将base转化为(char*),加上width(就是这里的整形变量的大小,4字节)就可以找到下个元素的地址,
26.             {
27.                 //交换
28.                 swap((char*)base+j*width,(char*)base+(j+1)*width,width);//然后把这个变量的地址传给交换函数
29.             }
30.         }
31.     }
32. }
33. int cmp_int(const void* e1,const void* e2)//对整形比较
34. {
35.     return *(int*)e1-*(int*)e2;
36. }
37. int main()
38. {
39.     int arr[10]={2,3,4,5,6,7,1,9,13,10};
40.         int sz=sizeof(arr)/sizeof(arr[0]);
41.         buble_sort(arr,sz,sizeof(arr[0]),cmp_int);
42.         for(int i=0;i<sz;i++)
43.         {
44.             printf("%d ",arr[i]);
45.         }
46.     return 0;
47. }

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸



相关文章
|
3月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
3月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
3月前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
3月前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
3月前
|
编译器 C语言
指针进阶(数组指针 )(C语言)
指针进阶(数组指针 )(C语言)
|
3月前
|
搜索推荐
指针进阶(2)
指针进阶(2)
39 4
|
3月前
指针进阶(3)
指针进阶(3)
32 1
|
3月前
|
C++
指针进阶(1)
指针进阶(1)
35 1
|
3月前
|
存储 安全 编译器
C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字
C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字
33 2
|
3月前
|
Java 程序员 Linux
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
探索C语言宝库:从基础到进阶的干货知识(类型变量+条件循环+函数模块+指针+内存+文件)
36 0