如何制作接受不同类型的功能?

Unb*_*kle 3 c sorting algorithm c99

我有这个冒泡排序功能:

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何更改它以便我也可以使用它double?我希望能够一次传递一个float数组,另一次传递一个double数组,但它必须是相同的函数.像这样的东西:

float farr[SIZE];
double darr[SIZE];
...
bouble_sort(farr, SIZE);
bouble_sort(darr, SIZE);
Run Code Online (Sandbox Code Playgroud)

编辑:我重写了排序功能,它现在似乎工作正常.你怎么看?

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;
            }
        }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Dev*_*lar 8

编辑:在编写下面的答案时,对C99的限制尚不清楚.有了这个限制,教师很可能期望一个模拟解决方案qsort(),使用"比较"功能和sizeof作为参数传递的数据类型.所以我也写了一个"C99"的答案.

这只需要几个"技巧".您将接收数组void *,处理类型的大小和比较函数作为参数.

void bubble_sort( void * array, size_t nmemb, size_t size, int (*compar)( const void *, const void * ) )
Run Code Online (Sandbox Code Playgroud)

你需要做指针算术而不是数组索引,因为你不能array转换为正确的(未知)类型.

为此,您需要unsigned char *(因为指针算法不可用void *),并添加size到那些指针以获取下一个元素.

unsigned char * array_ = (unsigned char *)array;
Run Code Online (Sandbox Code Playgroud)

您调用比较函数而不是比较自己.

// instead of...
if (array[d] > array[d + 1])
// ...you call...
if ( compar( array_[d * size], array_[(d+1) * size] > 0 ) 
Run Code Online (Sandbox Code Playgroud)

你需要memswp两个元素而不是他们的类型:

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 );
Run Code Online (Sandbox Code Playgroud)

这是C99成为要求之前的原始答案.我仍然支持所作的陈述.

不,这是不可能的,至少不是很好的风格.你可以将第一个参数作为a void *,并有一个额外的参数来"切换" floatdouble处理,但这可能是几种不好的设计.或者你可以将比较"外包"到另一个作为函数指针传递的函数,方式就是qsort()这样,但我不认为这也是一个好的设计.

但是,您可以创建一个函数bubble_sort_float()和一个函数bubble_sort_double(),然后在_Generic后面"隐藏"它们:

#define bubble_sort(X, length) _Generic((X), \
                               double: bubble_sort_double, \
                               default: bubble_sort_double,  \
                               float: bubble_sort_float  \
)(X, length)
Run Code Online (Sandbox Code Playgroud)

  • Nota Bene:`_Generic`是C11扩展名. (2认同)