当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 《新加坡程序员考题一则及分析》的讨论

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 《新加坡程序员考题一则及分析》的讨论


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 52 ::
收藏到网摘: n/a

《新加坡程序员考题一则及分析》的讨论
作者:史列因

VC知识库21期刊登了一篇《新加坡程序员考题一则及分析》,但给出的代码却有大问题, 本文对此作一分析。

首先,题目明确要求"这个类必须从 C++ 中标准的 string 类派生",注意,是STL的string, 而不是MFC的CString。而且要求派生类的名字是String,而不是CMyString。这样,可以看出给出的程序完全不合要求。
以第一个函数为例,下面是一个基本符合要求的答案(对于不同的STL版本,可能会有细微的差别):

class divide_empty_substring : public logic_error{	const char * what() const throw() { return "Divided by an empty substring"; }};size_type String::operator / (const String & sub) const//注意第二个const{	if (sub.empty())	throw divide_empty_substring();//通常,抛出异常比返回0要合适	size_type n = 0;	size_type i = 0;	while ((i = find(sub, i)) != npos)	n++;	return n;	}
至于get_token的实现当然也有类似问题,但除此之外,还有一个问题:不应该使用静态变量!
题目中的叙述很容易使人使用静态变量,但这种叙述实际上是一个圈套。因为我们在实现的是类的成员函数,而不是全局函数,所以应该使用的是成员变量。否则,下面的代码会出现问题:
String str1, str2;.....str1.get_token();str2.get_token();//取得的是str2的第二个token
除掉这些语法性的问题,我们来看看算法:
int CMyString::operator/ (const String& sub){ if(sub.IsEmpty()) return 0; int count=0;	//sub在字符串中的出现次数count int ret = Find(sub);	//辅助变量ret if(ret == -1) return 0; else if(ret <= GetLength())//!! if语句多余,条件永远为真 {	do	{ count++; ret=Find(sub,GetAt(ret));//!! GetAt()在干什么!编译倒是能通过,可意思全拧了.	}while(ret != -1); } return count;}

至于get_token()的简直是一团糟!
CString CMyString::get_token(){ static int callednum=0;	//callednum纪录该函数的被调用次数 int totalnum=operator/('''' '''');	//totalnum是空格的总个数 if(totalnum==0) return NULL; int tokennum,ret1=0,ret2=0;	//tokennum是的token的总个数 while((ret1=Find('''' '''',ret2))!=-1 &&((ret2=Find('''' '''',ret1))!=-1)//!! ret1,ret2在这里开始都是0,所以找到的总是第一个记号 { if(ret1==ret2-1) totalnum--;//两个相邻的空格算作一个 return Mid(ret1,ret2-ret1); //!!如果上面的if()条件成立,这就返回一个空格,否则返回值正确,但callednum没有变化 } //!!如果执行到了这里,那就说明一个记号都没有,直接返回Stirng()就是了.下面的也都没了意义. if(ret2==-1) return Right(GetLength()-ret1); tokennum=totalnum; (callednum++)%=tokennum;//!!既然tokennum=totalnum;那么还要tokennum干什么? //!!最后一个分支竟然没有返回值} 

(完)