我正在尝试对C中的任何类型的数组进行排序(性能不是问题,因此我使用bubble sort来简化),为此我传递sort函数它应该用来比较不同的比较函数类型(compareInt,compareDouble,compareString等等)。 我的程序适用于int,但是当我使用double / string /其他任何东西时表现得非常奇怪...... w ^
出了什么问题,我该如何解决?
我的代码:
int main(void)
{
int a[] = {2, 7, 6, 4, 1};
double b[] = {12.5, 2.7, 3.0, 5.5, 5.9, 1.0};
char c[] = {'c', 'a', 'b', 'd'};
char * d[] = {"abc", "bca", "cba", "abcd"};
char e[][4] = {"bca", "abc", "cba", "dca", "za"};
printArray(a, sizeof(a[0]), sizeof(a)/sizeof(a[0]), printInt);
printArray(b, sizeof(b[0]), sizeof(b)/sizeof(b[0]), printDouble);
printArray(c, sizeof(c[0]), sizeof(c)/sizeof(c[0]), printChar);
//printArray(d, sizeof(d[0]), sizeof(d)/sizeof(d[0]), printStringPointer);
//printArray(e, sizeof(e[0]), sizeof(e)/sizeof(e[0]), printStringArray);
printf("\n");
sort(a, sizeof(a)/sizeof(a[0]), sizeof(a[0]), compareInt);
sort(b, sizeof(b)/sizeof(b[0]), sizeof(b[0]), compareDouble);
sort(c, sizeof(c)/sizeof(c[0]), sizeof(c[0]), compareChar);
//sort(d, sizeof(d)/sizeof(d[0]), sizeof(d[0]), compareStringPointer);
//sort(e, sizeof(e)/sizeof(e[0]), sizeof(e[0]), compareStringArray);
printArray(a, sizeof(a[0]), sizeof(a)/sizeof(a[0]), printInt);
printArray(b, sizeof(b[0]), sizeof(b)/sizeof(b[0]), printDouble);
printArray(c, sizeof(c[0]), sizeof(c)/sizeof(c[0]), printChar);
//printArray(d, sizeof(d[0]), sizeof(d)/sizeof(d[0]), printStringPointer);
//printArray(e, sizeof(e[0]), sizeof(e)/sizeof(e[0]), printStringArray);
printf("\n");
getchar();
return 0;
} // pay no attention to the printArray methods, as they are just for debugging purposes.
int compareInt(void * p1, void * p2)
{
return *(int *)p1 - *(int *)p2;
}
int compareDouble(void * p1, void * p2)
{
double d = *(double *)p1 - *(double *)p2;
if(d > 0) return 1;
if(d == 0) return 0;
return -1;
}
int compareChar(void * p1, void * p2)
{
return *(char *)p1 - *(char *)p2;
}
void sort(void * arr, int arrLength, int sizeOfElement, int (*compare)(void *, void *))
{
int i, j;
for(i = 0; i < arrLength; i++) // arrlength -1?
for(j = 0; j < arrLength - 1; j++)
{
//printf("%c, %c", *((char *)arr + j * sizeOfElement), *((char *)arr + (j + 1) * sizeOfElement));
if(compare(((char *)arr + j * sizeOfElement), ((char *)arr + (j + 1) * sizeOfElement)) > 0) swap(((char *)arr + j * sizeOfElement), ((char *)arr + (j + 1) * sizeOfElement));
}
}
void swap(void ** p1, void ** p2)
{
void * p3 = *p1;
*p1 = *p2;
*p2 = p3;
}
(我也计划使用字符串,这就是数组d和e存在的原因,但我还没有为字符串编写比较函数。)
程序的输入(printArray打印的数组):
2, 7, 6, 4, 1,
12.500000, 2.700000, 3.000000, 5.500000, 5.900000, 1.000000,
c, a, b, d,
程序的输出(假设按照printArray打印后的数组):
1, 2, 4, 6, 7,
12.500000, 2.700000, 3.000000, 5.500000, 5.900000, 1.000000,
a, a, a, c,
非常感谢。
答案 0 :(得分:2)
问题是swap
功能错误。它目前假装数组中有void *
,实际上有int
或double
或其他。
可能它似乎适用于int
因为您的系统sizeof(int) == sizeof(void*)
,但不适用于其他类型,因为它们的大小不同。
要解决此问题,请将swap
更改为使用memcpy
,复制正确的字节数。当然这意味着它必须将项目长度作为参数。 (您可以将临时VLA声明为交换中的“第三轮”,或使用XOR技巧)。
NB。从if(compare(((char *)arr + j *
开始的很长的行难以阅读,我建议声明两个指针,而不是重复计算。
答案 1 :(得分:0)
正如我所看到的,由于缺少函数原型,您的代码会调用未定义的行为。在这种情况下,您可能会得到预期或意外的输出
将函数定义置于main
之上或在main
函数之上添加原型。
int compareInt(void * p1, void * p2);
int compareDouble(void * p1, void * p2);
int compareChar(void * p1, void * p2);
void sort(void * arr, int arrLength, int sizeOfElement, int (*compare)(void *, void *));
void swap(void ** p1, void ** p2);