使用 void 指针对任何数据类型数组进行排序?
Sorting any data type array with void pointer?
我正在使用将参数作为 *void pointer、int size 和 int data_type 的函数对任何数据类型的数组进行排序(按升序排列) 。我可以借助以下函数对数组进行排序,但问题是代码重复太多。在 if 块中,在同一个函数中重复以下代码四次,这在编程中不是一个好的方法,而且在 DRY(don't repeat yourself) 中也是反对的。
int temp = 0;
//Sort the char_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (char_arr[i] > char_arr[j])
{
temp = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = temp;
}
}
}
完整代码如下
// ! sorting funtion for all data types
void sort_any_data_type(void *arr, int size, int data_type)
{
// ! data_type 1 = int,data_type 2 = float,data_type 3 = double,data_type 4 = char
if (data_type == 1)
{
int *int_arr = (int *)arr;
int temp = 0;
// sort()
//Sort the int_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (int_arr[i] > int_arr[j])
{
temp = int_arr[i];
int_arr[i] = int_arr[j];
int_arr[j] = temp;
}
}
}
}
if (data_type == 2)
{
float *float_arr = (float *)arr;
int temp = 0;
// sort()
//Sort the float_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (float_arr[i] > float_arr[j])
{
temp = float_arr[i];
float_arr[i] = float_arr[j];
float_arr[j] = temp;
}
}
}
}
if (data_type == 3)
{
double *double_arr = (double *)arr;
int temp = 0;
// sort()
//Sort the double_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (double_arr[i] > double_arr[j])
{
temp = double_arr[i];
double_arr[i] = double_arr[j];
double_arr[j] = temp;
}
}
}
}
if (data_type == 4)
{
char *char_arr = (char *)arr;
int temp = 0;
// sort()
//Sort the char_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (char_arr[i] > char_arr[j])
{
temp = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = temp;
}
}
}
}
}
我想要的是下面的样子。或者解决我的问题的等价物
花了一个星期的时间试图解决它,我做了很多研究,但不幸的是没有找到合适的解决方案。
提前谢谢你。
void sort_any_data_type(void *arr, int size, int data_type)
{
int *array = (int*)arr;
switch (data_type)
{
case 1:
array = (int *)arr;
break;
case 2:
array = (float *)arr;
break;
case 3:
array = (double *)arr;
break;
case 4:
array = (char *)arr;
default:
break;
}
int temp = 0;
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
该方法在 C 中不起作用,因为必须定义类型。 C 缺乏对类 C++ 模板的支持。有两种构建通用算法的实践方法。
- 使用
void*
- 使用宏
方法 1. 用于标准函数 qsort()
。该手册很容易获得。通常它会导致代码效率较低,尤其是对于小尺寸的类型(如 char
或 int
)。
方法二。
使用宏生成将对特定类型的数据进行排序的函数:
#define DEFINE_SORT(FNAME, TYPE) \
void FNAME(TYPE* array, int size) { \
TYPE temp = 0; \
for (int i = 0; i < size; i++) { \
for (int j = i + 1; j < size; j++) { \
if (array[i] > array[j]) { \
temp = array[i]; \
array[i] = array[j]; \
array[j] = temp; \
} \
} \
} \
}
为相关类型实例化它。
DEFINE_SORT(sort_char, char)
DEFINE_SORT(sort_int, int)
DEFINE_SORT(sort_float, float)
DEFINE_SORT(sort_double, double)
最后在 sort_any_data_type()
发送
void sort_any_data_type(void *arr, int size, int data_type) {
if (data_type == 1) sort_int(arr, size);
if (data_type == 2) sort_float(arr, size);
if (data_type == 3) sort_double(arr, size);
if (data_type == 4) sort_char(arr, size);
}
此调度程序利用 void*
和其他指针类型之间的自动转换。
然而,使用 void*
和幻数来识别类型是麻烦且容易出错的。
让我提出一个更好的 (IMO) 解决方案。
在 C11 中引入了 Generic Selection 允许按类型分派表达式
#define SORT(array, size) \
_Generic((array), \
int*: sort_int, \
float*: sort_float, \
double*: sort_double, \
char*: sort_char \
)(array, size)
_Generic
用于select一个正确的函数指针指向排序函数。
用法示例:
int main() {
int iarr[] = {3, 2, 5};
SORT(iarr, 3);
for (int i = 0; i < 3; ++i) printf("%d ", iarr[i]);
puts("");
float farr[] = {3.1, 2.2, 5.6, -12};
SORT(farr, 4);
for (int i = 0; i < 4; ++i) printf("%f ", farr[i]);
puts("");
char carr[] = "hello world";
SORT(carr, sizeof carr - 1);
puts(carr);
}
打印:
2 3 5
-12.000000 2.200000 3.100000 5.600000
dehllloorw
我正在使用将参数作为 *void pointer、int size 和 int data_type 的函数对任何数据类型的数组进行排序(按升序排列) 。我可以借助以下函数对数组进行排序,但问题是代码重复太多。在 if 块中,在同一个函数中重复以下代码四次,这在编程中不是一个好的方法,而且在 DRY(don't repeat yourself) 中也是反对的。
int temp = 0;
//Sort the char_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (char_arr[i] > char_arr[j])
{
temp = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = temp;
}
}
}
完整代码如下
// ! sorting funtion for all data types
void sort_any_data_type(void *arr, int size, int data_type)
{
// ! data_type 1 = int,data_type 2 = float,data_type 3 = double,data_type 4 = char
if (data_type == 1)
{
int *int_arr = (int *)arr;
int temp = 0;
// sort()
//Sort the int_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (int_arr[i] > int_arr[j])
{
temp = int_arr[i];
int_arr[i] = int_arr[j];
int_arr[j] = temp;
}
}
}
}
if (data_type == 2)
{
float *float_arr = (float *)arr;
int temp = 0;
// sort()
//Sort the float_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (float_arr[i] > float_arr[j])
{
temp = float_arr[i];
float_arr[i] = float_arr[j];
float_arr[j] = temp;
}
}
}
}
if (data_type == 3)
{
double *double_arr = (double *)arr;
int temp = 0;
// sort()
//Sort the double_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (double_arr[i] > double_arr[j])
{
temp = double_arr[i];
double_arr[i] = double_arr[j];
double_arr[j] = temp;
}
}
}
}
if (data_type == 4)
{
char *char_arr = (char *)arr;
int temp = 0;
// sort()
//Sort the char_array in ascending order
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (char_arr[i] > char_arr[j])
{
temp = char_arr[i];
char_arr[i] = char_arr[j];
char_arr[j] = temp;
}
}
}
}
}
我想要的是下面的样子。或者解决我的问题的等价物
花了一个星期的时间试图解决它,我做了很多研究,但不幸的是没有找到合适的解决方案。 提前谢谢你。
void sort_any_data_type(void *arr, int size, int data_type)
{
int *array = (int*)arr;
switch (data_type)
{
case 1:
array = (int *)arr;
break;
case 2:
array = (float *)arr;
break;
case 3:
array = (double *)arr;
break;
case 4:
array = (char *)arr;
default:
break;
}
int temp = 0;
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (array[i] > array[j])
{
temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
该方法在 C 中不起作用,因为必须定义类型。 C 缺乏对类 C++ 模板的支持。有两种构建通用算法的实践方法。
- 使用
void*
- 使用宏
方法 1. 用于标准函数 qsort()
。该手册很容易获得。通常它会导致代码效率较低,尤其是对于小尺寸的类型(如 char
或 int
)。
方法二。 使用宏生成将对特定类型的数据进行排序的函数:
#define DEFINE_SORT(FNAME, TYPE) \
void FNAME(TYPE* array, int size) { \
TYPE temp = 0; \
for (int i = 0; i < size; i++) { \
for (int j = i + 1; j < size; j++) { \
if (array[i] > array[j]) { \
temp = array[i]; \
array[i] = array[j]; \
array[j] = temp; \
} \
} \
} \
}
为相关类型实例化它。
DEFINE_SORT(sort_char, char)
DEFINE_SORT(sort_int, int)
DEFINE_SORT(sort_float, float)
DEFINE_SORT(sort_double, double)
最后在 sort_any_data_type()
void sort_any_data_type(void *arr, int size, int data_type) {
if (data_type == 1) sort_int(arr, size);
if (data_type == 2) sort_float(arr, size);
if (data_type == 3) sort_double(arr, size);
if (data_type == 4) sort_char(arr, size);
}
此调度程序利用 void*
和其他指针类型之间的自动转换。
然而,使用 void*
和幻数来识别类型是麻烦且容易出错的。
让我提出一个更好的 (IMO) 解决方案。
在 C11 中引入了 Generic Selection 允许按类型分派表达式
#define SORT(array, size) \
_Generic((array), \
int*: sort_int, \
float*: sort_float, \
double*: sort_double, \
char*: sort_char \
)(array, size)
_Generic
用于select一个正确的函数指针指向排序函数。
用法示例:
int main() {
int iarr[] = {3, 2, 5};
SORT(iarr, 3);
for (int i = 0; i < 3; ++i) printf("%d ", iarr[i]);
puts("");
float farr[] = {3.1, 2.2, 5.6, -12};
SORT(farr, 4);
for (int i = 0; i < 4; ++i) printf("%f ", farr[i]);
puts("");
char carr[] = "hello world";
SORT(carr, sizeof carr - 1);
puts(carr);
}
打印:
2 3 5
-12.000000 2.200000 3.100000 5.600000
dehllloorw