我在C中编写了一个通用插入排序,它工作得非常好。
但是,在我的插入排序功能上,它得到void** arr
,
并且在它的签名上得到void* arr
,否则,它不起作用。
为什么会这样? 我们是否有其他方法可以将插入排序编码为通用?
完整代码在这里:
#include <stdio.h>
#include <malloc.h>
#define SIZE 10
int cmp(void* elm1, void* elm2);
void insertionSort(void* arr, int size);
int main()
{
int arr[] = {5, 8, 2, 3, 15, 7, 4, 9, 20, 13};
int arr2[] = {1};
int i;
for (i = 0; i < SIZE; i++)
printf("%d ", arr[i]);
printf("\n");
insertionSort(&arr, SIZE);
for (i = 0; i < SIZE; i++)
printf("%d ", arr[i]);
return 0;
}
void insertionSort(void** arr, int size)
{
int i = 1;
int j;
void* temp;
while (i < size)
{
if (cmp(arr[i], arr[i-1]) == -1)
{
temp = arr[i];
j = i - 1;
while (j >= 0 && cmp(arr[j], temp) == 1)
{
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = temp;
}
i++;
}
}
int cmp(void* elm1, void* elm2)
{
if ((int)elm1 == (int)elm2)
return 0;
else if ((int)elm1 > (int)elm2)
return 1;
else
return -1;
}
答案 0 :(得分:1)
由于存在多个问题,因此未定义代码。它恰好起作用,因为在你的系统上,指针的大小与类型(deftest async-test
(testing "Testing some core.async functionality."
(async done
(go
(is (= (<! (go "val")) "val1"))
(done)))))
的大小相同。
您的代码不会在没有警告的情况下编译(如果您启用它们)。 insertSort函数和它的原型必须具有相同的类型。
您应该将函数定义中的类型更改为
int
然后将指针arr转换为适当的类型。由于这是一个通用的排序,如qsort(),唯一现实的选择是转换为void insertionSort(void* arr, int size)
。这意味着您还必须将类型的大小传递给函数,因此指针可以正确递增。这将要求您彻底改变功能。
因此,函数原型应该与qsort完全相同:
char*
答案 1 :(得分:0)
问题是integers
不是指针,因此您的测试数组的类型为*int
或int[]
。但是在你的函数中,你不知道这一点,并且你试图让你的代码使用指针。所以你期待* void[]
。如果您将temp
变量更改为int
,则签名中不需要**
。同样,如果你想保持“通用”(当你调用时),你需要一个*int
的数组。
基本上,在C语言中,你不能为主要类型和指针编写一个开箱即用的函数。你需要一些技巧。看看this stackoverflow,也许会有所帮助。