听说这是目录哦
- qsort函数🫧
- qsort是什么
- qsort如何用
- 解引用的方法
- strcmp函数
- sizeof和strlen的对比🫧
- sizeof操作符
- strlen函数
- 能量站😚
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)
{//比较字符串用库函数strcmpreturn 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;
}
解引用的方法
结构体类型的解引用:
- 直接解引用是
结构体变量.成员名
,如arr[i].name
(上述代码的打印函数Print中) - 间接解引用是
结构体指针->成员名
,如((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
中没有\0
,strlen
找不到它的公主👸,它伤心流泪地横冲直撞,最后,啊哦,就越界访问了哈哈哈哈哈哈。这里的18就是越界了,不同平台的运行结果可能不同。
运行截图:
能量站😚
你终会明白,前途比爱情重要,你还会明白,爱情比前途更难得,但最后你会明白,对的人会站在你的前途里。
❤️❤️❤️ 恭喜! 恭喜! 闯关成功! ❤️❤️❤️