//////————————8.回调函数
////回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个
////函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数
////的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进
////行响应。
////qosrt函数的使用者得实现一个比较函数
////qsort是比较函数,可以排序任意类型的数据
////qsort是库函数,需要引用对应头文件#include <stdlib.h>或者#include <search.h>
//// void qsort——————————————————————————参数详解
//// void qsort(void* base,size_t num,size_t width,int(* cmp)(const void* e1,const void* e2))
//// void* base//我们要排序的数据的起始位置(arr:首元素地址)
//// size_t num//待排序的数据元素的个数
//// size_t width//待排序的数据元素的大小(占几个字节)
//// int(* cmp)(const void* e1,const void* e2)//函数指针
////
////如果我们实现一个排序算法,排序不同数据的话(结构体,整型...),其比较方式不同,
//// 因此我们把比较函数的功能(比较的模块)提取出来,放在“int(* cmp)(const void* e1,const void* e2)”的“cmp”,
//// cmp函数就是一个比较函数的地址,我们可以把一个比较函数的地址传给cmp,cmp就是一个函数指针,
//// 此时e1指向了我们要比较的第一个元素,e2指向了我们要比较的第二个元素。
//// e1和e2是我们要比较的两个元素的地址,此时cmp就会主动去调用它指向的比较函数,
//// 然后把e1,e2指向的两个元素进行比较,此时,不管我们排序什么类型的数据,我们都根据提供的比较函数进行比较并排序。
////qsort(arr,sz,sizeof(arr[0]),)
//#include <stdio.h>
//#include <stdlib.h>
//int int_cmp(const void* e1, const void* e2)//比较两个整型元素,e1.e2分别指向一个整数
//{
// //void*的指针不能直接进行解引用操作//例如e1,e2就不可以
// /*if (*(int*)e1 > *(int*)e2)
// return 1;
// else if (*(int*)e1 == *(int*)e2)
// return 0;
// else
// return -1;*/
// return (*(int*)e1 - *(int*)e2);//"/*...*/"替换为此代码更加简洁
// //强制类型转换e1,e2为int*(整型指针)//return中e1-e2为升序、e2-e1为降序
//}
//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);
// //此处我们并没有调用int_cmp函数,int_cmp函数的“实现方”是程序员,也就是“我”,
// //而调用函数的是qsort,qsort在其内部某个特定的条件下调用了int_cmp所指向的函数
// for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
// {
// printf("%d ", arr[i]);
// }
// printf("\n");
// return 0;
//}
//////————void*的指针不能直接进行解引用操作
////例如:
//#include<stdio.h>
//int main()
//{
// int a = 10;
// //char* pa = &a;//不可以,会报错"int *" 类型的值不能用于初始化 "char *" 类型的实体
// void* pv = &a;//void*是无具体类型的指针,可以接受任意类型的地址,
// //但是不能解引用操作和+或-整数的操作,因为进行解引用操作时,到底访问多少字节,
// // 需要知道确切的类型,才清楚+或-一个整数时,跳过几个字节但是void*无类型
// return 0;
//}
////为什么使用void*的指针?
////答:当我们不清楚传过来的是什么类型的地址时,我们要去接收此地址只能使用void*(包容性)
//// 使用回调函数,模拟实现qsort(采用冒泡的方式)。
////注意:这里第一次使用 void* 的指针,讲解 void* 的作用。
//////——————————————————————————结构体排序
//#include <stdio.h>
//#include <string.h>
//#include <stdlib.h>
//struct Stu
//{
// char name[5];
// int age;
//};
//int cmp_Stu_byname(const void* e1, const void* e2)//通过比较名字(字符串比较大小必须要用strcmp函数比较,不可以用+-)
//{
// return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);////strcmp返回的值有>0、==0、<0
//}// //比较方法:kk和hh比较,先是第一个相互比,k>h,所以kk大
////通过比较年龄(直接进行比较,可以用+-)
//int cmp_Stu_byage(const void* e1, const void* e2)
//{
// return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
//}
//void test1()//————名字比较
//{
// //测试使用qsort来排序结构数据
// struct Stu s[] = { {"kk",15}, {"hh",16} ,{"ss",17}};
// int sz = sizeof(s) / sizeof(s[0]);
// qsort(s, sz, sizeof(s[0]), cmp_Stu_byname);
// printf("%s\n", s);
//}
//void test2()
//{
// //测试使用qsort来排序结构数据
// struct Stu s[] = { {"kk",15}, {"hh",16} ,{"ss",17} };
// int sz = sizeof(s) / sizeof(s[0]);
// qsort(s, sz, sizeof(s[0]), cmp_Stu_byage);
// printf("%s\n", s);
//}
//int main()
//{
// test1();
// test2();
// return 0;
//}
////////————————————————————————————自创函数冒泡排序
////qsort函数内部是基于快速排序的思想来实现的
//#include <stdio.h>
//int int_cmp(char* p1, char* p2)
//{
// return (*(int*)p1 - *(int*)p2);
//}
//void Swap(char* p1, char* p2, int width)
//{
// int i = 0;
// for (i = 0; i < width; i++)
// {
// /*char tmp = *((char*)p1 + i);
// *((char*)p1 + i) = *((char*)p2 + i);
// *((char*)p2 + i) = tmp;*///等同于
// char tmp = *p1;
// *p1 = *p2;
// *p2 = tmp;
// p1++;
// p2++;
// }
//}
//void bubble(void* base, int sz, int width, int(*cmp)(char*, char*))
//{
// int i = 0;//趟数
// for (i = 0; i < sz - 1; i++)
// {
// int flag=1;//假设数组已经排好顺序
// //一趟冒泡排序的过程
// int j = 0;
// for (j = 0; j < sz - i - 1; j++)
// {
// //由于计算之前一切都是未知的,所以我们传参时的每一项都要进行同等条件下最精细的等价转换
// if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
// //此处的两个参数是待比较两个元素的地址
// //此处的强制类型转换用char*而不是int*是因为我们不清楚其真实类型,而int*+1跳过四个字节过于大,
// //所以我们采用char*,每次只调过一个字节,更为稳妥
// {
// //交换
// Swap((char*)base + j *width, (char*)base + (j + 1) * width, width);//交换时,需交代一下元素的宽度width
// //width:待排序的数据元素的大小(占几个字节)
// flag = 0;
// }
// }
// if (flag == 1)
// {
// break;
// }
// }
//}
//int main()
//{
// int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
// //char *arr[] = {"aaaa","dddd","cccc","bbbb"};
// int i = 0;
// bubble(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;
//}
////——————sizeof的计算,以及类型匹配
//#include<stdio.h>
//#include<string.h>
//int main()
//{
// char a = 10;
// const char arr[] = {1,2,3,4,5};
// printf("%d\n",strlen(&a));
// printf("%d\n", strlen(arr));
// printf("%d\n", sizeof(a));
// printf("%d\n", sizeof(arr));
// return 0;
//}
//
标签:arr,int,void,29,C语言,char,初学,sizeof,cmp From: https://blog.51cto.com/KKhahaha/8853555