qsort 関数 - その使用法と手動によるシミュレーション実装の分析

目次

I.はじめに

2. テキスト

 1. ヘッダファイル 

2. パラメータ

3. 戻り値

4. 簡単な実験

5. qsort 関数の実装をシミュレート -- 整数ソート関数 (バブル ソートを使用)

3. 結論


I.はじめに

以前にバブルソートを学習しましたが、操作があまり便利ではないことがわかりました。そこで、今日は任意のデータの配列       をソートできるライブラリ関数のqsort 関数を共有したいと思います。

2. テキスト

 1. ヘッダファイル 

  #include<stdlib.h>

 qsort 関数の宣言は次のとおりです。

void qsort(void * base , size_t niitems , size_t size , int (*compar)(const void *, const void*) )

2. パラメータ

void * base : ソートする配列の最初の要素のアドレス

size_t niitems : 配列要素の数

size_t size    : 単位要素のバイトサイズ

int (*compar)(const void *, const void*) : カスタム関数ポインタ。関数の行パラメータは 2 つのデータ void ポインタです。関数の戻り値は int です。これについては後で説明します。

(注: void *a などの null ポインター定義であるため、 a を逆参照することはできません。コンピューターはデータ型とデータ サイズを判断できないため、 a++ にすることもできません。 )

3. 戻り値

空の戻り値

4. 簡単な実験

1. int型カスタム関数を配置する

qsort関数は自己定義関数で判定、つまり比較メソッドを書いているため、自己定義関数はint値を返します。

     コードは以下のように表示されます。


// 自定义函数
int swap(const void* x, const void* y)
{
	//这里对数字大小升序
	return (*(int*)x - *(int*)y); // 计算机不知道x, y数据类型,因此强制转化
}

2. 配列構造型 ---- 文字列カスタム関数

typedef struct Data {
	char* name;
	int age;
	int score;
	char class;
}Da;

// 字符串
int rank_name(const void* x, const void* y) // 降序升序更改一下x,y位置即可
{
	return strcmp( ((Da*)x)->name, ((Da*)x)->name );
}

3. 配置構造型 ---- 文字カスタム機能

typedef struct Data {
	char* name;
	int age;
	int score;
	char class;
}Da;

// 整型
int rank_age(const void* x, const void* y) // 降序升序更改一下x, y位置即可
{
	return (((Da*)x)->age - ((Da*)y)->age);
}

5. qsort 関数の実装をシミュレート -- 整数ソート関数 (バブル ソートを使用)

コードは以下のように表示されます。

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int int_cmp(const void* p1, const void* p2)
{
	return (*(int*)p1 - *(int*)p2);
}

void _swap(void* p1, void* p2, int size)
{
	int i = 0;
	for (i = 0; i < size; i++)
	{   // 将数据一个一个字节的交换,保证任何数据都能替换
		char tmp = *((char*)p1 + i);  
		*((char*)p1 + i) = *((char*)p2 + i);
		*((char*)p2 + i) = tmp;
	}
}
void bubble(void* base, int count, int size, int(*cmp)(void*, void*))
{
	int i = 0;
	int j = 0;
	for (i = 0; i < count - 1; i++)
	{
		for (j = 0; j < count - i - 1; j++)
		{
			if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
			{
				_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
			}
		}
	}
}
int main()
{
	int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
	int i = 0;
	bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof(arr[0]), int_cmp);
	for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

交換機能について補足説明します。

 void _swap(void* p1, void* p2, int サイズ)
{     int i = 0;     for (i = 0; i < サイズ; i++)     {           char tmp = *((char*)p1 + i);           *((char*)p1 + i) = *((char*)p2 + i);         *((char*)p2 + i) = tmp;     } }







コード図

3. 結論

      閲覧していただきありがとうございます。ご提案がございましたら、コメント欄にコメントしてください。

おすすめ

転載: blog.csdn.net/qq_72112924/article/details/129861055