突破•指针五

qsort函数🫧

qsort是什么

qsort 函数是 C 语言标准库中提供的一个用于数组排序的函数。使用qsort函数需要包含头文件stdlib.h
它的声明是void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const void*));,即void qsort (排序起点的地址, 数组元素个数, 每个元素的大小, 比较函数);

qsort如何用

把元素放到数组中进行排序。
总共的元素个数要用sizeof操作符计算后再传入,这样的代码比较灵活。
比较函数要根据所比较的元素类型,自己写。
比较函数的模板:

int 比较函数的名字(const void* e1, const void* e2)
{
	//强制转换为原来的数据类型再比较
if(解引用(原数据类型*)e1)<(解引用(原数据类型*)e2) return -1;
if(解引用(原数据类型*)e1)==(解引用(原数据类型*)e2) return 0;
if(解引用(原数据类型*)e1)>(解引用(原数据类型*)e2) return 1;
}

例如,如果所要比较的元素是结构体:

#include <stdio.h>
#include<stdlib.h>//qsort的头文件
#include<string.h>//strcmp的头文件

struct Stu
{
	char name[20];
	int age;
};

//打印函数
void Print(struct Stu arr[],int i)
{
	for (i = 0; i < 3; i++)
		printf("%s %d ", arr[i].name, arr[i].age);
	printf("\n");
}

//按名字比较
int com_by_name(const void* e1, const void* e2)
{
	//比较字符串用库函数strcmp
	return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name); 
}

//按年龄比较(从小到大)
int com_by_age1(const void* e1, const void* e2)
{
	return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}

//按年龄比较(从大到小)
int com_by_age2(const void* e1, const void* e2)
{
	return ((struct Stu*)e2)->age - ((struct Stu*)e1)->age;
}

int main()
{
	int i = 0;
	struct Stu arr[] = { {"zhangsan",19},{"lisi",17},{"wangwu",20}};
	int sz = sizeof(arr) / sizeof(arr[0]);
	printf("原序:");
	Print(arr,sz);

	//按名字比较
	qsort(arr, sz, sizeof(arr[0]), com_by_name);
	printf("按名字排序(abc顺序):");
	Print(arr, sz);

	//按年龄比较(从小到大)
	qsort(arr, sz, sizeof(arr[0]), com_by_age1);
	printf("按年龄排序(从小到大):");
	Print(arr, sz);

	//按年龄比较(从大到小)
	qsort(arr, sz, sizeof(arr[0]), com_by_age2);
	printf("按年龄排序(从大到小):");
	Print(arr, sz);
	return 0;
}

解引用的方法

结构体类型的解引用:

  1. 直接解引用是结构体变量.成员名,如 arr[i].name(上述代码的打印函数Print中)
  2. 间接解引用是结构体指针->成员名,如((struct Stu*)e1)->age(上述代码的比较函数中)

其它类型的解引用是*指针,如*( int *)p1,这里p1先被强制类型转换为整型指针类型,然后再解引用。

strcmp函数

要包含头文件string.h,它的声明是int strcmp ( const char * str1, const char * str2 );,它和qsort函数中要自己写的那个比较函数的返回类型都是int型,具体表现为str1 < str2返回一个负数(一般用-1),str1 == str2返回0,str1 > str2返回一个正数(一般用1)。
在这里插入图片描述
在这里插入图片描述

字符串的比较不是按长短,而是按字母顺序,就像微信列表中联系人的排序一样。

使用方法例如strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name); (上述代码中按名字比较的比较函数),就是把要比较的两个字符串扔进去,看打印出来的字母顺序是不是想要的,不是就把扔进去的字符串掉个位置,即strcmp(((struct Stu*)e2)->name, ((struct Stu*)e1)->name);

强制类型转换的模板是(转化后的类型)变量名

注意return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;等价于

if((struct Stu*)e1)->age < ((struct Stu*)e2)->age return -1;
if((struct Stu*)e1)->age == ((struct Stu*)e2)->age return 0;
if((struct Stu*)e1)->age > ((struct Stu*)e2)->age return 1;

运行截图:
在这里插入图片描述

sizeof和strlen的对比🫧

sizeof操作符

sizeof计算变量所占内存内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。sizeof只关注占用内存空间的大小,不在乎内存中存放什么数据。

#inculde <stdio.h>
int main()
{
int a = 10;
printf("%d\n", sizeof(a));
printf("%d\n", sizeof a);//sizeof是操作符的证明:函数的括号不可省略
printf("%d\n", sizeof(int));
return 0;
}

运行截图:
在这里插入图片描述

strlen函数

strlen是C语言库函数,要包含头文件string.h,功能是求字符串长度,从strlen函数的参数str 中这个地址开始向后,\0 之前字符串中字符的个数【直到找到\0为止,所以可能存在越界查找】。关注内存中是否有\0

#inculde <stdio.h>
#include <string.h>
int main()
{
	char arr[] = "abcdef";
	char arr1[] = { 'a', 'b', 'c' };
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr1));
	return 0;
}

字符数组arr1中没有\0strlen找不到它的公主👸,它伤心流泪地横冲直撞,最后,啊哦,就越界访问了哈哈哈哈哈哈。这里的18就是越界了,不同平台的运行结果可能不同。
运行截图:
在这里插入图片描述

能量站😚

你终会明白,前途比爱情重要,你还会明白,爱情比前途更难得,但最后你会明白,对的人会站在你的前途里。
请添加图片描述

❤️❤️❤️ 恭喜! 恭喜! 闯关成功! ❤️❤️❤️

  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值