您需要做的是使用泛型生成C++模板函数的C等效版本。这通常是将函数指针和重新转换`void*`数据相结合以实现所需结果。`qsort()`函数就是这样做的。下面包括一个代码清单和示例运行
来自我之前某个答案的类似内容,展示了如何使用简单的冒泡排序实现多种数据类型。
要将其扩展到任何数据类型,您只需要:
- 创建自己的
int compareDataType(void* a, void* b)
函数
- 更新传递给
BubbleSort()
函数的sizeOfElement
和compareFcn
参数。
您的方法可能适用于已定义比较操作的原始数据类型,但不适用于抽象数据类型,例如`struct`等。
代码清单
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define ELEMENT_AT(arr, i, w) (((char*)arr) + ((i)*(w)))
#define BUF_SIZE (20)
typedef struct cricket_s {
char pname[BUF_SIZE];
char tname[BUF_SIZE];
int avg;
} cricket_t;
void* bubbleSort(void* arr, int (*compareFcn)(void*, void*), size_t sizeOfElement, size_t numElements);
void rand_str(char *dest, size_t length);
int compareCricketAvg(void *a, void *b);
int compareCricketPname(void *a, void *b);
void* bubbleSort(void* arr, int (*compareFcn)(void*, void*), size_t sizeOfElement, size_t numElements) {
if (!arr || !compareFcn || !numElements || !sizeOfElement) {
return NULL;
}
int i, j;
void* tempBuf;
if ((tempBuf = calloc(1, sizeOfElement)) == NULL) {
return NULL;
}
for (i=0; i<(numElements-1); i++) {
for (j=0; j<(numElements - i -1); j++) {
if (compareFcn(ELEMENT_AT(arr, j, sizeOfElement), ELEMENT_AT(arr, j+1, sizeOfElement)) == (-1)) {
memcpy(tempBuf, ELEMENT_AT(arr, j, sizeOfElement), sizeOfElement);
memcpy(ELEMENT_AT(arr, j, sizeOfElement), ELEMENT_AT(arr, j+1, sizeOfElement), sizeOfElement);
memcpy(ELEMENT_AT(arr, j+1, sizeOfElement), tempBuf, sizeOfElement);
}
}
}
free(tempBuf);
return arr;
}
int compareCricketAvg(void *a, void *b) {
if (!a || !b) {
return 0;
}
int ret;
if (((cricket_t*)a)->avg < ((cricket_t*)b)->avg) {
ret = (-1);
} else if (((cricket_t*)a)->avg > ((cricket_t*)b)->avg) {
ret = 1;
} else
ret = 0;
return ret;
}
int compareCricketPname(void *a, void *b) {
if (!a || !b) {
return 0;
}
int ret;
char *s1, *s2;
s1 = ((cricket_t*)a)->pname;
s2 = ((cricket_t*)b)->pname;
ret = strncmp(s1, s2, BUF_SIZE);
if (ret > 0) {
ret = 1;
} else if (ret < 0) {
ret = (-1);
} else {
ret = 0;
}
return ret;
}
void rand_str(char *dest, size_t length) {
char charset[] = "0123456789"
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
while (length-- > 0) {
size_t index = (double) rand() / RAND_MAX * (sizeof charset - 1);
*dest++ = charset[index];
}
*dest = '\0';
}
int main(void) {
srand(time(NULL));
int numPlayers = 10;
int i;
cricket_t* team;
if ((team = calloc(numPlayers, sizeof(cricket_t))) == NULL) {
printf("Memory error\n");
return (-1);
}
for (i=0; i<numPlayers; i++) {
team[i].avg = rand() % 1000;
rand_str(team[i].pname, BUF_SIZE);
printf("Team %d - Pname:%s - Average:%d\n", i, team[i].pname, team[i].avg);
}
printf("\n");
bubbleSort((void*)team, compareCricketAvg, sizeof(cricket_t), numPlayers);
for (i=0; i<numPlayers; i++) {
printf("Team %d - Pname:%s - Average:%d\n", i, team[i].pname, team[i].avg);
}
printf("\n");
bubbleSort((void*)team, compareCricketPname, sizeof(cricket_t), numPlayers);
for (i=0; i<numPlayers; i++) {
printf("Team %d - Pname:%s - Average:%d\n", i, team[i].pname, team[i].avg);
}
printf("\n");
free(team);
return 0;
}
样例运行
Team 0 - Pname:YY7plBOnjIi7YQTKjgqB - Average:605
Team 1 - Pname:sKGbl8pIAjHzq6U2UimD - Average:439
Team 2 - Pname:tBrmmKDNmvf6crrlQaWa - Average:226
Team 3 - Pname:vBXqESI0vju7KRuvvhS1 - Average:117
Team 4 - Pname:YdYqzPBv0s0Bqqgi9hNs - Average:209
Team 5 - Pname:VdDpJ8GB9dAnb0W1Bs14 - Average:633
Team 6 - Pname:DuUTM3bAvXvJAVsJB3TP - Average:212
Team 7 - Pname:h1Fd2hF3l8GQ2AD6LdBI - Average:237
Team 8 - Pname:kjEN3gRX5ve6ar8r7cMg - Average:467
Team 9 - Pname:Djtgpet1XdmhSal81iew - Average:473
Team 0 - Pname:VdDpJ8GB9dAnb0W1Bs14 - Average:633
Team 1 - Pname:YY7plBOnjIi7YQTKjgqB - Average:605
Team 2 - Pname:Djtgpet1XdmhSal81iew - Average:473
Team 3 - Pname:kjEN3gRX5ve6ar8r7cMg - Average:467
Team 4 - Pname:sKGbl8pIAjHzq6U2UimD - Average:439
Team 5 - Pname:h1Fd2hF3l8GQ2AD6LdBI - Average:237
Team 6 - Pname:tBrmmKDNmvf6crrlQaWa - Average:226
Team 7 - Pname:DuUTM3bAvXvJAVsJB3TP - Average:212
Team 8 - Pname:YdYqzPBv0s0Bqqgi9hNs - Average:209
Team 9 - Pname:vBXqESI0vju7KRuvvhS1 - Average:117
Team 0 - Pname:vBXqESI0vju7KRuvvhS1 - Average:117
Team 1 - Pname:tBrmmKDNmvf6crrlQaWa - Average:226
Team 2 - Pname:sKGbl8pIAjHzq6U2UimD - Average:439
Team 3 - Pname:kjEN3gRX5ve6ar8r7cMg - Average:467
Team 4 - Pname:h1Fd2hF3l8GQ2AD6LdBI - Average:237
Team 5 - Pname:YdYqzPBv0s0Bqqgi9hNs - Average:209
Team 6 - Pname:YY7plBOnjIi7YQTKjgqB - Average:605
Team 7 - Pname:VdDpJ8GB9dAnb0W1Bs14 - Average:633
Team 8 - Pname:DuUTM3bAvXvJAVsJB3TP - Average:212
Team 9 - Pname:Djtgpet1XdmhSal81iew - Average:473
qsort()
? - Iharob Al Asimiqsort()
并使用回调函数。 - Iharob Al Asimi