
qsort是C语言中的一个库函数(quick sort 底层使用的是快速排序的思想)。
这个函数是对数据进行排序,对任意类型的数据都能排序
int int_cmp(const void* p1, const void* p2)
{
/*if (*(int*)p1 > *(int*)p2) //void* 无法比较大小,所以需要先强制类型转换才能比较
{
return 1;
}
else if (*(int*)p1 < *(int*)p2)
{
return -1;
}
else
return 0;*/
return *(int*)p1 - *(int*)p2;//可以用这个替换,因为qsort的返回值只需要大于0,小于0,或等于0即可
}
print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[] = { 2,3,5,4,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), int_cmp);
print(arr, sz);
return 0;
}在之前的章节中我们对结构体进行了粗略的讲解,这里我们对它的进行一些补充
struct stu
{
char name[20];
int age;
};
结构体成员访问操作符
. 结构体变量.成员名
-> 结构体指针->成员名
int main()
{
struct stu s = { "zhangsan",20 };
printf("%s %d\n", s.name, s.age);
struct stu * ps=&s; // 结构体指针
printf("%s %d\n", (*ps).name, (*ps).age);
printf("%s %d\n", ps->name, ps->age);
return 0;
}使用qsort排序结构体数据
#include<stdio.h>
#include<string.h>
struct stu
{
char name[20];
int age;
};
int cmp_stu_name(const void*p1,const void*p2 )
{
strcmp(((struct stu*)p1)->name, ((struct stu*)p2)->name); //void* 无法比较大小,所以需要先强制类型转换才能比较,外面还要多加一个括号
//strcmp函数的返回值与我们所创建的cmp_stu_name函数所希望的返回值恰好是相同的,所以我们可以直接返回
} //(strcmp函数是用来比较两个字符串的函数)
void test1()
{
struct stu arr[] = { {"zhangsan",20},{"lisi",30}, {"wangwu",50} };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, szieof(arr[0]), cmp_stu_name);
}
int cmp_stu_age(const void* p1, const void* p2)
{
return ((struct stu*)p1)->age - ((struct stu*)p2)->age;
}
void test2()
{
struct stu arr[]={ {"zhangsan",20},{"lisi",60}, {"wangwu",50} };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_stu_age);
}
int main()
{
test1();
test2();
return 0;
} //我们可以通过监视(f10)来观察在上面的代码中我们用到了strcmp函数,该函数的原理:
函数首先将第一个字符串的第一个字符的ACSII值减去第二个字符串第一个字符的ACSII值(自左向右逐个字符相比,直到出现不同的字符或遇'\0'为止),若差值为零则继续比较下去;若差值不为零,则返回差值。
返 回 值:str1 = str2 则返回0, str1 > str2 则返回大于0的值, str1 < str2 则返回小于0的值
采用回调函数,采用冒泡排序的方式模拟实现qsort
#include<stdio.h>
int cmp_int(const void* p1,const void* p2)
{
return (*(int*)p1 - *(int*)p2);
}
void Swap(void* buf1, void* buf2,int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
char temp = *((char*)buf1+i);
*((char*)buf1 + i) = *((char*)buf2+i);
*((char*)buf2 + i) = temp;
}
}
//void Swap(char* buf1, char* buf2,int size)
//{
// int i = 0;
// char temp = 0;
// for (i = 0; i < size; i++)
// {
// temp = *buf1;
// *buf1 = *buf2;
// *buf2 = temp;
// }
//}
void bubble_sort(void* base, int count, int size, int(* cmp)(void*, void*))
{
int i = 0;
for (i = 0; i < count-1; i++)
{
int j = 0;
for (j = 0; j < count-1-i; j++)
{
if (cmp((char*)base+j*size, (char*)base+(j+1)*size) > 0)
{
Swap((char*)base + j * size, (char*)base + (j + 1) * size,size);
}
}
}
}
print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[] = { 2,3,1,8,5,6,7,9,0,4 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
print(arr, sz);
return 0;
}sizeof 计算变量所占内存内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。sizeof 只关注占⽤内存空间的大小不在乎内存中存放什么数据。
#inculde <stdio.h>
int main()
{
int a = 10;
printf("%d\n", sizeof(a)); //4
printf("%d\n", sizeof a); //4
printf("%d\n", sizeof(int));//4
return 0;
}strlen 是C语言库函数,功能是求字符串长度。函数原型如下:
size_t strlen ( const char * str );统计的是从 strlen 函数的参数 str 中这个地址开始向后, \0 之前字符串中字符的个数。 strlen 函数会⼀直向后找 \0 字符,直到找到为止,所以可能存在越界查找。
int main()
{
char arr1[3] = { 'a', 'b', 'c' };
//a b c
char arr2[] = "abc";
//a b c \0
printf("%d\n", strlen(arr1)); //strlen函数遇到\0才会停止,而arr1中没有\0,所以是一个随机值
printf("%d\n", strlen(arr2));//3
printf("%d\n", sizeof(arr1));//3
printf("%d\n", sizeof(arr2));//4
return 0;
}