c语言函数指针,快速排序qsort()函数

目录

1.函数指针

2.qsort()函数

2.1说明

2.2参数

2.3举例

2.3.1对char类型进行排序

2.3.2对int类型排序

2.3.3对double类型排序

2.3.4对结构体中的数据进行排序


1.函数指针

指向函数的指针称为函数指针 , 它可以指向一个参数列表相同 , 返回值相同的函数族 。
函数名本身也表示函数的地址 . 例如 Max 等同 &Max。
int Max(int a, int b)
{
  return a > b ? a : b;
}

int Min(int a, int b)
{
  return a < b ? a : b;
}

int Avg(int a, int b)
{
  return (a + b) / 2;
}

void Fun(int a, int b)
{}

int Fun1(int a)
{
  return 0;
}

int main()
{
  //pf指向一个函数族(参数列表和返回值类型都必须一样)
  int (*pf)(int, int);//pf是指针,指向参数为(int,int),返回值为int的函数.pf是指向函数的指针简称 
  函数指针
  pf = Max;
  printf("%d\n",pf(10,20));
  pf = Min;
  printf("%d\n", pf(10, 20));
  pf = Avg;
  printf("%d\n", pf(10, 20));
  //pf = Fun;//错误的
  //pf = Fun1;//错误的
  return 0;
}

2.qsort()函数

void qsort(
void *base,
size_t num,
size_t width,
int (__cdecl *compare )(const void *, const void *)
);

2.1说明

qsort:快速排序函数,需要引用stdlib.h文件。

2.2参数

  • base:需要排序的数组
  • num:数据个数(数组长度)
  • width:每个数据的字节数(sizeof(数据类型))
  • compare:比较大小的依据
在进行排序时 , 一定需要比较两个数据的大小 , 由于 qsort 能对任意的数据进行排序 , 那么它无法知道排
序的规则 , 这个需要使用的人通过参数把这个传递给 qsort, 也就是上面的 compare 参数。

2.3举例

2.3.1对char类型进行排序

注意是字符,不是字符串。

int Cmp_char(const void* vp1, const void* vp2)
{
  return *(char*)vp1 - *(char*)vp2;
}

int main()
{
  char arr[] = "aajdsfljsadzyxytp";
  qsort(arr,strlen(arr),sizeof(char),Cmp_char);
  printf("%s\n",arr);
  return 0;
}

2.3.2int类型排序

//int Cmp_int(int* p1, int* p2)//错误的,形参类型需与规定保持一致
int Cmp_int(const void *vp1,const void*vp2)
{
  return *(int*)vp1 - *(int*)vp2;//默认升序
  //return -( *(int*)vp1-*(int*)vp2);//降序
}

void Show(int* arr, int len)
{
  for (int i = 0; i < len; i++)
  {
    printf("%d ",arr[i]);
  }
  printf("\n");
}

int main() {
	int arr[] = { 1,4,8,3,24,41,2,34 };
	qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof(int),Cmp_int);
	Show(brr, sizeof(brr) / sizeof(brr[0]));
	return 0;
}

2.3.3double类型排序

int Cmp_double(const void* vp1, const void* vp2)
{
  //return *(double*)vp1 - *(double*)vp2; //12.3-12.7 == -0.4 -> 0 (这两个相等) 错误的
  double tmp = *(double*)vp1 - *(double*)vp2;
  if (tmp > 0)
    return 1;
  else if (tmp < 0)
    return -1;
  else
  return 0;
}

void Show(double* arr, int len)
{
  for (int i = 0; i < len; i++)
  {
    printf("%.2lf ",arr[i]);
  }
  printf("\n");
}

int main() {
	double brr[] = { 12.3,23.6,18.9,44.6,25.2 };
    qsort(brr, sizeof(brr) / sizeof(brr[0]), sizeof(double), Cmp_double);
	Show(brr, sizeof(brr) / sizeof(brr[0]));
	return 0;
}

因为排序规则函数int (__cdecl *compare )(const void *, const void *) 的返回类型为int,所以计算返回值时double类型不能直接相减,会发生数据的丢失。如上述代码第3行所示。

2.3.4结构体中的数据进行排序

Student类型,分别按姓名,年龄,成绩进行排序。


typedef struct Student {
	char name[20];
	int age;
	double score;
}Student;

int Cmp_name(const void* a, const void* b) {//指针类型为qsort第一个参数的类型
	return strcmp(((Student* )a)->name, ((Student*)a)->name);
}

int Cmp_age(const void* a, const void* b) {
	return ((Student*)a)->age- ((Student*)b)->age;
}

int Cmp_score(const void* a, const void* b) {
	double tmp = ((Student*)a)->score - ((Student*)b)->score;
	if (tmp > 0)
		return 1;
	else if (tmp == 0)
		return 0;
	else if (tmp < 0)
		return -1;
}

void Show(Student* arr, int len)
{
    for (int i = 0; i < len; i++)
    {
    printf("%s %d %lf\n", arr[i].name, arr[i].age, arr[i].score);
    }
}



int main() {
	Student crr[] = { "liubei",20,85.5,"caocao",19,96.5,"sunquan",21,74 };
	//按姓名排序
	qsort(crr, sizeof(crr) / sizeof(crr[0]), sizeof(crr[0]), Cmp_name);
	printf("按姓名排序:\n");
	Show(crr, sizeof(crr) / sizeof(crr[0]));

	//按年龄排序
	qsort(crr, sizeof(crr) / sizeof(crr[0]), sizeof(crr[0]), Cmp_age);
	printf("按年龄排序:\n");
	Show(crr, sizeof(crr) / sizeof(crr[0]));

	//按分数排序
	printf("按分数排序:\n");
	qsort(crr, sizeof(crr) / sizeof(crr[0]), sizeof(crr[0]), Cmp_score);
	Show(crr, sizeof(crr) / sizeof(crr[0]));

	return 0;
}

排序规则函数int (__cdecl *compare )(const void *, const void *) 传递的指针类型为qsort()函数的第一个参数的类型。

  • 13
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值