在线求助!!悬赏100分

vpeen 2006-08-10 04:22:31
我在vs.net中用控制台方式进行了标准C开发,当初是因为TC汉字麻烦,VC又不能直接编译C,现在问题是:一个C文件编译执行都OK,但是由于在开发一个纯C的搜索引擎,用到很多C文件,连接起来想实现类似C++中的类的思路,可是郁闷的是,我在vs2003下试验了两个c文件连接不成功,具体代码简单写在下面,错误也写在下面。请各位帮忙!!

------------------------------ 文件min.c--------------------------------------------------
int MinNumber(int a,int b)
{
return(a<b? a: b);
}
------------------------------ 文件ex1.c--------------------------------------------------
#include <stdio.h>
#include "min.c"
extern int MinNumber(int a,int b);
main()
{
int a=1;
int b=2;
int c;
c=MinNumber(a,b);
printf("%d",c);
}

错误情况:

texte fatal error LNK1169: 找到一个或多个多重定义的符号
texte error LNK2005: _MinNumber 已经在 ex1.obj 中定义


请问:
vs2003下面到底可不可以编写一个多c文件的项目,如果可以,怎么弄?如果不可以,推荐一个好的IDE,支持中文和多文件连接。 :)
...全文
559 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
guoshanhe 2006-08-11
  • 打赏
  • 举报
回复
mark
netxuning 2006-08-11
  • 打赏
  • 举报
回复
mark
灯草拐杖 2006-08-11
  • 打赏
  • 举报
回复
来晚了,有人回答了
Arthur_ 2006-08-11
  • 打赏
  • 举报
回复
学习
Arthur_ 2006-08-11
  • 打赏
  • 举报
回复
mark
chenhu_doc 2006-08-10
  • 打赏
  • 举报
回复
C语言的多态实现
相信很多人都看过设计模式方面的书,大家有什么体会呢?Bridge,Proxy,Factory这些设计模式都是基于抽象类的。使用抽象对象是这里的一个核心。

其实我觉得框架化编程的一个核心问题是抽象,用抽象的对象构建程序的主体框架,这是面向对象编程的普遍思想。用抽象构建骨架,再加上多态就形成了一个完整的程序。由于C++语言本身实现了继承和多态,使用这样的编程理念(理念啥意思?跟个风,嘿嘿)在C++中是十分普遍的现象,可以说Virtual(多态)是VC的灵魂。

但是,使用C语言的我们都快把这个多态忘光光了。我常听见前辈说,类?多态?我们用的是C,把这些忘了吧。很不幸的是,我是一个固执的人。这么好的东西,为啥不用呢。很高兴的,在最近的一些纯C代码中,我看见了C中的多态!下面且听我慢慢道来。

1. VC中的Interface是什么
Interface:中文解释是接口,其实它表示的是一个纯虚类。不过我所要说的是,在VC中的Interface其实就是struct,查找Interface的定义,你可以发现有这样的宏定义:
#Ifndef Interface
#define Interface struct
#endif
而且,实际上在VC中,如果一个类有Virtual的函数,则类里面会有vtable,它实际上是一个虚函数列表。实际上C++是从C发展而来的,它不过是在语言级别上支持了很多新功能,在C语言中,我们也可以使用这样的功能,前提是我们不得不自己实现。

2.C中如何实现纯虚类(我称它为纯虚结构)
比较前面,相信大家已经豁然开朗了。使用struct组合函数指针就可以实现纯虚类。
例子: typedef struct {
void (*Foo1)();
char (*Foo2)();
char* (*Foo3)(char* st);
}MyVirtualInterface;

这样假设我们在主体框架中要使用桥模式。(我们的主类是DoMyAct,接口具体实现类是Act1,Act2)下面我将依次介绍这些“类”。(C中的“类”在前面有说明,这里换了一个,是使用早期的数组的办法)

主类DoMyAct: 主类中含有MyVirtualInterface* m_pInterface; 主类有下函数:
DoMyAct_SetInterface(MyVirtualInterface* pInterface)
{
m_pInterface= pInterface;
}
DoMyAct_Do()
{
if(m_pInterface==NULL) return;
m_pInterface->Foo1();
c=m_pInterface->Foo2();
}
子类Act1:实现虚结构,含有MyVirtualInterface st[MAX]; 有以下函数:
MyVirtualInterface* Act1_CreatInterface()
{
index=FindValid() //对象池或者使用Malloc !应该留在外面申请,实例化
if(index==-1) return NULL;
St[index].Foo1=Act1_Foo1; // Act1_Foo1要在下面具体实现
St[index].Foo2=Act1_Foo2;
St[index].Foo3=Act1_Foo3;
Return &st [index];
}
子类Act2同上。

在main中,假设有一个对象List。List中存贮的是MyVirtualInterface指针,则有:
if( (p= Act1_CreatInterface()) != NULL)
List_AddObject(&List, p); //Add All

While(p=List_GetObject()){
DoMyAct_SetInterface(p);//使用Interface代替了原来大篇幅的Switch Case
DoMyAct_Do();//不要理会具体的什么样的动作,just do it
}

FREE ALL。
在微系统里面,比如嵌入式,通常使用对象池的技术,这个时候可以不用考虑释放的问题(对象池预先没有空间,使用Attach,在某个函数中申请一个数组并临时为对象池分配空间,这样函数结束,对象池就释放了)

但是在Pc环境下,由于程序规模比较大,更重要的是一些特殊的要求,使得对象的生命周期必须延续到申请的那个函数体以外,就不得不使用malloc,实际上即使在C++中,new对象的自动释放始终是一个令人头疼的问题,新的标准引入了智能指针。但是就我个人而言,我觉得将内存释放的问题完全的交给机器是不可信任的,它只能达到准最佳。

你知道设计Java的垃圾回收算法有多困难吗?现实世界是错综复杂的,在没有先验条件下,要想得到精确的结果及其困难。所以我说程序员要时刻将free记在心上,有关程序的健壮性和自我防御将在另外一篇文章中讲述。

3.纯虚结构的退化
下面我们来看看如果struct里面仅仅有一个函数是什么? 这个时候如果我们不使用struct,仅仅使用函数指针又是什么? 我们发现,这样就退化为普通的函数指针的使用了。

所以说,有的时候我觉得面向对象仅仅是一种形式,而不是一种技术。是一种观点,而不是一种算法。但是,正如炭,石墨和钻石的关系一样,虽然分子式都是C,但是组成方法不一样,表现就完全不一样了!
有的时候,我们经常被编程中琐碎的事情所烦恼,而偏离了重心,其实程序可进化的特性是很重要的。有可能,第一次是不成功的,但是只要可进化,就可以发展。

4.进阶――类结构树,父类不是纯虚类的类
前面仅仅讲的是父类是纯虚结构的情况 (面向对象建议的是所有类的基类都是从纯虚类开始的), 那么当类层次比较多的情况下,出现父类不是纯虚结构怎么办呢。嘿嘿,其实在C中的实现比C++要简单多了。因为C中各个函数是分散的。

在这里使用宏定义是一个很好的办法:比如两个类Act1,ActByOther1“继承”Act1:
MyVirtualInterface* ActByOther1_CreatInterface()
{
index=FindValid() //对象池或者使用Malloc
if(index==-1) return NULL;
St[index].Foo1= ActByOther1_Foo1; // Act1_Foo1要在下面具体实现
St[index].Foo2= ActByOther1_Foo2;
St[index].Foo3= ActByOther1_Foo3;
Return &st [index];
}

#define ActByOther1_Foo1 Act1_Foo1 //这就是继承 嘿嘿
ActByOther1_Foo2(){} // 可以修改其实现
ActByOther1_DoByOther() {} //当然就可以添加新的实现咯

5.实例――可以参见H264的源码,其中NalTool就是这样的一个纯虚结构。
作者Blog:http://blog.csdn.net/liyuming1978/

//我没有做过,给个参考资料
chenhu_doc 2006-08-10
  • 打赏
  • 举报
回复
extern int MinNumber(int a,int b);
去掉
vpeen 2006-08-10
  • 打赏
  • 举报
回复
感谢各位!fflush(stdin)和tailzhou(尾巴) ,谢谢你们,问题已经解决,采用.h形式的确可以保证该C文件最多编译一次,大大加快运行速度。
至于多态问题的解决,还是没有找到好方法。
还有个问题不清楚,就是在windows下先编写,再移植到Liunx下是否可以??要是形÷可以的话,采取什么方案?
Arthur_ 2006-08-10
  • 打赏
  • 举报
回复
其实有两种方法来使用外部函数,一种是包含头文件,一种是使用extern,推荐使用头文件

一般用dev就好了,不过编window程序有点问题,个人推荐lcc win32 3兆基本上可以编译所window程序。

Dong 2006-08-10
  • 打赏
  • 举报
回复
extern int MinNumber(int a,int b);
----------------------
这个去掉!因为mic.c已经包含了!
fflush 2006-08-10
  • 打赏
  • 举报
回复
你这样做肯定会造成重复定义,在vc中,每一个*.c文件可以被视为一个模块(都会进行编译,而在tc中,你可能没有进行关于工程的设置,只编译了ex1.c),你这样等于在min.c和ex1.c中都定义了MinNumber。解决办法tailzhou(尾巴)已经给出,并且我认为这也是通用的解决方案,也就是说,所有的人都这么干的

另外,#include"min.c "的想法是包含同一目录下的不同源文件,而#include"min.h"肯定和我的想法无关,谢谢各位
--------------------------------------------------------------------
没明白你的意思,你是想MinNumber具有“多态性”?这在c中不好实现,你可以使用macro来部分的实现
kangji 2006-08-10
  • 打赏
  • 举报
回复
turbo c需要建立project,把多个.c包含进去,也一样可以编译
vpeen 2006-08-10
  • 打赏
  • 举报
回复
首先,我这个例子只是说我想将一个项目分成若干块,通过多个 .c 文件连接编译,刚才试验了一下,在vc.net环境中只用extern声明外部函数就可以通过编译,但是我把原来的程序放在Turbo C下面发现extern方法不行,只能#include “min.c”。
我想既然net做得如此庞大,不可能没有一个好的办法实现纯c多文件编译,呵呵,我以前一直没有真正地用标准C做过项目,希望有这方面经验的朋友给我一些建议。
另外,#include"min.c "的想法是包含同一目录下的不同源文件,而#include"min.h"肯定和我的想法无关,谢谢各位
lkpo 2006-08-10
  • 打赏
  • 举报
回复
#include "min.c"或将min.c改为min.h

lz的错误很低级,要认真点哦
睡在床板下_ 2006-08-10
  • 打赏
  • 举报
回复
VC又不能直接编译C ??为什么
william_weizhen 2006-08-10
  • 打赏
  • 举报
回复
将#include "min.c"去掉
wswqwps 2006-08-10
  • 打赏
  • 举报
回复
定义函数默认是extern的
kangji 2006-08-10
  • 打赏
  • 举报
回复
#include "min.c"
去掉就行了
yzx1983 2006-08-10
  • 打赏
  • 举报
回复
#include <stdio.h>
#include "min.c"
--------------------

如果你要两个c文件一起编译连接,那么你不应该这样include一个c文件。
bo.cui 2006-08-10
  • 打赏
  • 举报
回复
还是用devc++编译器吧~~
比较好用,还小,还简单~(调整性强,可以调节成支持C99什么的~)

上面代码小弟在devc++下调试了 没问题呀~~ 呵呵
环境:winxp 编译器:devc(gcc)

(2个文件在同一个目录,并且编译min.c.


原代码略做修改:
_______________________________ex1.c____________________
#include <stdio.h>
#include "min.c"
extern int MinNumber(int a,int b);
int main(void)
{
int a=1;
int b=2;
int c;
c=MinNumber(a,b);
printf("%d",c);
getch();
return 0;
}
___________________________________min.c_________________
int MinNumber(int a,int b)
{
return(a<b? a: b);
}
_________________________________________________________________________________

输出结果:1

呵呵~~~
加载更多回复(3)
主要特点: 1、优化会员注册页面,全部采用ajax无刷新提示; 2、强大而灵活的邮件提醒机制:N天未登录提醒、同城好友推荐提醒、生日提醒等,有效提升会员粘性; 3、增加礼物中心。礼物中心可在后台添加新类、新礼物,并且可以设置礼物价格、VIP会员折扣等; 4、 VIP支付中心。升级VIP会员后可查看对方联系方式,拥有更多主动权,同时可优先在搜索结果中排名优先,可在网站显著位置推荐、首页推荐等。优化和美化元VIP支付模块,界面更清爽直观,功能更直接适用。用户在线支付后可以自动升级为VIP会员,或自动更新M币增加,真正实现了在线支付的自动化、自助化; 5、用户可申请首页推荐,管理员收到通知后可以选择是否通知,并告知其理由; 6、将首页的会员推荐和排行榜推荐开,排行榜推荐单独用页面展示,用户用积即可自动申请上榜; 7、增加会员顶部黄金推荐位功能,用户点击后可以申请,按天数收费,费用额度可以由站长设定。此为增加站长盈利渠道的方式; 8、增加诚信星级认证系统,将资料完整度、相片数、是否设置头像、是否通过身份通认证、用户近30日登陆天数、空间访问人气等指标综合,得出星级,根据会员的资料完整度进行星级标识; 9、增加心灵匹配测试系统,用户通过测试后,能够更好地了解自己和他人。通过测试后,会在其个人主页解读其恋爱类型和交往提示; 10、增加梦缘推荐功能,用户设置择偶标准后,系统会按照最后登录、活跃度等指标,为其推荐同城异性会员; 11、扩充会员资料,增加择偶标准、个性资料、约会宝典、幸福宣言等类,方便用户更好地了解自己和他人; 12、增加求助中心,用户可悬赏提出问题,回答满意者可以结贴赠送积。也可以增加悬赏。; 13、增加1+1约会功能,用户通过身份通实名认证后,可以发起约会邀请,感兴趣的会员可以表示关注、报名等等操作。; 14、增加成功故事功能,交友成功的会员可以发布两个人的爱情故事,与大家一起享他们的幸福快乐!; 15、增加后台管理功能,用户的用户名、密码等等全部个人信息,几乎都可以在后台方便地修改更新; 16、增加短信管理功能,可以在后天方便地浏览、删除; 17、可以在后台设置首页推荐会员、首页相片推荐、排行榜推荐等等; 18、可以在后天更改会员头像; 19、用户注册添加ajax验证输入框效果,可实时监测用户名、email是否合法、是否已注册;用户名限制不能N位为数字(N可自定义),防止用户用手机号码或者qq注册。 20、完善过滤机制,在留言板、相片和博客评论等处的信息,如果包含4位以上数字或email信息者,发布失败,弹出完善资料,通过站内联系或者升级vip之类的友情提示! 21、保留uchome和uc架构,方便后续版本的升级,方便用户自行安装插件扩展、个人空间模板等; 22、首页幻灯片可在后台方便添加、删除和编辑; 23、增加恋爱资讯模块,管理员可以发布、编辑、删除资讯! 24、后台添加关键词和描述编辑功能,方便搜索引擎收录! 25、后台可编辑关于我们-隐私策略-会员条款-联系我们等页脚信息; 26、增加完善的互助中心系统。管理员可以发布网站使用的帮助主题,会员也可以提出问题,然后全体会员帮助你解答,构建和谐互助的交友氛围! 27、附带完整的全新安装和升级教程,只需鼠标操作,几钟就可搭建起一个和点梦缘交友网一模一样的交友网站! 28、增加同城异性会员定期推荐邮件功能,对于N(N的数值可在后台配置)天未登录的会员,可以向其邮箱发送同城异性会员推荐邮件!

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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