c - 如何制作接受不同类型的函数?

标签 c algorithm sorting 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;
            }
        }
    }
}

如何更改它以便我也可以将它用于 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;
            }
        }
    }
  }
}

最佳答案

编辑:在撰写以下答案时,对 C99 的限制尚不明确。有了这个限制,教师很可能期望一个模仿 qsort() 的解决方案。 ,具有“比较”功能和 sizeof对于作为参数传递的数据类型。所以我也写了一个“C99”答案。

这只需要几个“技巧”。您收到的数组为 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两个元素而不是处理它们的类型:

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 );

这是在要求 C99 之前的原始答案。我仍然支持所做的声明。

不,这是不可能的,至少不是很好的风格。您可以将第一个参数作为 void * ,并有一个附加参数在 float 之间“切换”和 double处理,但那将是几种糟糕的设计。或者你可以将比较“外包”给作为函数指针传递的另一个函数,方式 qsort() 做到了,但我认为这也不是一个好的设计。

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

#define bubble_sort(X, length) _Generic((X), \
                               double: bubble_sort_double, \
                               default: bubble_sort_double,  \
                               float: bubble_sort_float  \
)(X, length)

关于c - 如何制作接受不同类型的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47031697/

相关文章:

string - 是否可以在 O(n) 中计算字符串中不同子串的数量?

python - 为什么我的 python 代码这么慢(leetcode)?

python - 在python中将一维列表转换为具有给定行长度的二维列表

actionscript-3 - 自定义排序算法的速度问题

c - 对这个函数背后的数学有点困惑

c - 如何在 Netbeans IDE 中用 C 编程语言触发 EOF(文件结束符)

c - 如何让 GCC __attribute__ ((constructor)) 在 OSX 下工作?

c - 函数中的 malloc — 段错误

bash - 如何在 bash 中使用不可打印的字符作为排序命令的字段分隔符?

c++ - 对指针列表进行排序