c语言的qsort函数理解与使用

介绍:qsort 函数是 C 标准库中用于排序的快速排序算法函数。它的用法非常灵活,可以对任意类型的元素进行排序,只要提供了比较函数即可。

qsort 函数原型及参数解释:

void qsort (

     void* base,         //指向要排序的数组的首元素的指针

     size_t num,         //待排序数组中元素的个数

     size_t size,        //待排序数组中每个元素的大小(以字节为单位)

     int (*compare)(const void*,const void*)  //比较函数的指针,用于确定元素之间的排序

);

注意: 

使用qsort函数时,需要根据实际情况编写一个合适的比较函数来确定排序规则。

比较函数可以根据元素的类型和排序需求进行自定义。

比较函数的原型如下:

int compare(const void *a, const void *b);

比较函数需要返回一个整数值,表示两个元素之间的关系:

如果返回值小于0,则表示a应该排在b之前。

如果返回值等于0,则表示a和b相等,它们的相对顺序不变。

如果返回值大于0,则表示a应该排在b之后。

对于一个数组或是任意需要进行排序的内容进行排序时可以理解如下:

// qsort中自定义比较函数compare返回值 > 0表示对需要排序的内容进行升序排序(小->大)

// qsort中自定义比较函数compare返回值 < 0表示对需要排序的内容进行降序排序(大->小)

实例:

// qsort排序举例:升序排序(小->大)
// 自定义比较函数返回值 > 0表示对需要排序的内容进行升序排序// qsort 函数是 C 标准库中用于排序的快速排序算法函数。
// 它的用法非常灵活,可以对任意类型的元素进行排序,只要提供了比较函数即可。#include <stdio.h>
#include <stdlib.h>// 比较函数的形式为:
// int cmp(const void *a, const void *b);
// 其中,cmp 函数用于比较 a 和 b 两个指针所指向的元素的大小关系,
// 如果 a 指向的元素小于 b 指向的元素,则返回负数;
// 如果 a 指向的元素大于 b 指向的元素,则返回正数;
// 如果 a 指向的元素等于 b 指向的元素,则返回 0。
// 下面我们来看一个最简单的实例代码,用于对整数数组进行排序:
int compare(const void *a, const void *b)
{printf("%d - %d = %d,  ", *(int *)a, *(int *)b, (*(int *)a - *(int *)b));return (*(int*)a - *(int*)b);
}int main()
{int arr0[] = {2, 1};int len = sizeof(arr0) / sizeof(int);// 这段代码的核心部分就是使用 qsort 函数对整数数组进行排序,排序时需要传递一个比较函数 cmp。// cmp 函数的实现非常简单,就是计算 a 和 b 之间的差值。最后,我们依次输出排序后的整数数组。// 需要注意的是,在使用 qsort 函数时,我们需要传递以下参数:// 1. 待排序的数组的首地址。// 2. 数组中元素的个数。// 3. 每个元素的大小(以字节为单位)。// 4. 比较函数的地址(即函数指针)。// 这里我们传递的数组是 int 类型的数组,每个元素占据 4 个字节;// 比较函数 cmp 的地址可以直接传递函数名,也可以使用 & 运算符取地址。// 这就是 qsort 函数的基本用法。// 需要注意的是,cmp 函数要保证正确性和稳定性才能得到正确的排序结果,同时在实际使用时,也需要根据具体情况进行参数传递和处理。printf("arr0 升序排序过程:\n");// compare 返回值 > 0表示对数组arr1进行降序排序qsort(arr0, len, sizeof(int), compare);printf("\narr0 after sort:\n");for (int i = 0; i < len; i++) {printf("%d ", arr0[i]);}printf("\n");int arr1[] = {3, 2, 1, 5, -2, 9};int len1 = sizeof(arr1) / sizeof(int);printf("\narr1 升序排序过程:\n");// compare 返回值 > 0表示对数组arr1进行降序排序qsort(arr1, len1, sizeof(int), compare);printf("\narr1 after sort:\n");for (int i = 0; i < len1; i++) {printf("%d ", arr1[i]);}printf("\n");return 0;
}

// qsort排序举例:降序排序(大->小)
#include <stdio.h>
#include <stdlib.h>int cmp0(const void *a, const void *b)
{printf("%d - %d = %d,  ", *(int *)a, *(int *)b, (*(int *)a - *(int *)b));return -(*(int*)a - *(int*)b);
}int cmp1(const void *a, const void *b)
{printf("%d - %d = %d,  ", *(int *)b, *(int *)a, (*(int *)b - *(int*)a));return (*(int *)b - *(int*)a);
}int main()
{int arr[] = {5, 4, 2, 5, 3, 1};int len = sizeof(arr) / sizeof(int);printf("升序排序过程:\n");// cmp1返回值 < 0表示对数组arr1进行降序排序qsort(arr, len, sizeof(int), cmp0);printf("\nafter sort:\n");for (int i = 0; i < len; i++) {printf("%d ", arr[i]);}printf("\n");// cmp1返回值 < 0表示对数组arr1进行降序排序int arr1[] = {3, 2, 1, 5, -2, 9};printf("降序排序过程:\n");qsort(arr1, len, sizeof(int), cmp1);printf("\nafter sort:\n");for (int i = 0; i < len; i++) {printf("%d ", arr1[i]);}printf("\n");return 0;
}

// 对浮点数进行排序
#include <stdio.h>
#include <stdlib.h>// 对浮点数进行升序排序
int cmpFloat2Ascending(const void *a, const void *b)
{return *(float *)a - *(float *)b;
}// 对浮点数进行降序排序
int cmpFloat2Descending(const void *a, const void *b)
{return -(*(float *)a - *(float *)b);
}int main()
{float arr0[] = { -0.52, 1.7, 20.5, 9.9, 10.22 };int num0 = sizeof(arr0) / sizeof(int);printf("升序排序过程:\n");// cmp1返回值 < 0表示对数组arr1进行降序排序qsort(arr0, num0, sizeof(float), cmpFloat2Ascending);printf("\nafter sort:\n");for (int i = 0; i < num0; i++) {printf("%.2f ", arr0[i]);}printf("\n");// cmp1返回值 < 0表示对数组arr1进行降序排序float arr1[] = {3.3, 5.2, 1.1, 0.5, -1.2, 9.9};int num1 = sizeof(arr0) / sizeof(float);printf("降序排序过程:\n");qsort(arr1, num1, sizeof(float), cmpFloat2Descending);printf("\nafter sort:\n");for (int i = 0; i < num1; i++) {printf("%.2f ", arr1[i]);}printf("\n");return 0;
}

// qsort 函数对结构体类型的数据进行升序和降序排序:
// 这个程序定义了一个 Student 结构体类型,包含了学生的姓名、年龄和考试成绩三个成员变量。
// 在比较函数中,我们先比较考试成绩的大小,如果不同则返回差值;
// 如果考试成绩相同,则比较年龄的大小,如果不同则返回差值;
// 如果年龄也相同,则比较姓名的大小,从而实现了升序和降序排序。
// 在 main 函数中,我们首先定义了一个 Student 类型的数组,用于测试排序结果。
// 然后先调用 qsort 函数实现升序排序,并输出排序后的结果;
// 接着再调用 qsort 函数实现降序排序,并输出排序后的结果。
// 需要注意的是,在实际使用 qsort 函数时,需要根据具体情况进行参数传递和处理,
// 特别是在程序中使用了自定义结构体类型时,需要编写相应的比较函数来实现排序。
// 同时,也需要特别注意比较函数的实现方式,确保能够正确地比较结构体类型的各个成员变量。#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct {char name[20];int age;int score;
} Student;// 升序
int cmpAsc(const void *a, const void *b)
{Student *sa = (Student *)a;Student *sb = (Student *)b;if (sa->score != sb->score) {return sa->score - sb->score;} else if (sa->age != sb->age) {return sa->age - sb->age;} else {return strcmp(sa->name, sb->name);}
}// 降序
int cmpDesc(const void *a, const void *b)
{Student *sa = (Student *)a;Student *sb = (Student *)b;if (sa->score != sb->score) {return -(sa->score - sb->score);} else if (sa->age != sb->age) {return -(sa->age - sb->age);} else {return -strcmp(sa->name, sb->name);}
}int main()
{Student students[] = {{"Alice", 18, 80},{"Bob", 20, 70},{"Charlie", 19, 90},{"David", 18, 80},{"Ella", 20, 85}};int n = sizeof(students) / sizeof(students[0]);// 升序qsort(students, n, sizeof(Student), cmpAsc);printf("Asc:\n");for (int i = 0; i < n; i++) {printf("Name: %s\t Age: %d\t Score: %d\n", students[i].name, students[i].age, students[i].score);}printf("\n");// 降序排序qsort(students, n, sizeof(Student), cmpDesc);printf("Desc:\n");for (int i = 0; i < n; i++) {printf("Name: %s\t Age: %d\t Score: %d\n", students[i].name, students[i].age, students[i].score);}return 0;
}
// 实现一个自定义的模拟qsort函数
// 在这个程序中,我们首先定义了一个 Person 结构体类型,包含名称和年龄两个成员变量。
// 在比较函数中,我们首先比较名称的大小,如果不同则返回名称的差值;
// 如果名称相同,则比较年龄的大小,从而实现了升序和降序排序。
// 在 bubble_sort 函数中,我们使用冒泡排序的逻辑来实现元素的排序,传入的对象是 void 指针,
// 因此我们需要将其强制转换为 char 指针,然后利用 memcpy 函数以元素的大小 width 为单位进行移动。
// 每次比较都使用传入的函数指针 cmp 来比较元素的大小,如果需要交换则使用 memcpy 函数来实现交换。
// 在 main 函数中,我们首先定义了一个 Person 类型的数组,包含了五个元素。
// 我们先对数组进行升序排序打印输出,然后再进行降序排序打印输出。
// 需要注意的是,在输出时使用了结构体的成员变量 name 和 age,分别代表了名称和年龄
#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct {char name[20];int age;
} Person;int cmp_asc(const void *a, const void *b)
{Person *pa = (Person *)a;Person *pb = (Person *)b;if (strcmp(pa->name, pb->name) != 0) {return strcmp(pa->name, pb->name);} else {return pa->age - pb->age;}
}int cmp_desc(const void *a, const void *b)
{Person *pa = (Person *)a;Person *pb = (Person *)b;if (strcmp(pa->name, pb->name) != 0) {return strcmp(pb->name, pa->name);} else {return pb->age - pa->age;}
}void bubble_sort0(void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *))
{char *array = (char *)base;for (int i = 0; i < nel - 1; i++) {for (int j = i + 1; j < nel; j++) {// > 0 表示升序if (cmp(array + i * width, array + j * width) > 0) {char tmp[width];memcpy(tmp, array + j * width, width);memcpy(array + j * width, array + i * width, width);memcpy(array + i * width, tmp, width);}}}
}void bubble_sort1(void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *))
{char *array = (char *)base;for (int i = 0; i < nel - 1; i++) {for (int j = 0; j < nel - i - 1; j++) {// > 0 表示升序if (cmp(array + j * width, array + (j + 1) * width) > 0) {char tmp[width];memcpy(tmp, array + j * width, width);memcpy(array + j * width, array + (j + 1) * width, width);memcpy(array + (j + 1) * width, tmp, width);}}}
}int main()
{Person people[] = {{"Alice", 18},{"Bob", 20},{"Charlie", 19},{"David", 18},{"Ella", 20}};int n = sizeof(people) / sizeof(Person);// 升序排序bubble_sort0(people, n, sizeof(Person), cmp_asc);printf("Asc:\n");for (int i = 0; i < n; i++) {printf("Name: %s\t Age: %d\n", people[i].name, people[i].age);}printf("\n");// 降序排序bubble_sort1(people, n, sizeof(Person), cmp_desc);printf("Desc:\n");for (int i = 0; i < n; i++) {printf("Name: %s\t Age: %d\n", people[i].name, people[i].age);}return 0;
}

// 实现一个自定义的模拟qsort函数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct {char name[20];int age;
} Person;int cmp_asc(const void *a, const void *b)
{Person *pa = (Person *)a;Person *pb = (Person *)b;if (strcmp(pa->name, pb->name) != 0) {return strcmp(pa->name, pb->name);} else {return pa->age - pb->age;}
}int cmp_desc(const void *a, const void *b)
{Person *pa = (Person *)a;Person *pb = (Person *)b;if (strcmp(pa->name, pb->name) != 0) {return strcmp(pb->name, pa->name);} else {return pb->age - pa->age;}
}//交换 --一个字节一个字节的交换,共交换width次
void Swap(char* buf1, char* buf2, size_t width)
{size_t i = 0;for (i = 0; i < width; i++){char tmp = *buf1;*buf1 = *buf2;*buf2 = tmp;buf1++;buf2++;}
}
void my_BubbleSort(void* base, size_t num,size_t width, int(*cmp)(const void* e1, const void* e2))
{//冒泡排序//若要排序n个元素,只需要进行n-1趟//每一趟可以少比较一个元素,每一趟可以使一个元素在确定的位置上//num:要排序元素的个数 类型是size_t //num是无符号数 防止产生警告 所以i和j也定义为size_t// size_t == unsigned int size_t i = 0;size_t j = 0;//共进行num-1趟for (i = 0; i < num; i++){//每一趟for (j = 0; j < num - 1 - i; j++){//比较//传地址   //相邻两个元素比较   width:宽度,每个元素所占字节//排成升序if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0){//交换两数Swap( (char*)base + j * width, (char*)base + (j + 1) * width, width );}}}
}int main()
{Person people[] = {{"Alice", 18},{"Bob", 20},{"Charlie", 19},{"David", 18},{"Ella", 20}};int n = sizeof(people) / sizeof(Person);// 升序排序my_BubbleSort(people, n, sizeof(Person), cmp_asc);printf("Asc:\n");for (int i = 0; i < n; i++) {printf("Name: %s\t Age: %d\n", people[i].name, people[i].age);}printf("\n");// 降序排序my_BubbleSort(people, n, sizeof(Person), cmp_desc);printf("Desc:\n");for (int i = 0; i < n; i++) {printf("Name: %s\t Age: %d\n", people[i].name, people[i].age);}return 0;
}

使用qsort对字符串数组进行排序:

// 使用qsort函数来对字符串数组进行升序和降序排序#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_STR_NUM 10
#define MAX_STR_LEN 20int cmpAsc(const void *a, const void *b)
{char **pa = (char **)a;char **pb = (char **)b;return strcmp(*pa, *pb);
}int cmpDesc(const void *a, const void *b)
{char **pa = (char **)a;char **pb = (char **)b;return -strcmp(*pa, *pb);return strcmp(*pb, *pa);
}int main()
{int n = 3;int i = 0;char **strs = (char **)malloc(n * sizeof(char *));char *str0 = (char *)malloc(100);for (i = 0; i < 3; ++i) {strs[i] = (char *)malloc(100);}snprintf(strs[0], 100, "ff str0\n");snprintf(strs[1], 100, "dd str1\n");snprintf(strs[2], 100, "aa str2\n");// 升序排序qsort(strs, n, sizeof(char *), cmpAsc);printf("\nAsc: \n");for(int i = 0; i < n; i++) {printf("%s", strs[i]);}printf("\n");// 降序排序qsort(strs, n, sizeof(char *), cmpDesc);printf("\nDesc: \n");for(int i = 0; i < n; i++) {printf("%s", strs[i]);}printf("\n");return 0;
}
// 使用qsort函数对字符串数组进行排序#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 在实际使用时,比较函数的参数应该根据实际情况转换为正确的指针类型。
// 在字符串数组中,每个元素都是指向一个字符串的指针,
// 因此需要将`const void *`类型的指针转换为`char **`类型的指针,即指向指针的指针,然后才能解引用该指针,
// 即使用`*(char **)a`,获取指向的字符串。
// 如果使用`(char *)a`进行强制类型转换,`char *`类型的指针是单层指针,而不是指针的指针。
// 这将导致在解引用该指针时不能得到正确的字符串指针,从而产生错误的答案。
// 因此,在使用指针数组中的字符串进行排序时,
// 必须使用`char **`类型的指针进行指针转换,再解引用该指针获取到正确的字符串指针进行比较,才能保证排序的正确性。
// a和b的值是strs的元素的地址,也就是指针的指针,所以void其实是char*,void*就是char**
// strs的每个元素都是一个指针,每个元素的地址就应该用指针的指针来存储
// 所以a和b就是指针的指针,所以void*就是char**,void想当于char*
int cmp(const void *a, const void *b)
{printf("a : %p, b : %p\n", a, b);char *tmpa = (char *)a;char *tmpb = (char *)b;char **tmpaa = (char **)a;char **tmpbb = (char **)b;printf("*tmpa:  %s, **tmpaa:%s\n", tmpa, *tmpaa);printf("tmpa: %p, tmpb: %p, tmpaa: %p, tmpbb: %p\n",tmpa, tmpb, tmpaa, tmpbb);// 调试后发现:// a存放的是strs[0]的地址(char**类型)b存放的是strs[1]的地址(char**类型)        // strcmp()会将p地址对应的内容转化成字符串,也就是将strs[0~2]的地址转化成字符串,将得到一个乱码// 因为将(char **类型的数据转换成了char *类型的数据,这样解引用出来的字符串当然是错误的// 因此得先把a,b转化成char**,这样解引用以后才是一个char*的地址// return strcmp(tmpa, tmpb);// return strcmp(*tmpaa, *tmpbb);// 用指针的方式进行排序return strcmp(*(char **)a, *(char **)b);// 不能将二级指针直接解引用,这样借用用后的值为1个一级指针,而不是一个字符串,// 因此需要转换成char **类型后在进行解引用操作// return strcmp((char *)a, (char *)b);
}int main()
{int n = 3;int i = 0;char **strs = (char **)malloc(n * sizeof(char *));char *str0 = (char *)malloc(100);for (i = 0; i < 3; ++i) {strs[i] = (char *)malloc(100);}printf("strs: %p, *strs: %p, strs[0]: %p, strs[1]: %p, strs[2]: %p\n",strs, *strs, strs[0], strs[1], strs[2]);printf("strs: %p, &strs[0]: %p, &strs[1]: %p, &strs[2]: %p\n",strs, &strs[0], &strs[1], &strs[2]);snprintf(strs[0], 100, "ff str0\n");snprintf(strs[1], 100, "dd str1\n");snprintf(strs[2], 100, "aa str2\n");printf("\nbefore sort:\n");for (i = 0; i < n; ++i) {printf("%s", strs[i]);}// 传入的参数为strs[0~2],即指针的指针qsort(strs, n, sizeof(char *), cmp);printf("\nafter sort:\n");for (i = 0; i < n; ++i) {printf("%s", strs[i]);}printf("\n");for (i = 0; i < n; ++i) {free(strs[i]);}free(strs);return 0;
}

通过以上代码可以活得一个经验,在进行字符串数组比时较需要注意如下问题:

不能在自定义的数据比较函数中return strcmp((char *)a, (char *)b);

而是应该return strcmp(*(char **)a, *(char **)b);

strs是一个指针数组,保存3个指针,也就是说&strs[0], &strs[1], &strs[2]都是二级指针,

地址分别为

0x555555757260

0x555555757268

0x555555757270

这3个二级指针分别各自保存1个一级指针,分别为strs[0], strs[1], strs[2]

指针的地址和保存的字串分别为:

0x5555557572f0 "ff str0\n"

0x555555757360 "dd str1\n"

0x5555557573d0 "aa str2\n"

而传入到cmp函数中的指针为二级指针&strs[0], &strs[1], &strs[2]

(用void *类型作为形参类型,并于不同类型数据的转换),

二级指针保存一级指针的地址对应关系为:

&strs[0]: 0x555555757260 ->  strs[0]:0x5555557572f0 "ff str0\n"

&strs[1]: 0x555555757268->  strs[0]:0x555555757360 "dd str1\n"

&strs[2]: 0x555555757270->  strs[0]:0x5555557573d0 "aa str2\n"

若将传入的二级指针转换成char *类型,则接应用时去除的字符串是一个乱码,

因为二级指针保存的值为1个一级指针,所以接应用后的值仍然是一个一级指针,

而这个一级指针指向的内容才是需要获取的字符串。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/477825.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC学习笔记(6)——AI大模型开发工程师

文章目录 AI大模型开发工程师005 OpenAI大模型案例实践1 AI 翻译助手需求分析项目起源市场价格和市场前景基于大模型的翻译软件核心功能设计 2 AI 翻译助手架构设计架构设计代码结构设计 3 AI 翻译助手核心功能文档解析文档操作PDF文档操作表格操作图片操作 Prompt封装 4 AI 翻…

《生成式 AI》课程 作业6 大语言模型(LLM)的训练微调 Fine Tuning -- part1

资料来自李宏毅老师《生成式 AI》课程&#xff0c;如有侵权请通知下线 Introduction to Generative AI 2024 Spring 该文档主要介绍了国立台湾大学&#xff08;NTU&#xff09;2024 年春季 “生成式人工智能&#xff08;GenAI&#xff09;” 课程的作业 5&#xff08;GenAI HW…

cangjie (仓颉) vscode环境搭建

sdk下载 下载中心-仓颉编程语言官网 可选择半年更新版&#xff0c;不用申请。目前版本&#xff1a;0.53.13 &#xff0c;选择不同平台压缩包下载解压到任意位置即可 补充下载&#xff0c;vscode插件解压后&#xff0c;在vscode扩展中选择从vsix安装&#xff0c;安装后新增名为…

微信小程序全局配置:导航栏、下拉刷新与上拉触底设置教程

微信小程序全局配置:导航栏、下拉刷新与上拉触底设置教程 引言 微信小程序作为一种新兴的轻量级应用,凭借其便捷性和丰富的功能受到了广泛的欢迎。在开发小程序的过程中,合理配置全局属性是提升用户体验的关键。本文将深入探讨小程序的全局配置中的window选项,重点介绍导…

CPU命名那些事

一、Intel CPU命名 1. 命名结构 Intel CPU 的命名通常包含以下几个部分&#xff1a; 品牌 产品线 系列 代数 具体型号 后缀 例如&#xff1a;Intel Core i7-13700K 2. 各部分含义 品牌 Intel&#xff1a;表示厂商&#xff08;几乎所有命名中都有&#xff09;。不同品…

【C++笔记】数据结构进阶之二叉搜索树(BSTree)

【C笔记】数据结构进阶之二叉搜索树(BSTree) &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;C笔记 文章目录 【C笔记】数据结构进阶之二叉搜索树(BSTree)前言一.二叉搜索树的概念二.二叉搜索树的性能分析三.二叉搜索树的实现3.1二叉树的中序…

无线图传下的低延迟视频传输播放技术探讨

技术背景 无线图传技术即无线图像传输技术&#xff0c;是指不用布线&#xff08;线缆&#xff09;利用无线电波来传输图像数据的技术。 一、工作原理 无线图传技术主要涉及图像采集、编码、调制、发射、接收、解调、解码和图像显示等环节。 图像采集&#xff1a;通过摄像头…

Linux的开发工具(三)

条件编译 预处理本质&#xff1a;对代码进行裁剪 像网易云音乐有vip和普通用户&#xff0c;可以通过条件编译来&#xff0c;这样只用写一份代码&#xff0c;也只用维护一份代码&#xff0c;是vip就走vip代码&#xff0c;不是就普通用户代码&#xff0c;条件编译来动态裁剪。 …

VSCode 汉化教程【简洁易懂】

VSCode【下载】【安装】【汉化】【配置C环境&#xff08;超快&#xff09;】&#xff08;Windows环境&#xff09;-CSDN博客 我们安装完成后默认是英文界面。 找到插件选项卡&#xff0c;搜索“Chinese”&#xff0c;找到简体&#xff08;更具你的需要&#xff09;&#xff08;…

Ubuntu下的Doxygen+VScode实现C/C++接口文档自动生成

Ubuntu下的DoxygenVScode实现C/C接口文档自动生成 1、 Doxygen简介 Doxygen 是一个由 C 编写的、开源的、跨平台的文档生成系统。最初主要用于生成 C 库的 API 文档&#xff0c;但目前又添加了对 C、C#、Java、Python、Fortran、PHP 等语言的支持。其从源代码中提取注释&…

Linux网络——网络层

网络层的作用&#xff1a;在复杂的网络环境中确定一个合适的路径。 一.IP协议 IP存在的意义&#xff1a;IP地址提供一种能力&#xff0c;使得数据能够从主机B跨网络、可靠的送至主机A。 1.协议头格式 能够看出IP协议的格式与TCP协议存在很多相似之处&#xff0c;同样拥有4为首…

Shiro-550反序列化漏洞分析

&#x1f338; 环境配置 代码下载地址&#xff1a;https://codeload.github.com/apache/shiro/zip/refs/tags/shiro-root-1.2.4 下载完成之后&#xff0c;需要修改一下pom文件&#xff1a; 修改一下红色框中的配置。然后配置一下tomcat&#xff1a; 点击部署&#xff0c;然后…

【Rhino】【Python】Create a series of Blocks according to Value of object Property

文章目录 1. Complete Code Display2. Detailed Code Analysis2.1 Import and Setup2.2 Function Structure and Initial Setup2.3 Object Collection and Filtering2.4 Story Management System2.5 Locating Point Processing2.6 Object Organization by Story2.7 Block Creat…

CSP/信奥赛C++语法基础刷题训练(23):洛谷P1217:[USACO1.5] 回文质数 Prime Palindromes

CSP/信奥赛C语法基础刷题训练&#xff08;23&#xff09;&#xff1a;洛谷P1217&#xff1a;[USACO1.5] 回文质数 Prime Palindromes 题目描述 因为 151 151 151 既是一个质数又是一个回文数&#xff08;从左到右和从右到左是看一样的&#xff09;&#xff0c;所以 151 151 …

【探寻密码的奥秘】-001:解开密码的神秘面纱

目录 1、密码学概述1.1、概念1.2、目的1.3、应用场景 2、密码学的历史2.1、第一时期&#xff1a;古代密码时代2.2、第二时期&#xff1a;机械密码时代2.3、第三时期&#xff1a;信息密码时代2.4、第四时期&#xff1a;现代密码时代 3、密码学的基本概念3.1、一般通信系统3.2、保…

文件操作详解(1)

1.文件&#xff0c;文件与流&#xff0c;文件指针 2.文件的打开与关闭 3.文件的读写 文件的顺序读写&#xff1a; &#xff08;1&#xff09;fgetc 和 fputc &#xff08;2&#xff09;fgets 和 fputs &#xff08;3&#xff09;fscanf 和 fprintf &#xff08;4&#x…

基于YOLOv8深度学习的人体姿态摔倒检测与语音报警系统(PyQt5界面+数据集+训练代码)

随着人口老龄化进程的加速&#xff0c;摔倒事故逐渐成为威胁老年人健康和安全的主要问题之一。研究表明&#xff0c;摔倒不仅可能导致老年人骨折、头部受伤等严重的身体损伤&#xff0c;还可能引发心理恐惧和行动能力下降&#xff0c;从而降低其生活质量和独立性。如何快速、准…

jmeter5.6.3安装教程

一、官网下载 需要提前配置好jdk的环境变量 jmeter官网&#xff1a;https://jmeter.apache.org/download_jmeter.cgi 选择点击二进制的zip文件 下载成功后&#xff0c;默认解压下一步&#xff0c;更改安装路径就行(我安装在D盘) 实用jmeter的bin目录作为系统变量 然后把这…

差分进化算法原理与复现

目录 摘要1、算法原理1.1、种群初始化1.2、变异1.3、交叉1.4、选择 2、算法实现2.1、种群初始化2.2、变异2.3、交叉2.4、选择2.5、选取终代种群中最优秀个体 摘要 如何选取一组最佳的参数&#xff0c;使得代价函数值最优&#xff1f;这是优化算法做的事&#xff0c;一个直觉的…

搜索引擎中广泛使用的文档排序算法——BM25(Best Matching 25)

在搜索场景中&#xff0c;BM25能计算每个文档与查询的匹配度&#xff0c;从中找出最相关的文档&#xff0c;并按相关性高低排序展示。 要理解BM25&#xff0c;需要掌握以下几个关键概念&#xff1a; 1. 词频&#xff08;Term Frequency, TF&#xff09;&#xff1a;某关键词在文…