九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

继续boost的相关学习, boost::string_algo让std::string这样的废柴类有用一点

继续boost的相关学习, boost::string_algostd::string这样的废柴类有用一点

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

一、   string态度的慢慢转变

作为一个初学者,本来没有批评大牛们创造的语言及其标准库的资本,初期看的一些教学书籍总是推荐你在绝大多数时候不要使用char*,使用string,比如C++ Primer,C++ Effective等,但是再接着看深点,就开始有书批评C++中的某些库了,比如C++ STL Library,(批评string的书比较多,我倒是一下子举不出例子-_-!)但是,甚至在看过很多书批评std::string后,我还是感觉尽量去使用std::string比较好,知道越用感觉越多的不方面,除了与标准库算法搭配较为方便外,std::string甚至比不过CString好用,性能上的问题也是比我想象的要严重的多,以前在做代码优化的时候发现,按照常用的for循环记法,绝大多数标准库容器都会将begin(),end()这样的迭代器函数调用内联,但是唯独std::string不会,傻傻的每次都调用(在VS2005上测试,全优化结果一致)。

假如这方面你还可以说是MSstring实现上的缺陷的话(事实上现有STL几乎统一是来源于HP的库),那么作为一个string,在std中甚至连一个大小写转换的函数都没有,甚至连大小写不敏感的比较都没有,那就实在说不过去了,想想python,lua等语言中一个string是何其的强大!难道是因为C ++的设计者们都做操作系统,一般不处理字符串?-_-!没有正则表达式的历史原因我就不多说了。。。。

二、   轮子没有总会有人造的

于是乎,在需要相关功能的时候,需要用replacestricmp加上一大串参数来完成,从理解的角度来说其实并不那么直观,对于普通功能的实现我能理解,但是对于常用功能老是这样用,感觉总是不爽,于是问题又来了,自己做个自己的库吧,下次重复利用就完了,才发现,当一种语言需要人造一个本应该存在的轮子的时候,这个语言本身就有问题。

再于是乎,造轮子的人boost::string_algo诞生了,可见std::string的恶劣。。。。自然,像这种库要进标准肯定是没有戏了,自己偷着用吧。

三、   boost::string_algo个人概述

string_algo我粗略的看了一下,相对而言还是比较强大,实现了很多功能。个人觉得必要的功能,比如大小写转换:to_upperto_lower有了。python中用的很愉快的字符串处理函数,很有用的功能,比如trim, trim_left , trim_right (Python中对应的函数名字是striplstrip,rstrip)Python中经常用到的starts_with也有了,相关的很多find函数也出来了,最最让我高兴的是,splice函数也有了。。。。这个函数在处理CSV数据的时候相当有用,一个函数往往可以节省很多的工作量。另外,其实从函数的参数来看就能看出两种语言的文化,C++的很多算法喜欢以_if的形式提供,要求用户提供判断函数,甚至是trim_left这样的函数也不提供一个以字符形式提供出来的参数以指定到底削除啥,而是提供了trim_left_if的函数来由你判断。。。。个人感觉,虽然_if的用法有的时候能极大的提高算法的适用范围,但是对于简单应用来说,实在离make simple things easy原则,何况,在没有lambda语法,没有好用的bind,却有强类型的复杂函数定义形式,复杂的函数指针语法,超复杂的成员函数指针语法的C++中,要好好的用对,用好一个类似的情况,实在并不见得那么简单。。。。。。。。。。。

最近老是将C++Python做比较,感觉自己似乎更像是一个初学C++Python程序员在不停的抱怨。。。其实本人还是完全靠C++吃饭的,仅仅是业余时间学习一下Python(工作中也用,但是比较少),本人的观点一向是,虽然将不关心效率,奇慢的动态类型语言Python和以效率为根本的强类型C++做语法比较对C++非常不公平,但是,来自另一个语言的经验其实对于反思一个语言需要什么和怎么样更好的使用现有语言还是很有帮助的,就是因为这种相互的促进,我才会从需求的角度去学习了很多boost的库,比如《多想追求简洁的极致,但是无奈的学习C++for_each的应用》,《其实C++Python更需要lambda语法,可惜没有。。。。》,《boost::function,让C++的函数也能当第一类值使用》不然,都是纯粹的跟着文档走的学习,那个效果要差的太多。

四、   例子:

这里将我试用我感兴趣函数的例子列出来,其实,知道个大概以后,留份参考文档,以后有需要的时候,会发现工具箱中实在是又多了很重要的一项工具。

 

1.      大小写转换

void CaseChange()

{

    string lstr("abcDEF");

    string lstr2(lstr);

 

    // 标准形式

    transform(lstr.begin(), lstr.end(), lstr.begin(), tolower);

    cout <<lstr <<endl;

 

    // string_algo

    to_lower(lstr2);

 

    cout <<lstr2 <<endl;

}

比较奇怪的就是,为啥to_lower这样的函数不返回转换后的字符串,这样可以支持很方便的操作,难道也是出于不为可能不需要的操作付出代价的原则考虑?。。。。。。很有可能,想想标准的map.erase函数吧,看看《C++ STL Library》中相关的评价及说明。这是C++程序员的一贯作风。

2.      大小写不敏感的比较

void CaseIComp()

{

    string lstrToComp("ABCdef");

    string lstr("abcDEF");

    string lstr2(lstr);

 

    string lstrTemp;

    string lstrTemp2;

    // 标准形式worst ways

    transform(lstr.begin(), lstr.end(), back_inserter(lstrTemp), tolower);

    transform(lstrToComp.begin(), lstrToComp.end(), back_inserter(lstrTemp2), tolower);

    cout <<(lstrTemp == lstrTemp2) <<endl;

 

    // 标准形式

    cout << !stricmp(lstr.c_str(), lstrToComp.c_str()) <<endl;

 

    // string_algo 1

    cout << (to_lower_copy(lstr2) == to_lower_copy(lstrToComp)) <<endl;

 

    // no changed to original values

    cout << lstr2 <<" " <<lstrToComp <<endl;

 

    // string_algo 2 best ways

    cout << iequals(lstr2, lstrToComp) <<endl;

}

 

好了,我们有比调用stricmp更好的办法了,如例子中表示的。

 

3.      修剪

void TrimUsage()

{

    // 仅以trim左边来示例了,trim两边和右边类似

    string strToTrim="     hello world!";

 

    cout <<"Orig string:[" <<strToTrim <<"]" <<endl;

 

    // 标准形式:

    string str1;

    for(int i = 0; i < strToTrim.size(); ++i)

    {

       if(strToTrim[i] != ' ')

       {

           // str1 = &(strToTrim[i]);  at most time is right,but not be assured in std

           str1 = strToTrim.c_str() + i;

           break;

       }

    }

    cout <<"Std trim string:[" <<str1 <<"]" <<endl;

   

    // string_algo 1

    string str2 = trim_left_copy(strToTrim);

    cout <<"string_algo string:[" <<str2 <<"]" <<endl;

 

    // string_algo 2

    string str3 = trim_left_copy_if(strToTrim, is_any_of(" "));

    cout <<"string_algo string2:[" <<str3 <<"]" <<endl;

}

 

可见一个常用操作在std中多么复杂,甚至直接用char*实现这样的操作都要更简单,效率也要更高,string版本不仅失去了效率,也失去了优雅。但是在有了合适的库后多么简单,另外,假如std可以有更简化的办法的话,欢迎大家提出,因为毕竟我在实际工作中也没有boost库可用。

 

 

4.      切割

不是经常处理大量数据的人不知道字符串切割的重要性和常用长度,在比较通用的数据传递方式中,CSVComma separated values)是比较常用的一种,不仅仅在各种数据库之间传递很方便,在各种语言之间传递数据,甚至是用excel打开用来分析都是非常方便,Pythonstring有内置的split函数,非常好用,我也用的很频繁,C++中就没有那么好用了,你只能自己实现一个切割函数,麻烦。

示例:

void SplitUsage()

{

    // 这是一个典型的CSV类型数据

    string strToSplit("hello,world,goodbye,goodbye,");

 

    typedef vector< string > SplitVec_t;

    SplitVec_t splitVec1;

    // std algo 无论在任何时候string原生的搜寻算法都是通过index返回而不是通过iterator返回,总是觉得突兀

    // 还不如使用标准库的算法呢,总怀疑因为stringSTL的分别设计,是不是string刚开始设计的时候,还没有加入迭代器?

    string::size_type liWordBegin = 0;

    string::size_type liFind = strToSplit.find(',');

    string lstrTemp;

    while(liFind != string::npos)

    {

       lstrTemp.assign(strToSplit, liWordBegin, liFind - liWordBegin);

       splitVec1.push_back(lstrTemp);

       liWordBegin = liFind+1;

       liFind = strToSplit.find(',', liWordBegin);

    }

    lstrTemp.assign(strToSplit, liWordBegin, liFind - liWordBegin);

    splitVec1.push_back(lstrTemp);

 

    BOOST_FOREACH(string str, splitVec1)

    {

       cout <<" split string:" <<str <<endl;

    }

 

    // string_algo

    SplitVec_t splitVec2;

    split( splitVec2, strToSplit, is_any_of(",") );

 

    BOOST_FOREACH(string str, splitVec2)

    {

       cout <<" split string:" <<str <<endl;

    }

}

 

5.      其他:

至于其他的搜寻,替换,由于标准库中的已经比较强大了,string_algo也就算锦上添花吧,我的对搜寻和替换的需求不是那么强烈。大家参考boost本身的文档吧。在搜寻中提供搜寻迭代器的方式倒是还是使易用性有一定提高的。至于正则表达式这个字符串处理的重头戏嘛,因为tr1中都有了regex库了,平时使用的时候还是以此为主吧,相对string_algo这个宿命就是存在于boost的库来说,tr1regex库在将来肯定可移植性及通用性更强。

 

五、   稀泥终究糊不上墙

虽然string_algo可以弥补std::string的功能缺陷,但是string的性能问题又怎么解决啊?。。。。因为string如此的弱,导致stringstream的使用都有很大的问题(在内存上),有兴趣的可以再网上搜搜,当年工作的时候就是因为太相信标准库,结果用了stringstream来实现整数到string的转换,结果经历除了痛苦就是痛苦,公司服务器因为此问题全服停止了2次。stringstream在作为局部变量存在的时候都会无止尽的消耗内存,这点我以前怎么也无法想象。

实际中的使用也是反应了std::string的悲哀,看看有多少实际的项目中没有实现自己的一套string?

其实寄希望于regex库出来后,std::string就能涅槃也不是太可能,std::stringstring可能在平时的使用中是个简化编程的好办法,但是在对性能和内存占用稍微有点追求的程序,估计,std::string的使用还是会少之又少。。。。。。。。。。。

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

阅读全文....

恐怖的boost库,难道还有什么是没有的吗?改变了对原有跨平台支持库开发想法。假如我以后不能使用boost库那怎么办啊?!


恐怖的boost库,难道还有什么是没有的吗?改变了对原有跨平台支持库开发想法。假如我以后不能使用boost库那怎么办啊?!

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

最近这段时间以理解asio为契机,开始学习了一些以前并不用到的boost库,慢慢的发现boost库的强大远超过我的想象,以前我也就用用boost库中的智能指针,后来TR1出来后,在学习正则表达式的时候,尝试用过其boost::regex这个以后肯定会进C++09标准的东西,其他东西用的还真是不多,毕竟工作中学习的时间还是少了些,公司的开发又完全不准用boost的,加上又有太多东西要学,直到最近说要学习网络编程的相关知识,然后找到了asio,才开始又一次的慢慢接触boost库了,再加上学习python的过程中,不断的对C++现有体系进行了反思(其实主要还是语法上的,毕竟我层次还没有那么高),常常回过头来看看C++中的对应用法,虽然这里将一个超级慢的动态语言的语法优点来和以效率为生命的C++来对比不是太公平,但是起码我加深了对很多东西的理解,在连续的三篇文章中可以得到体现:

分别是《多想追求简洁的极致,但是无奈的学习C++for_each的应用》,《其实C++Python更需要lambda语法,可惜没有。。。。》,《boost::function,让C++的函数也能当第一类值使用》,其实,也许还可以为boost::bind专门写一篇,但是后来觉得自己对嵌套反复的bind语法还是比较反感,就作罢了,虽然boost::bind比现在标准库中的bind1st,bind2nd加一大堆的mem_funXXX的东西优美一些,但是即便新的标准加上bind,加上mem_fn,其实感觉还是在语言上打补丁一样,还不是那么的优美,唉。。。具体要多优美,这个我也就不好说了。。。。。。。弱弱的说一句,看看python的列表解析。。。。

但是,对boost库的进一步了解,倒是让我对自己写一个可移植网络框架的心少了很多,一方面的确也是精力不太够,另一方面我发现自己没有办法写的比boost中现有的更好(也许能更加精简)。这里将原有的计划列出来,对比一下boost中已经有的东西。详细计划见原来的文章《工作之外的学习/开发计划(1) -- windows/linux服务器程序支持库的开发

工作之外的学习/开发计划(1) -- windows/linux服务器程序支持库的开发

简化服务器程序的开发,设计合理的服务器框架程序。 --- 主要目的

实现工程文件(对我来说一般就是服务器程序)以同一套源码在windowslinux下的编译运行。 -- 次要目的,但是必完成-_-!

其实对于支持库来说,很重要的一点来说,就是尽量对外实现操作系统无关的同一套接口。。。。

 

需求列表:(仅仅是知识还非常欠缺的我目前能想到的,以后需要再添加吧)

网络框架支持:

windows服务器TCPIOCP模型

linux服务器TCPepoll模型

UDP都用同一套

另外,为简单的网络应用程序(其实在我们公司中是客户端跑的)使用select模型。(就目前我浅显的网络知识了解,我不明白为什么要这样,select其实也是属于I/O复用的模型了,但是实际客户端方面用的都是单套接字,单连接,单处理线程,难道仅仅是为了防止输入阻塞和套接字API阻塞的冲突?)

 

服务器其他支持库

1.       序列化支持。

2.       日志系统支持。

3.       脚本语言配置文件支持。(可考虑上脚本系统)

4.       运行时异常dump支持。

5.       多线程支持。(其实看很多书说Linux下弄单进程更好,但是那样和windows下共用一套源码估计就更难了。)

6.       windows下也能跑的posix库。

7.       ODBC/mySQL API 支持库(任选)

8.       多进程支持(待选)。

 

这里给出一个boost中已有实现的对比。。。

首先,我的目标。。。。可移植的网络框架,以简化开发服务器为目的。。

boost作为准标准库可移植性实在是做的够好了。。。。看看其文档中支持的编译器/环境列表就知道了,远超我以前的目标Windows/Linux可移植。。。。

其次,核心模块,网络框架,boost::asio的实现就是和我原有设想的实现一模一样。。。。。windowsIOCP模型,linuxepoll,并且作为一个已经获得较广泛使用的轻量级网络支持库,见《Who is using Asio? 》并且甚至可能进入下一版的C++标准(虽然个人认为可能性还是比较小),还是远超我以前的目标。。。。。当然,我从来没有目标去达到想ACE一样,asio就很不错了。

然后,其他支持库:

1.序列化支持。==boost::serialize库,强大,强大,还是强大,我有一系列文章,介绍了其强大和使用方法。《序列化支持(1)》,《序列化支持(2)—Boost的序列化库》,《序列化支持(3)—Boost的序列化库的使用》,《序列化支持(4)—Boost的序列化库的强大之处》。但是比较遗憾的是,虽然据说BS以前很遗憾的说,现在C++中最大的遗憾就是没有数据持久化和垃圾回收机制的话,但是,boost::serialize似乎还是没有希望进入下一版C++标准,也就是说,我们以后的C++只能还是没有一个标准的序列化方式可以使用。。。。

2.日志系统支持。==》这个boost种据说以前有过,但是后来停止开发了,最近也在某个地方看到过一个使用标准iostream的日志库,一下子没有找到,但是其实实在没有,用log4cxx也不错。再没有自己写一个也不难(在公司我就完成过用额外的线程写日志的工作,包括测试也就用了一天时间)

3. 脚本语言配置文件支持。(可考虑上脚本系统)==》这点更好了,boost::Program Options就是完全对应的选择,并且,假如我想用Python,我还可以不仅仅是使用PythonC API,个人感觉要完全用Python C API去映射C++的类相对来说还是比较难,但是有了boost::Python库又不一样了。。。。生活可以更美的。

4.运行时异常dump支持。==》这个嘛。。。。除了我以前研究过的googlebreakpad似乎不知道还有其他更好的选择没有,实在不行也就只能自己做了。注意啊,这个dump不仅仅是出错/异常的时候,我应该能在我需要的任何时候进行core dump,而不影响程序的运行。

5.多线程支持。==》天哪。。。boost::thread库就是为这个准备的,并且其实现的确不错,虽然假如自己要实现一套也不算太难。

6. windows下也能跑的posix库。==》虽然说boost::System库设计的就像是错误代码集合库,但是在大量的使用boost库后,posix的很多功能有没有必要使用还难说。。。。。比如说boost::Filesystem,boost:: Date Time的支持作用还是很强的

7. 多进程支持==》创建进程的方式在Windows(CreateProcess)LinuxFork)下的差异还是有的,但是也不是完全不能统一,麻烦点的就是Windows没有僵尸进程的概念导致进程ID不能真正区别出一个进程,比如说一个ID100的进程关闭了,然后一个新的进程启动后ID100,并且父子进程之间的联系比Linux下要弱的多。,比如没有getppid系统调用,其实CreateProcess后,父进程将子进程的句柄都close后,两者就几乎没有关系了,可能仅有的联系就是子进程继承了父进程的核心对象列表,Linux下子进程可是必须等待父进程来‘收割的啊:)但是最最核心的问题还是IPC(进程通信)的问题,还好,boost:: Interprocess又是完美的满足了需求

 

如上所述。。。一个可移植的网络服务器开发支持库,基本上也就是boost库的一个子集。。。。我们能使用的还有如boost::Signals这样的库来实现网络包的分发及映射,有如智能指针,boost::funtion, boost::lambda, boost::bindboost::foreach来简化我们的程序,这个C++的世界还能更加美好吗?。。。。。。。呵呵,除非等下一代C++的标准出来了。。。。。

也许,使用boost库唯一的问题是。。。。让我使用了这么好用的库,假如我以后不能使用boost库那怎么办啊?!

呵呵,当然,总是要在自己的程序中带上很多的boost库的dll,其实也算是个问题。

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

阅读全文....

boost::function,让C++的函数也能当第一类值使用

boost::function,让C++的函数也能当第一类值使用

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

最近在学习Python比较特殊的语法的时候,顺便也研究了一下C++中的类似实现。。。本文中的一些内容也可以参考前几天写的文章《多想追求简洁的极致,但是无奈的学习C++for_each的应用

》《其实C++Python更需要lambda语法,可惜没有。。。。》最后发现类似的实现都要通过boost,并且还是比较扭曲的通过,然后,起码还算是实现那么回事了。然后前天工作正好属于配合工作,稍微有点时间,大致的看了下《Beyond the C++ Standard Library: An Introduction to Boost》,加深了一些理解,这里感叹一下,其起到的引导性作用还是不错的,可以有个大概的概念了以后再看boost的文档,那样更加事半功倍,虽然boost文档已经非常的好了,但是毕竟文档还是不同于教学。

当然,就算这个库真的进了C++09标准了其实也还是没有真的将函数作为第一类值那样简洁高效。。。。但是BS的原则嘛。。。尽量不扩张语言功能,而是去用库来实现。。。直到其没有办法,D&E上其认为C++中不需要原生的并发支持,用库就好了(虽然其实连标准库也没有)的言语还历历在目,09标准中却已基本通过增加并发的内存模型了。也不知道为啥。。。其语言只要符合需要就好,不成为特性的拼凑的思想,很显然让reflectclosure这样的特性也没有办法进入09标准了。。。无奈一下。

       简单描述一下问题:在函数是第一类值的语言中,你可以保存,动态创建及传递一个函数,就像是一个普通的整数一样。比如python,lua中你就能这样。但是在C++这样的语言中,你需要用函数指针来保存一个普通的函数,然后用类对象来保存函数对象。

参考《其实C++Python更需要lambda语法,可惜没有。。。。一文中的例子比如在Python中,你可以这样:

 

 1
 2 def add1(a,b):  return a + b
 3 add2 = lambda a,b : a + b
 4
 5 class Add():
 6     def __init__(self):
 7         self._i = 0
 8
 9     def reset(self):
10         self._i = 0
11         
12     def add(self, a, b):
13         self._i += a + b
14         return self._i
15
16 addobj = Add()
17 add3 = addobj.add
18
19 print add1(1,1)
20 print add2(1,2)
21 print add3(1,3)
22 addobj.reset()
23
24 fun = lambda f,a,b : f(a,b)
25
26 print fun(add1, 1, 1)
27 print fun(add2, 1, 2)
28 print fun(add3, 1, 3)
29 print fun(lambda a,b : a + b, 1, 4)

 

一个函数一旦定义以后,然后在以后再使用此函数,就像任何普通的函数定义一样,调用此函数并不关心函数实际的定义方式,是用lambda语法还是实际的完整函数定义,甚至是类的一个成员函数也是一样,语法完全一模一样。

C++中需要区别的就是,到底是函数对象还是函数指针,到底是普通函数还是对象的成员函数。。。假如加上boost库的话,还需要加上boost::lambda的定义的保存功能。假如函数真是第一类值的话,那么可以将以上的多种形式的函数语法统一,你尝试用用C++实现上述的例子就知道这些东西之间的语法差异多大了。但是,很明显,我们暂时不能奢望这一点,还好有boost::funciton库。

其实,就C++中的实现而言,光是需要实现函数的回调,通过模板来实现已经可以比较简化,因为函数模板的自动推导模板参数的功能可以让我们几乎不用写任何别扭的语法,也能实现上述的一些功能,比如普通函数,函数对象,还有boost::lambda库。

例子如下:

#include <list>

#include <iostream>

#include <boost/lambda/lambda.hpp>

#include <boost/bind.hpp>

using namespace std;

using namespace boost;

 

 

int add1(int a, int b)

{

    return a + b;

}

 

class add2

{

public:

    int operator()(int lhs, int rhs)

    {

       return lhs + rhs;

    }

};

 

class CAdd

{

public:

    int add3(int a, int b) { return a + b; }

};

 

 

template<typename FUN, typename T>

T fun(FUN function, T lhs, T rhs)

{

    cout <<typeid(function).name() <<endl;

    return function(lhs, rhs);

}

 

int add4(int a, int b, int c)

{

    return a+b+c;

}

 

 

int main()

{

    cout << fun(add1, 1, 1) <<endl;

    cout << fun(add2(), 1, 2) <<endl;

    cout << fun(lambda::_1+lambda::_2, 1, 3) <<endl;

    cout << fun(bind(add4, 0, _1, _2), 1, 4) <<endl;

 

    system("PAUSE");

}

 

直到这里,问题都不大,语法也算足够的简洁,模板的强大可见一斑。但是一旦你准备开始使用类的成员函数指针或者碰到需要将lambda生成的对象保存下来,需要将boost::bind生成的对象保存下来重复使用的时候,就碰到问题了,先不说类成员函数指针这种非要看过《Inside C++Object》一书,才能理解个大概,并且违反C++一贯常规的指针行为,甚至大小都可能超过sizeof(void*)的指针,起码在不了解boost这些库的源码的时候,我们又怎么知道bind,lambda生成的是啥吗?我是不知道。我想boost::function给了我们一个较为一致的接口来实现这些内容,虽然说实话,在上面例子中我列出来的情况中boost::function比起单纯的使用模板(如例子中一样)甚至要更加复杂,起码你得指明返回值和参数。(熟称函数签名)

我在上面例子中特意用运行时类型识别输出了lambdabind生成的类型,分别是一下类型:

int (__cdecl*)(int,int)

2

class add2

3

class boost::lambda::lambda_functor<class boost::lambda::lambda_functor_base<cl

ss boost::lambda::arithmetic_action<class boost::lambda::plus_action>,class boo

t::tuples::tuple<class boost::lambda::lambda_functor<struct boost::lambda::plac

holder<1> >,class boost::lambda::lambda_functor<struct boost::lambda::placehold

r<2> >,struct boost::tuples::null_type,struct boost::tuples::null_type,struct b

ost::tuples::null_type,struct boost::tuples::null_type,struct boost::tuples::nu

l_type,struct boost::tuples::null_type,struct boost::tuples::null_type,struct b

ost::tuples::null_type> > >

4

class boost::_bi::bind_t<int,int (__cdecl*)(int,int,int),class boost::_bi::list

<class boost::_bi::value<int>,struct boost::arg<1>,struct boost::arg<2> > >

5

 

当我觉得int (*)(int,int)形式的函数指针都觉得复杂的是否。。。怎么样去声明一个个看都看不过来的lambda类型和bind类型啊。。。。。看看同样的用boost::function的例子。

 

#include "stdafx.h"

#include <list>

#include <iostream>

#include <boost/lambda/lambda.hpp>

#include <boost/bind.hpp>

#include <boost/function.hpp>

#include <boost/ref.hpp>

using namespace std;

using namespace boost;

 

 

int add1(int a, int b)

{

    return a + b;

}

 

class add2

{

public:

    int operator()(int lhs, int rhs)

    {

       return lhs + rhs;

    }

};

 

class CAdd

{

public:

    int add3(int a, int b) { return a + b; }

};

 

 

template<typename FUN, typename T>

T fun(FUN function, T lhs, T rhs)

{

    cout <<typeid(function).name() <<endl;

    return function(lhs, rhs);

}

 

int add4(int a, int b, int c)

{

    return a+b+c;

}

 

int fun2(boost::function< int(int,int) > function, int a, int b )

{

    cout <<typeid(function).name() <<endl;

    return function(a,b);

}

 

 

int main()

{

    cout << fun2(add1, 1, 1) <<endl;

    cout << fun2(add2(), 1, 2) <<endl;

    cout << fun2(lambda::_1+lambda::_2, 1, 3) <<endl;

    cout << fun2(bind(add4, 0, _1, _2), 1, 4) <<endl;

 

    system("PAUSE");

}

 

 

还是输出了最后函数中识别出来的类型:

class boost::function<int __cdecl(int,int)>

2

class boost::function<int __cdecl(int,int)>

3

class boost::function<int __cdecl(int,int)>

4

class boost::function<int __cdecl(int,int)>

5

你会看到,当使用了boost::funciton以后,输出的类型得到了完全的统一,输出结果与前一次对比,我简直要用赏心悦目来形容了。特别是,boost::funtion还可以将这些callable(C++中此概念好像不强烈,但是在很多语言中是一个很重要的概念)的东西保存下来,并且以统一的接口调用,这才更加体现了boost::funtion的强大之处,就如我标题所说,将C++中的函数都成为第一类值一样(虽然其实还是不是),并且将callable都统一起来。

例子如下:

#include "stdafx.h"

#include <list>

#include <iostream>

#include <boost/lambda/lambda.hpp>

#include <boost/bind.hpp>

#include <boost/function.hpp>

#include <boost/ref.hpp>

using namespace std;

using namespace boost;

 

 

int add1(int a, int b)

{

    return a + b;

}

 

class add2

{

public:

    int operator()(int lhs, int rhs)

    {

       return lhs + rhs;

    }

};

 

class CAdd

{

public:

    int add3(int a, int b) { return a + b; }

};

 

 

template<typename FUN, typename T>

T fun(FUN function, T lhs, T rhs)

{

    cout <<typeid(function).name() <<endl;

    return function(lhs, rhs);

}

 

int add4(int a, int b, int c)

{

    return a+b+c;

}

 

int fun2(boost::function< int(int,int) > function, int a, int b )

{

    cout <<typeid(function).name() <<endl;

    return function(a,b);

}

 

 

int main()

{

    boost::function< int(int,int) > padd1 = add1;

    boost::function< int(int,int) > padd2 = add2();

    boost::function< int(int,int) > padd3 = lambda::_1+lambda::_2;

    boost::function< int(int,int) > padd4 = bind(add4, 0, _1, _2);

 

    cout << fun2(padd1, 1, 1) <<endl;

    cout << fun2(padd2, 1, 2) <<endl;

    cout << fun2(padd3, 1, 3) <<endl;

    cout << fun2(padd4, 1, 4) <<endl;

 

    system("PAUSE");

}

 

当你发现你能够这样操作C++中的callable类型的时候,你是不是发现C++的语言特性都似乎更加前进一步了?^^起码我是这样发现,甚至有了在Python,lua中将函数做第一类值使用的感觉。

好消息是。。。bind,function都比较有希望进C++09标准^^至于lambda嘛。。。似乎还有点悬。。。虽然BS还是会一如既往的说,一个好的编程语言绝不是一大堆有用特性的堆积,而是能在特定领域出色完成特定任务,但是。。。多一些功能,总比没有好吧,毕竟,人们还可以选择不用,没有特性。。。则只能通过像boost开发者这样的强人们扭曲的实现了,甚至将C++引入了追求高超技巧的歧途,假如一开始这些特性就有的话,人们何必这样做呢。。。。。。话说回来,那些纯C的使用者又该发言了。。。心智包袱。。。。呵呵,我倒是很想去体会一下在纯C情况下真实的开发应该是怎么样组织大规模的程序的,然后好好的体会一下没有这样的心智包袱的好处(虽然读过很多纯C的书籍。。。。但是实际开发中都没有机会用纯C,所以对C的理解其实主要还是停留在C++的层面上,这点颇为遗憾)

 

参考资料:

1.Beyond the C++ Standard Library: An Introduction to Boost

By Björn Karlsson

2. boost.org

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

阅读全文....

google的广告匹配算法其实也挺搞的

google的广告匹配算法其实也挺搞的

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

大家都知道google的广告吧。。。那属于通过匹配你浏览的网页中的关键字提供给你你可能最需要的广告,google的广告一向以此为卖点,或者说是优点。

今天在看一个关于Python的网站,结果google给我匹配出了一个搞笑的广告-_-!一个卖蟒蛇皮的手袋的网站。。。Python handbag。。。。晕,本来截了图了,但是csdn网站照常出了问题,图片不能上传,以后又机会再补吧。

呵呵,计算机的程序的极限还远远没有到。。。。

 

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

阅读全文....

计算机业最振奋也是最残酷的特性就是喜新厌旧

今天从各类网站,辗转跳转,从《梦断代码》跟到《新机器的灵魂》,突然在

《新机器的灵魂》IT业魂在何方?

 

文中,看到了一句话," 计算机业最振奋也是最残酷的特性就是喜新厌旧。",很感叹。。。。呵呵,大家自由想象。。。。。。。。。起码从编程语言上来想。。。此话实在不假,虽然C也坚持了这么多年了。

各类网站,新特性等等,喜新厌旧,无孔不入,不过,就是这个新。。。不也是代表着创新及激情吗?。。一句话,也可以引发人无限的思考。

 

"

但疯狂的节奏下,一些内在的东西是弥久的,甚至是永恒的。毕竟任一行业,其真正的主角都是人,而人恐怕是世界上最难升级的事物。写于22年前的《新机器的灵魂》无疑是一本经得起时间锤打的经典。它讲述了一群忘我工作的电脑技术人员,制造一台新型计算机的动人过程。可以说,本书定义了计算机业整整一个时代的灵魂和精神。尽管业内技术2年一变,人物5年一换,但这个产业的问题和驱动力与10年、20年前相比并无两样,只是不同的公司扮演着不同的角色而已。无论是后来的PC之火,还是互联网浪潮,都没有脱离贯穿这个产业数十年的本质。

"

 

有时看到一些文字真的很感叹。。。。为啥人家水平那么高呢?。。。。。。呵呵,学习了。

阅读全文....

纯YY一下,在The Python Tutorial中,从Guido van Rossum的例子中可以看出他对现在流行的脚本语言perl,tcl,ruby,lua,python的评分

In addition to alternative list implementations, the library also offers other tools such as the bisect module with functions for manipulating sorted lists:

>>> import bisect
>>> scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
>>> bisect.insort(scores, (300, 'ruby'))
>>> scores
[(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
摘自:Python 2.6.1的文档,Brief Tour of the Standard Library – Part II章,Tools for Working with Lists节
呵呵,很明显可以看出Guido van Rossum的意图,以scores来表示含义,然后分别给了perl 100分,tcl 200分, ruby 300分, lua 400分,然后给了其创造的语言python 最高的500分:)
其他的都还能理解。。。。。不过ruby在其心中排在lua之后,实在有点让ruby阵营的人抓狂-_-!呵呵,虽然个人没有学过ruby,仅学过lua。。。。。。
呵呵,纯YY一下,这是偶然从文档中查资料的时候翻出来的:)

阅读全文....

程序员平时都是木讷的,但是谈到计算机或者程序的时候简直就是天才—兼借题发挥,谈谈语言及工具的选择

程序员平时都是木讷的,但是谈到计算机或者程序的时候简直就是天才兼借题发挥,谈谈语言及工具的选择

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

程序员们对各类事物的敏感度可能都不够,但是对于计算机和程序语言的敏感度实在太高,所以,在这个他们赖以为生的领域,他们的聪明才智发挥的是若此的淋漓尽致。

最近看到CSDN上的

语录:101条伟大的计算机编程名言》,觉得很有意思:)

其中有很多,是真的属于程序员才能理解的幽默:

最能让人会心一笑的是61条:

61、我想微软之所以把它叫做.Net,是因为这样它就不会在Unix的目录里显示出来了.(Oktal)

不理解的兄弟。。。。和你解释了也就没有效果了。

 

也有很多的确是属于经验之谈:

32、好的软件的作用是让复杂的东西看起来简单.(Grady Booch,UML创始人之一)

62There is no programming languageno matter how structuredthat will prevent programmers from making bad programs.(Larry Flon)

(这是唯一文章中没有翻译的,不知道为啥漏了,意思是无论结构多好的程序语言都不能阻止程序员写出垃圾程序。)

75、好代码本身就是最好的文档.(Steve McConnell)

 

另外,因为国外对s e x这种事情看的比较普通,所以例子中不乏相关的类比:

70、说Java好就好在运行于多个操作系统之上,就好像说肛 交好就好在不管男女都行.(Alanna)

73、软件就像性事:免费/自由更好.(Linus Torvalds)

 

程序语言是程序员的信仰,其圣战从未停止过:

57、只有两种编程语言:一种是天天挨骂的,另一种是没人用的.(Bjarne Stroustrup,C++之父)

58PHP是不合格的业余爱好者创建的,他们犯做了个小恶;Perl是娴熟而堕落的专家创建的,他们犯了阴险狡诈的大恶.(Jon Ribbens)

 

微软作为世界软件世界的实际霸主,相关的也不少,除了.net那一条,我觉得还比较有意思的是:

18、微软有出了个新版本,Windows XP,据大家说是'有史以来最稳定的Windows', 对我而言, 这就好像是在说芦笋是'有史以来发音最清脆的蔬菜一样' (Dave Barry)

 

调试永远是占用着程序员绝大部分时间:。。。。。

14、我终于明白'向上兼容性'是怎么回事了.这是指我们得保留所有原有错误.(Dennie van Tassel)

84、如果调试是除虫的过程,那么编程就一定是把臭虫放进来的过程.(Edsger W. Dijkstra)

 

为了增加主题的契合度,我还引用一些国内有意思的例子,某年某月,当大牛开始贬低C++的时候,国内程序员突然牵扯到C++,Python上的争吵:

d 发表于2007911 11:59:29  IP:举报

C++还在讨论String的时候.Python已经做好了项目在喝酒了.我也有一句.python在为开发一个操作系统无能为力的时候.C++已经在喝COFI,.

gussing 发表于2007911 12:21:01  IP:举报

是啊,可以喝咖啡,多爽
python
程序员喝了十年咖啡,c程序员熬了十年夜,后来在一次聚会上他们相遇了,python还在喝咖啡,c程序员则买了一艘豪华游艇准备出海旅游。python 程序员一脸兴奋的说:老兄,知道吗,python又出新库了!c程序员也一脸兴奋,说:当然知道,那正是我带领的一个团队开发的。

irplay 发表于2007911 12:45:43  IP:举报

python什么垃圾啊...高不成低不就的语言都要淘汰.

hehe 发表于2007911 13:20:52  IP:举报

gussing 发表于2007-09-11 12:21:00 IP: 220.248.25.*
是啊,可以喝咖啡,多爽

python
程序员喝了十年咖啡,c程序员熬了十年夜,后来在一次聚会上他们相遇了,python还在喝咖啡,c程序员则买了一艘豪华游艇准备出海旅游。python 程序员一脸兴奋的说:老兄,知道吗,python又出新库了!c程序员也一脸兴奋,说:当然知道,那正是我带领的一个团队开发的。
--------------------------------------------
一百个python程序员都在喝咖啡,一百个c程序员中只有一个买了游艇,剩下99个还在加班

笑死 发表于20071228 1:32:01  IP:举报

刚喝完咖啡,忽然客户过来说:"太慢了,我去找人重新开发.我们的合作到此为止啦".

 

 

呵呵,C++程序员对于Python运行速度的攻击,Python程序员对于C++开发效率的攻击都是如此的尖锐并且有思想:)很有意思,我印象深刻,好不容易翻出来啊。。。。。

 

说到圣战:。。。VIMEmacs的圣战被誉为从计算机发明那天就开始,计算机历史上持续最长时间的圣战:)有很多相关资料,这里是一个

EMACS 对 vi:永无止境的圣战

。。。无奈的是。。。我作为靠C++谋生,业余对Python很感兴趣,并且无论在Linux,Windows下都使用着VIM的家伙,几大圣战的讨论我都是被攻击的当事人-_-!(因为攻击者肯定都是全面积覆盖)

其实。。。从使用者的角度来说,没有东西是完美的,但是都存在选择,当年也在EMACSVI中选择,最后我发现我要的仅仅是一个在任何时候都可以使用的方便的文本编辑工具的时候,我选择了VIM,虽然也有被那句很经典的话打动的意思:EMACS的程序员都希望增加一个脚踏板。。。呵呵

当我觉得我需要是一种通用的编程语言,但是却要足够的接近底层的时候,我选择了C++,这个领域我没有其他选择,当我开始网络游戏服务器/客户端开发的时候,我需要一种高效的嵌入式脚本语言(工作需要)我选择了LUA这样的小众语言,再后来,我感觉自己希望加深对Linux/Unix的理解,并且习惯在Shell下工作时,我学习了bash(不知道是用的太少,还是没有理解其精髓,总感觉语法过于扭曲,实际上用bash的时候更喜欢用其兼容csh”(())”语法,特别是当我不当使用,用其实现算法的时候-_-!),再再后来,我希望有一种足够好,足够通用,并且和C/C++能够很好交互的脚本语言时,我选择了Python,它也一直在给我惊喜:)虽然它的速度实在不咋的,但是,当我开始使用Python的时候,速度明显不是我关心的东西了,别忘了。。。作为程序员,我的母语是C++。理解你需要的,做出适当的选择,可能这才是王道。。。。。

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

 

阅读全文....

其实C++比Python更需要lambda语法,可惜没有。。。。

其实C++比Python更需要lambda语法,可惜没有。。。。

write by 九天雁翎(JTianLing) -- www.jtianling.com

讨论新闻组及文件

思路有点混乱,想到哪就写到哪了。

起点是PythonPython的语法大都简单,有人说接近自然语言,但是其实我还是发现了一些不那么通俗易懂的东西,也许是因为还没有形成深刻的Python思维,也许是受C++的熏陶太深吧,其中,Python的函数式编程方式上就有很多地方感觉语法比较不那么容易一眼就看出来。其实想到函数式编程,倒是首先想到了lambda,自此思路混乱。对于将函数作为第一类(first class)值的语言,比如Python,lua中,感觉lambda的作用就不是那么明显,比如Python中,调用lambda的实际需求似乎感觉不算太大,再加上其函数定义的语法本身就足够的简洁,定义一个完整的函数实在也不算什么。作为语法糖的lambda,实在就显得有点甜味不足,虽然也不是说完全没有用。

这里举几个例子:

def add1(a,b):  return a + b

add2 = lambda a,b : a + b

print add1(1,2)
print add2(1,2)

fun = lambda f,a,b : f(a,b)

print fun(lambda a,b : a * b, 3, 4)

print fun(add1, 3, 4)

 

可以看出,对于lambda这样的语句,假如在Python中还有作用的话,那么就是在需要函数作为参数传递的时候了,但是个人还是保持这样的观点,因为python这样的动态类型语言+足够简洁的函数定义语法+函数第一类型值的特点导致实际上lambda不够甜,虽然其可以进一步的简化一些语法。

但是,假如C++中有lambda那就是完全不同的概念了,看看同样的事情吧:

int add(int a, int b)

{

    return a + b;

}

 

template<typename T>

T add1(T lhs, T rhs)

{

    return lhs + rhs;

}

 

template<typename T>

class add2

{

public:

    T operator()(T lhs, T rhs)

    {

       return lhs + rhs;

    }

};

 

template<typename FUN, typename T>

T fun(FUN function, T lhs, T rhs)

{

    return function(lhs, rhs);

}

 

 

int main()

{

    int a = 1;

    int b = 2;

 

    cout << add1(a,b) <<endl;

    cout << fun( ptr_fun(add), 1, 2) <<endl;

    cout << fun( add, 1, 2) <<endl;

    cout << fun( add1<int>, 1, 2) <<endl;

    cout << fun( ptr_fun(add1<int>), 1, 2) <<endl;

    cout << fun(add2<int>(), 1, 2) <<endl;

 

    system("PAUSE");

}

 

可以看到,相对而言C++的函数定义语法,包括使用方式上都会比Python要复杂一些,最主要的复杂性来之于C++赖以生存的根本,强类型,为了达到类型安全又类型无关,引入的模板机制,进一步的复杂化了函数的定义。

最有意思的是,

    cout << fun( add1<int>, 1, 2) <<endl;

    cout << fun( ptr_fun(add1<int>), 1, 2) <<endl;

 

这两种方式,在开启/clr,即开启微软的公共运行时库时会出现异常,我还是在反汇编时发现汇编代码异常才发现原来我在上次调试for_each的时候,为了展示/clr的新添的for each语法而开启了/clr选项,详情可以见《多想追求简洁的极致,但是无奈的学习C++for_each的应用》一文。

/clr选项应该就是将C++加入微软的.net体系,因为没有深入学习过,所以对出现的异常现象无法解释,希望有学过.net的人可以解释一下。

 

另外,这里想说的是,因为C++没有原生的for each语法,所以实际上很多循环不想写的话只能通过for_each算法来模拟,再加上很大一族的算法函数对于函数对象的需求,导致了语法的极大复杂化,使得C++对于lambda语法的需求远远大于Python这样的语言,但是,遗憾的是,C++并没有这样的语法,实际上09标准中好像有人提议过这样的特性,不过不知道通过没有-_-!就我目前所知,否决的可能性要大得多,但是因为没有仔细去查阅资料了,所以不敢肯定,但是很明显TR1中是没的,新出来的g++中新添了很多09标准要出来的特性中也没有包含lambda,似乎我们可能在短时间内(起码下一版标准。。。又要起码十年)是没有机会了。

多想追求简洁的极致,但是无奈的学习C++for_each的应用》一文,为了能够简单的让c++模拟出for each语法的调用,我甚至都不得不将很多循环进行两次。。。。。。详细情况见前文,就知道假如能有lambda,那么我们就能够省下多少函数的定义了。这里我就不在重复原文中的例子了。

事实上,还是如同boost::foreach库一样,虽然没有这样的语法,但是C++界的牛人们绝不允许这样的情况发生,他们想要什么,就会有什么,如同当年上帝。。。。要有光,于是就这么有了。。。。。看看boostlambda库能给我们带来什么。

#include <list>

#include <iostream>

#include <boost/foreach.hpp>

#include <boost/lambda/lambda.hpp>

using namespace std;

using namespace boost::lambda;

 

template<typename T>

void printInt(T i)

{

    cout <<i <<endl;

}

 

int main()

{

    int a[5] = {1,2,3,4,5};

    list<int> l(a, a+5);

 

    for(list<int>::const_iterator lit = l.begin(); lit != l.end(); ++lit)

    {

       cout <<*lit <<endl;

    }

 

    // 同样是需要输出

    for_each(l.begin(), l.end(), ptr_fun(printInt<int>));

 

    BOOST_FOREACH( int i, l)

    {

       cout <<i <<endl;

    }

 

    // 因为Andrew koenig发明的操纵器的特性,boost::lambda无法支持

    for_each(l.begin(), l.end(), cout <<_1 <<'/n');

 

    system("PAUSE");

}

 

一条语句,省下了很多工作,只当有这样简洁的实现方式时,我们才能够大规模的利用for_each去代替无聊的循环,非常高频率出现的循环,并且,虽然说Boost实现的lambda语法和一般而言有点区别,但是还算是比较容易理解,在没有for each语法前,我最希望有的可能就是lambda语法了,我希望利用算法来代替循环,但是没有lambda前,那样做可能比不费脑子的写个循环更加费力不讨好,甚至流于语言特性的滥用。还是在多想追求简洁的极致,但是无奈的学习C++for_each的应用》一文中,后面的例子就可以看出在没有这些语法特性时,我希望实现一个那么简单的功能所付出的代价。

 

这里为了方便,还是拷贝一次原文中的例子:

Python中:

def add(a,b):
    
return a + b

l = [1,2,3,4,5]
for i in l:
    
print add(i,1)

 

无非就是在每个输出的函数中调用一个函数,没有任何值的一提的地方,是个人就能看懂。

C++需要实现成下面这个样子:

#include <list>

#include <iostream>

#include <algorithm>

#include <functional>

using namespace std;

 

template <typename T>

class Add : public binary_function<T, T, void>

{

public:

    void operator()(const T& ai, const T& aj) const

    {

       cout <<(ai + aj) <<endl;

    }

 

};

 

int main()

{

    int a[5] = {1,2,3,4,5};

    list<int> l(a, a+5);

 

    for_each(l.begin(), l.end(), bind2nd(Add<int>(), 1));

 

    system("PAUSE");

}

 

这是在没有lambdafor each语法时无奈的实现。

假如有lambda语法的话,那么感觉就不同了。

#include <list>

#include <iostream>

#include <boost/foreach.hpp>

#include <boost/lambda/lambda.hpp>

using namespace std;

using namespace boost::lambda;

 

int main()

{

    int a[5] = {1,2,3,4,5};

    list<int> l(a, a+5);

 

    for(list<int>::const_iterator lit = l.begin(); lit != l.end(); ++lit)

    {

       cout <<*lit + 1 <<endl;

    }

 

    for_each(l.begin(), l.end(), cout <<_1+1 <<'/n');

 

    system("PAUSE");

}

 

还是几乎与原有的不+1输出实现同样的简洁,这就是lambda带来的特性,在没有这些特性的时候,我们就只能老老实实的按iterator的方式写了,在C++苦海中挣扎的兄弟们啊。。。。(特别是像我这样,工作中甚至连boost都不能用的人啊。。。。)继续等待吧。。。。等09标准出来。。。等VS202X版本的VS出来后,估计差不多才可能实现新的C++ 09标准,然后我们也许能够稍微减轻点工作量,以后能够写成大概是

    for(auto lit = l.begin(); lit != l.end(); ++lit)

    {

       cout <<*lit + 1 <<endl;

    }

这个样子。。。。。。。。。。。。。。阿门。

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

阅读全文....

程序员手中的利器(1)--工欲善其事必先利其器

程序员手中的利器(1--工欲善其事必先利其器

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

不要和讲述工具不是最重要的理论,我知道,并且就是一直被其所害。这里我得说明一下,在最开始学习某种编程语言的时候的确应该主要关注与语言特性的学习而不是被一些复杂的IDE所分心,但是当真的成为一个程序员后,当渐渐的一种语言对你来说也就是一种工具的时候,那些IDE一样的工具,也应该值得你花同样的实现去学习!

这里主要也就是列出平时我用到的工具,自从刚开始工作的时候被总监一句“工欲善其事必先利其器”的话警醒,从以前学习时那种语言才是最重要的,IDE什么都仅仅是个工具而已的思想中走出来。我开始有意识的花功夫去学习那些以前我很不屑去学习的工具。事实上,作为一个计算机面前工作的人员(其实不仅仅是程序员),熟悉好你手中的每一个工具,那都是节省你时间的法宝,同时,节省的是你的生命。(虽然说主要是提高你的工作效率。)并且,因为好的工具可能最主要关注的是熟练使用者的使用效率,所以往往都不那么“初学者友好”,使很多人望而却步,但是在我逐渐的去熟悉了这样一些工具以后,我总是会发现,我用来学习一个好工具的时间,到头来总是会远远的少于用一个好工具为我节省的时候,所以,一个好工具几乎总是值得投入足够的精力去学习的,毕竟,学会了一个好工具会一直受用!这点,我深有体会!

 

作为一个列表,得有个分类和顺序,先列表,然后再讲理由吧。

文本编辑工具:特别推荐vim! Windows/Linux/X多平台通用

辅助:Ultra Edit:Windows下偶尔用用

IDE: Visual Studio 2005(VS2005)  Windows下的C++开发环境

Eclipse: Windows/X 多种语言跨平台综合开发环境

代码控制:Visual Source Safe(VSS)Windos下与VS2005结合使用

SVN,CVSLinux下及开源需要

调试:gdb linux/X 需要

pydb: Linux Python语句调试

bashdb: Linux bash 语言调试

工程控制:GNU makeLinux

编译器: gccLinux

UML IBM Rational rosewindows,最强大的UML工具,毋庸置疑

测试工具:Compuware DevPartner windows下用于检测代码错误或者内存泄露

备选工具:Visual Studio Team版自带C++代码分析工具

Profiler: AQTimeWindows下代码运行时间分析工具

8.    资源管理器:Total CommandWindows

9.    比较工具:Beyond compareWindows

10. 16进制编辑工具:WinHex, 我认为Windows下最佳的16进制编辑工具

HViewWindows,同样优秀,除了界面有点老,支持对PE文件格式的分析及内带反汇编功能

11. 反汇编静态分析:IDA ProWindows/Linux,基本上,有这一个就够了,w32dm什么的我好像没有需要过。

12. 反汇编动态调试工具:OllyDbg, Windows 的确比较容易上手,功能也很强大

       SoftIce,Windows ring0调试工具

13. SSH客户端: WinSCP,图形界面,主要用于远程登陆Linux服务器做文件管理用

       Putty 个人感觉不错的远程控制台

以上Linux都是特指Linux下的控制台,X才是指Linux下的图形界面环境

 

从此列表中可以看出,我的主要工作环境还是Windows,这是工作需要,但是由于工作中服务器需要跑在Linux下加上个人爱好,所以也掌握了一些Linux下的工具,但是由于我主要是通过Putty登陆Linux服务器工作,所以对于X下的工具了解不多。再加上个人爱好和前段时间反外挂的工作,所以还了解了一些反汇编工具的使用。

再说一次的是,这个列表仅仅是我个人平时使用的软件列表,并不代表人人都喜欢,或者世界最高水平。。。。。。-_-!

 

以下为逐条分析,因为精力有限,可能主要讲一些我个人的看法,至于大家都知道的东西讲太多也没有意义,并且以精简为主,不然的话光是讲vim好用的插件都可以用一天的时间来写。另外。。。本来准备写一篇小文章来总结一下自己所用工具的,但是发现这个话题一旦开始,就很难收尾了。。。。结果。。。又是一个系列。

BTW:万恶的ASP.net,明显和FireFox不兼容,我在FF中发表的文章在IE中都看不到,虽然可以参考原则,IE不能看的空文章用FF浏览。。。但是,这些文字也看不到吧。。。还是重发一下吧 

 

write by 九天雁翎(JTianLing) -- www.jtianling.com

 

阅读全文....