如果只用C实现如模版的功能,怎么做?

boluor1987 2009-05-18 11:40:10
考虑一个问题,比如说,给一个函数,对一个数组进行排序,但是这个数组,可能是int型的,double型的,也可能是float型的,如果有可能,可以考虑下字符串型的。
我初步想的解决的方法是用 void *,但是具体怎么写有点纠结。
help me,thank you!
...全文
420 50 打赏 收藏 转发到动态 举报
写回复
用AI写文章
50 条回复
切换为时间正序
请发表友善的回复…
发表回复
boluor1987 2009-05-20
  • 打赏
  • 举报
回复
呵呵,哪敢?只是觉得有些人花了很多的时间帮我解决问题,理应多给点.
boluor1987 2009-05-20
  • 打赏
  • 举报
回复
总结贴,欢迎大家留言。http://www.boluor.com/?p=81
boluor1987 2009-05-19
  • 打赏
  • 举报
回复
用宏写了一个,大家看看,如果不好的地方请指正! thank you!

#include <stdio.h>

#ifndef _INT_
#define _INT_
#endif

int cmp(const void *a,const void *b){
#ifdef _INT_
return (*(int *)a-*(int *)b);
#elif _FLOAT_
return (fabs(*(float *)a-*(float *)b)<1e-6)?-1:1;
#elif _DOUBLE_
return (fabs(*(double *a)-*(double *)b)<1e-9)?-1:1;
#endif
}

#ifdef _INT_
void FindMin(int *arr,int arr_size,int *result,int cmp(const void *a,const void *b))
#elif _FLOAT_
void FindMin(float *arr,int arr_size,float *result,int cmp(const void *a,const void *b))
#elif _DOUBLE_
void FindMin(double *arr,int arr_size,double *result,int cmp(const void *a,const void *b))
#endif
{
int i;
*result=arr[0];
for(i=1;i<arr_size;++i){
if(cmp(&arr[i],result)>0)
*result=arr[i];
}
}

int main(){
int arr1[]={1,2,4,2,1,7};
int result;
FindMin(arr1,6,&result,cmp);
printf("%d\n",result);
return 0;
}
hityct1 2009-05-19
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 ltc_mouse 的回复:]
库函数中的qsort 如何?
http://msdn.microsoft.com/en-us/library/aa272872(VS.60).aspx
[/Quote]
up
光宇广贞 2009-05-19
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 boluor1987 的回复:]
引用 11 楼 hikaliv 的回复:
是否能正常工作咱先不管,单单如下一句:

result=(int *)arr;

你不得不指定显示转换的类型,那么你的想法不就全被破坏了么?……呵呵……

再考虑一下吧。


因为在这里result保存的是最小值的地址,比如说arr数组中第三项最小,那么result应为&arr[2]. 至于用(int *)arr,这句也可以改为(char *)arr,或者(double *)arr,因为这只是指针的地址.在32位机器上,指针所占字节都是4个字节,所…
[/Quote]

没错,但是你不得不在程序里面显示指定,静态指定死了,而不能在程序运行中让程序来自动判断,那么你用VOID*有什么用?
Sou2012 2009-05-19
  • 打赏
  • 举报
回复
MARK!!
lzh9955 2009-05-19
  • 打赏
  • 举报
回复
可能会有很多不确定性的存在!
wen_eric 2009-05-19
  • 打赏
  • 举报
回复
重载函数,和模板函数
ltc_mouse 2009-05-19
  • 打赏
  • 举报
回复
在FindMin中不应该出现具体的数据类型! void *之间的赋值,可以考虑memcpy呀。我们知道了数据长度了,memcpy就行了~
9楼代码中,这条语句是错的:(int *)arr+i*arrmembersize,把arr看成int型指针,再偏移i*arrmembersize?? 很可能导致越界...

void FindMin(void *arr,int arr_size,int arrmembersize,void * result, //result保存最小值的地址.
int (*fpCmp)(const void *,const void *b)){
int i;
unsigned char *pSrc = (unsigned char *)arr;
unsigned char *pRes = (unsigned char *)result;
memcpy( (void *)pRes, (const void *)pSrc, arrmembersize );
for (i=1;i<arr_size;i++){
pSrc += arrmembersize;
if ( fpCmp((const void *)pSrc, result)<0 ){
memcpy( (void *)pRes, (const void *)pSrc, arrmembersize );
}
}
}
boluor1987 2009-05-19
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 hikaliv 的回复:]
是否能正常工作咱先不管,单单如下一句:

result=(int *)arr;

你不得不指定显示转换的类型,那么你的想法不就全被破坏了么?……呵呵……

再考虑一下吧。
[/Quote]

因为在这里result保存的是最小值的地址,比如说arr数组中第三项最小,那么result应为&arr[2]. 至于用(int *)arr,这句也可以改为(char *)arr,或者(double *)arr,因为这只是指针的地址.在32位机器上,指针所占字节都是4个字节,所以用哪个来强制类型转换都可以的.
因此我就不懂我那个程序为什么不工作了...
chenzhp 2009-05-19
  • 打赏
  • 举报
回复
除了用宏来控制,还有什么好办法
光宇广贞 2009-05-19
  • 打赏
  • 举报
回复
按回复的优劣分楼给分。

很有评卷的味道。

我喜欢,哈哈……
lingyin55 2009-05-19
  • 打赏
  • 举报
回复
呵呵,c里面没有函数重载的概念。

[Quote=引用 12 楼 amossavez 的回复:]
引用 10 楼 Loaden 的回复:
要模拟模板,只能用宏
你写的代码貌似也没实现模版的功能呀!!函数重载应该行吧!!
[/Quote]
lingyin55 2009-05-19
  • 打赏
  • 举报
回复
呵呵,c里面没有函数重载的概念。

[Quote=引用 12 楼 amossavez 的回复:]
引用 10 楼 Loaden 的回复:
要模拟模板,只能用宏
你写的代码貌似也没实现模版的功能呀!!函数重载应该行吧!!
[/Quote]
lingyin55 2009-05-19
  • 打赏
  • 举报
回复
使用void * 这种方法行不通,想了下,还是只有通过宏模拟比较好。
编译时期就得确定参数类型了。

[Quote=引用 9 楼 boluor1987 的回复:]
写了一个,但是不知道为什么得不到想要的结果?大家帮忙看看。

C/C++ code
#include "stdio.h"

int cmp(const void *a,const void *b){
int *c=(int *)a;
int *d=(int *)b;
if (*c-*d<0){
return -1;
}
else{
return 1;
}
}

void FindMin(void *arr,int arr_size,int arrmembersize,void * result, //result保存最小值的地址.
int (*cmp)(const voi…
[/Quote]
amossavez 2009-05-19
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 Loaden 的回复:]
要模拟模板,只能用宏
[/Quote]你写的代码貌似也没实现模版的功能呀!!函数重载应该行吧!!
boluor1987 2009-05-19
  • 打赏
  • 举报
回复
[Quote=引用 43 楼 ltc_mouse 的回复:]
引用 41 楼 boluor1987 的回复:
图片不错^.^

终于有点懂我的为什么出错了.按照我的写法,是不能写成的吗?

我狠奇怪qsort是怎么实现的.它也需要实现自己的比较函数.但就没有我现在的问题.

who knows?

lz有没试试我在18楼给的代码? 那里我是直接让result指向的内存保存了结果值,不是地址~ 整理下,连同测试代码放在下面:

C/C++ code
void FindMin(void *arr,int arr_size,int arrmembersize,void * resul…
[/Quote]


相当的佩服...
估计qsort里面也是这么实现的.我们的方法虽然可以,但是没有你的漂亮.
mark
光宇广贞 2009-05-19
  • 打赏
  • 举报
回复
cmp(p+index*arrmembersize,p+i*arrmembersize

自己来定位的方法。

恭喜楼主,贺喜楼主,楼主万福
boluor1987 2009-05-19
  • 打赏
  • 举报
回复
试了,只是一直没想明白自己怎么错了...所以自己又写了个.现在搞清楚了. 其实完全可以把指针都看做char *.这样就清晰多了^.^


#include "stdio.h"
#include "stdlib.h"


int cmp(const void *a,const void *b){
return *((int *)a)-*((int *)b);
}

int FindMin(const void *arr,int arr_size,int arrmembersize,int (*cmp)(const void *,const void *)){
char *p=(char *)arr;//开始的时候,我不是很明白,所以,以为用(int *)都可以.原来,指针本身所占字节没问题,只是加减的时候,是按照对应类型所占的字节数来移动的.所以本题应该用(char *)
int index=0;
int i;
for (i=1;i<arr_size;++i){
if (cmp(p+index*arrmembersize,p+i*arrmembersize)>0){
index=i;
}
}

return index;
}


int main(){
int arr[]={2,1,1,2,3,4,5,0,2,3,1,3};
//int *result;
int result;
result=FindMin(arr,12,sizeof(arr[0]),cmp);

printf("%d,%d\n",result,arr[result]);
//system("PAUSE");
return 0;
}



xlttap 2009-05-19
  • 打赏
  • 举报
回复
对,就用void*来实现。
加载更多回复(30)

64,664

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧