指针(5)(qsort函数讲解)

文章目录

  • assert断言
  • 练习指针——qsort函数的使用与实现
    • qsort函数的介绍
    • qsort函数的使用
    • qsort函数的模拟实现

assert断言

使用这个函数时,要引用头文件assert.h

assert(表达式);
这里表达式为真的话,这行代码就不会产生任何作用,表达式为假就会使程序出错

在我们使用指针时,如果一个指针时空指针(NULL),我们如果使用了这个指针,我们有时候比较难以察觉这种错误

#include

int main()
{
	char* s1=NULL;
	assert(s1);
	return 0;
}


像这样,就可以判断指针是否使空指针
指针(5)(qsort函数讲解)_第1张图片

产生上图的结果。

来看一下这个代码在实践中的应用。

#include
char* my_strcpy(char* s1, char* s2)
{
	assert(s1 && s2);
	char* ret = s1;

	while (*s2)
	{
		*ret = *s2;
		ret++;
		s2++;
	}
	return s1;
}

如上述strcpy函数模拟实现代码,在使用指针时,先对两个指针进行assert断言,这样会使我们的代码出错时更加容易处理。

assert 的缺点是引入额外检查,增加了程序运行时间,一般在 debug 中使用,release 版本中就直接优化掉了

练习指针——qsort函数的使用与实现

qsort函数的介绍

qsort函数时C语言自带的排序函数,包含在stdlib.h头文件中。

qsort(voidbase ———base指向要排序的数组的第一个元素
size_t num———base指向数组中元素个数(待排序的元素个数)
size_t size———base指向的数组元素大小(以字节为单位)
int (compar)(const voidp1,const void
p2)————函数指针——比较数组中的两个元素)


> int cmp_int(const void* p1, const void* p2)
{
	return *(int*)p2 - *(int*)p1;//降序
}

返回类型应该是一个整型,所以使用返回类型int的函数
因为要比较各种数组(字符数组,整形数组,结构体数组)
所以传入的参数要使用void*类型,在相减时,再根据需要
进行强制类型转换。
排序分为升序和降序
return *(int*)p1 - *(int*)p2;//升序
return *(int*)p2 - *(int*)p1;//降序

qsort函数的使用

下面看一下使用qsort函数进行数组降序的排序

#include
#include

int cmp_int(const void* p1, const void* p2)
{
	return *(int*)p2 - *(int*)p1;//降序
}

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	qsort(arr, sz, sizeof(arr[0]), cmp_int);
	for (int i = 0;i < 10;i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

来看看结构体排序

int cmp_str_age(const void*ptr1,const void*ptr2)
{
	return ((struct stu*)ptr1)->age - ((struct stu*)ptr2)->age;//年龄升序
}

int cmp_str_name(const void* ptr1, const void* ptr2)
{
	return strcmp(((struct stu*)ptr1)->name ,((struct stu*)ptr2)->name);
	//名字排序,使用strcmp函数
}

int main()
{
	struct stu arr1[3] = { {"zhangsan",20},{"lisi",10},{"wangwu",30} };
	int sz1 = sizeof(arr1) / sizeof(arr1[0]);
	qsort(arr1, sz1, sizeof(arr1[0]),cmp_str_age);
	printf("%d \n", arr1[0].age);
	qsort(arr1, sz1, sizeof(arr1[0]), cmp_str_name);

	printf("%s", arr1[0].name);
	return 0;
}

指针(5)(qsort函数讲解)_第2张图片
这就是程序结果。

qsort函数的模拟实现

在qsort函数的模拟实现的时候,我们暂且先用冒泡排序的方法及逆行排序。
但其实qsort函数的内部排序方法比冒泡排序要更快,时间复杂度低。

来看代码

int cmp_int(const void* p1, const void* p2)
{

	return *(int*)p1 - *(int*)p2;
}


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


int cmp_stu(void* ptr1,  void* ptr2)
{
	return strcmp(((struct stu*)ptr1)->name, ((struct stu*)ptr2)->name);
}


void swap( char* p1,  char* p2, int width)
{
	for (int i = 0;i < width; i++)
	{
		char temp = *(p1 + i);
		*(p1 + i) = *(p2 + i);
		*(p2 + i) = temp;
	}
}


void sort_qsort(void* base, size_t sz, size_t width, int(*cmp)(const void* p1, const void* p2))
{
	for (int i = 0;i < sz - 1;i++)
	{
		for (int j = 0;j < sz - i - 1;j++)
		{
			//swap函数进行交换
			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()
{
	int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
	int sz = sizeof(arr)/sizeof(arr[0]);
	sort_qsort(arr, sz, sizeof(arr[0]), cmp_int);

	struct stu arr1[3] = { {"zhangsan",20},{"lisi",10},{"wangwu",30} };
	int sz1 = sizeof(arr1) / sizeof(arr1[0]);
	sort_qsort(arr1, sz1, sizeof(arr1[0]), cmp_stu);
	for (int i = 0;i < sz;i++)
	{
		printf("%d ", arr[i]);
	}
	for (int i = 0;i < 3;i++)
	{
		printf("%s ", arr1[i].name);
	}
	return 0;
}

你可能感兴趣的:(c语言)