我有这个冒泡排序功能:
void bubble_sort(float* array, int length)
{
int c, d;
float temp;
for (c = 0; c < (length - 1); c++) {
for (d = 0; d < length - c - 1; d++) {
if (array[d] > array[d + 1]) {
temp = array[d];
array[d] = array[d + 1];
array[d + 1] = temp;
}
}
}
}
如何更改它以便我也可以将其用于double
?我希望能够一次传递一个float数组,另一次传递一个double数组,但它必须是相同的函数。像这样:
float farr[SIZE];
double darr[SIZE];
...
bouble_sort(farr, SIZE);
bouble_sort(darr, SIZE);
编辑:我重写了排序功能,现在似乎工作正常。你觉得怎么样?
void bubble_sort(void* generalArray, int lenght_row, char type)
{
int column_sort;
int sorting_process = 0;
if (type == 'f')
{
float temp;
float* array = (float *) generalArray;
while (sorting_process == 0)
{
sorting_process = 1;
for (column_sort = 0; column_sort < lenght_row - 1; column_sort++)
{
if (array[column_sort] > array[column_sort + 1])
{
temp = array[column_sort + 1];
array[column_sort + 1] = array[column_sort];
array[column_sort] = temp;
sorting_process = 0;
}
}
}
}
else if (type == 'd')
{
double temp; // added
double* array = (double *) generalArray;
while (sorting_process == 0)
{
sorting_process = 1;
for (column_sort = 0; column_sort < lenght_row - 1; column_sort++)
{
if (array[column_sort] > array[column_sort + 1])
{
temp = array[column_sort + 1];
array[column_sort + 1] = array[column_sort];
array[column_sort] = temp;
sorting_process = 0;
}
}
}
}
}
答案 0 :(得分:8)
编辑:在撰写以下答案时,对C99的限制并不明确。有了这个限制,教师很可能期望一个模拟qsort()
的解决方案,带有“比较”功能,并且public void addCastleToKingdom(String kingdomName,String castleName) {
Kingdom kingdom = getKingdom(kingdomName);
Castle castle = new Castle(castleName);
kingdom.addCastle(castle);
kingdomRepository.save(kingdom);
}
作为参数传递的数据类型。所以我也写了一个“C99”的答案。
这只需要几个“技巧”。您将数组作为sizeof
接收,处理类型的大小和比较函数作为参数。
void *
您需要执行指针算术而不是数组索引,因为您无法将void bubble_sort( void * array, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) )
强制转换为正确的(未知)类型。
为此,您需要array
(因为unsigned char *
上无法使用指针算术),并将void *
添加到指向下一个元素的指针。
size
您调用比较函数而不是比较自己。
unsigned char * array_ = (unsigned char *)array;
你需要// instead of...
if (array[d] > array[d + 1])
// ...you call...
if ( compar( array_[d * size], array_[(d+1) * size] > 0 )
两个元素,而不是处理他们的类型:
memswp
这是原始答案,在C99成为要求之前。我仍然坚持所作的陈述。
不,这是不可能的,至少不是很好的风格。您可以将第一个参数作为static inline void memswp( unsigned char * i, unsigned char * j, size_t size )
{
unsigned char tmp;
while ( size )
{
tmp = *i;
*i++ = *j;
*j++ = tmp;
--size;
}
}
// instead of...
temp = array[d];
array[d] = array[d + 1];
array[d + 1] = temp;
// ...you call:
memswp( array[ d * size ], array[ ( d + 1 ) * size ], size );
,并在void *
和float
处理之间有一个“切换”的附加参数,但这会有几种风格糟糕的设计。或者你可以将比较“外包”到作为函数指针传递的另一个函数,qsort()
的方式,但我不认为那是一个好的设计。
但是,您可以创建一个函数double
和一个函数bubble_sort_float()
,然后将它们“隐藏”在_Generic
macro后面:
bubble_sort_double()
答案 1 :(得分:1)
研究qsort的界面。它应该激励你。
请注意,函数的类型和签名与calling conventions和ABI相关。实际上,编译器正在生成不同的代码来为double
- s调用排序函数,为long
- s调用另一个函数。
我猜你的老师要你使用function pointers。您可能希望向它们传递一些额外的客户端数据(将这些函数指针用作callbacks),有点像非标准qsort_r(3)那样。
请注意,C遗憾地没有closures(一个与anonymous functions和free and bound variables相关的重要概念)。我建议您阅读SICP以了解它们的重要性。
或者,使用preprocessor让一些穷人metaprogramming。您可以定义一个包含数十行的巨大DEFINE_BUBBLE_SORT(Type,Name)
宏(除最后一行之外都以\
结尾),这将扩展为在数组上运行的名为Name
的冒泡排序函数的定义Type
。在SGLIB的源代码中寻找灵感。然后,您将使用DEFINE_BUBBLE_SORT(int, my_int_bubble_sort)
来定义在my_int_bubble_sort
- s上运行的例程int
,并使用DEFINE_BUBBLE_SORT(double, my_double_bubble_sort)
获取对{double}进行操作的my_double_bubble_sort
。< / p>
(你甚至可以混合两种方法:使用函数指针代码my_bubble_sort
和内部使用该函数的较短DEFINE_BUBBLE_SORT
宏)
另一种方法(与第二种方法相关)是用C编写元编程。你将编写一个程序在某个文件中生成一些C代码,该程序可能{{3} DEFINE_BUBBLE_SORT
作为程序参数的类型和函数名称。然后,您将配置take工具(例如您的build automation)以正确使用该生成器。
BTW,在操作系统及其外部编译器的帮助下,您甚至可以“动态地”执行此操作:在运行时生成一些C代码,将其编译为临时Makefile
和{{3这个插件使用eg关于POSIX的plugin;但这对初学者来说太过分了......
答案 2 :(得分:1)
无论您做什么,都必须有一个类型比较array[d] > array[d + 1]
的地方,或float
到double
的促销。因此,每种类型需要最少的自定义。对于这么小的代码,将它打包在一个函数中并不是一个好主意。传递外部比较函数会增加不必要的开销。
为了避免代码重复,我会通过使用预处理器模拟模板化函数来解决这个问题:
档案bubblesort.h
:
#define function_name(type) type##_bubble_sort
void function_name(type)(type* array, int length)
{
int c, d;
type temp;
for (c = 0; c < (length - 1); c++) {
for (d = 0; d < length - c - 1; d++) {
if (array[d] > array[d + 1]) {
temp = array[d];
array[d] = array[d + 1];
array[d + 1] = temp;
}
}
}
}
#undef function_name
#undef type
主档案:
#define type float
#include "bubblesort.h"
#define type double
#include "bubblesort.h"
这定义了函数
void float_bubble_sort(float* array, int length);
void double_bubble_sort(double* array, int length);
答案 3 :(得分:0)
正如DevSolar所说。你可以使用void指针来完成它。例如:
void bubble_sort(void* array, int length, int sizeItem)
{
int c, d;
double temp_d;
float temp_f
float* array_f;
double* array_d;
if (sizeItem == sizeof(float)){
array_f = (float*)array;
for (c = 0; c < (length - 1); c++) {
for (d = 0; d < length - c - 1; d++) {
if (array_f[d] > array_f[d + 1]) {
temp_f = array_f[d];
array_f[d] = array_f[d + 1];
array_f[d + 1] = temp_f;
}
}
}
} else if (sizeItem == sizeof(double)){
array_d = (double*)array;
for (c = 0; c < (length - 1); c++) {
for (d = 0; d < length - c - 1; d++) {
if (array_d[d] > array_d[d + 1]) {
temp_d = array_d[d];
array_d[d] = array_d[d + 1];
array_d[d + 1] = temp_d;
}
}
}
} else {
// unknown type ->your errorhandling goes here
}
}
// function call:
bubble_sort((void*)your_array, length, sizeof(your_array[0]));
答案 4 :(得分:0)
您不能将不同类型的变量传递给函数,但可以避免重写函数以进行类型更改。
#include<stdio.h>
#define bubble_sort(type) type##_bubble_sort (type* array, int length) \
{ \
int c, d; \
type temp; \
for (c = 0; c < (length - 1); c++) { \
for (d = 0; d < length - c - 1; d++) { \
if (array[d] > array[d + 1]) { \
temp = array[d]; \
array[d] = array[d + 1]; \
array[d + 1] = temp; \
} \
} \
} \
}
bubble_sort(int) //This will create function named int_bubble_sort(int* array, int length)
bubble_sort(char) //char_bubble_sort(char* array, int length)
bubble_sort(float) //float_bubble_sort(float* array, int length)
int main()
{
char array[] = {"edcba"};
char_bubble_sort(array,5);
puts(array);
return 0;
}