??xml version="1.0" encoding="utf-8" standalone="yes"?>少妇人妻88久久中文字幕,国产日韩久久久精品影院首页 ,久久人人爽人人爽人人AV东京热http://m.shnenglu.com/shifan3/category/3013.htmlEverything is template...zh-cnTue, 20 May 2008 22:42:04 GMTTue, 20 May 2008 22:42:04 GMT60意不是凡h能领会的Q?Q?/title><link>http://m.shnenglu.com/shifan3/archive/2007/11/02/35767.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Fri, 02 Nov 2007 10:05:00 GMT</pubDate><guid>http://m.shnenglu.com/shifan3/archive/2007/11/02/35767.html</guid><wfw:comment>http://m.shnenglu.com/shifan3/comments/35767.html</wfw:comment><comments>http://m.shnenglu.com/shifan3/archive/2007/11/02/35767.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://m.shnenglu.com/shifan3/comments/commentRss/35767.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/shifan3/services/trackbacks/35767.html</trackback:ping><description><![CDATA[转蝲自神的blog<br><a >http://blog.csdn.net/vbvan/archive/2007/10/30/1857134.aspx</a><br><br><span style="FONT-SIZE: 24pt"><font color=#000080>Flexible C++</font><br></span><br>C++是一门非常灵zȝ语言Q只要充分发挥你的想象, 再普通的东西都能玩出新花?br><br>1?~1000求和<br>循环Q递归Q再单不q的题目了。但是如果不允许你用判断语句呢?<br>如果你熟悉switch的内部实玎ͼ那么你很Ҏ惛_使用函数指针数组?br> <p align=left><span>#include</span><span> <span><cstdio></span></span></p> <p><span>typedef</span><span> <span>int</span> (*<span>fun</span>)(<span>int</span>);<br></span><span>int</span><span> <span>f1</span>(<span>int</span> <span>i</span>) {<span>return</span> 0;}</span><br><span>int</span><span> <span>f2</span>(<span>int</span> <span>i</span>) {<span>fun</span> <span>f</span>[2]={<span>f1</span>,<span>f2</span>}; <span>return</span> <span>i</span>+<span>f</span>[!!<span>i</span>](<span>i</span>-1);}</span><br><span>int</span><span> <span>main</span>()<br>{<br><span>     </span><span>printf</span>(<span>"%d\n"</span>,<span>f2</span>(1000));<br>}</span></p> 2、输?,2,...,100,99,...,2,1<br>如果同样不让你用判断语句呢?你仍然可以用函数指针数l:<br> <p align=left><span>#include</span><span> <span><cstdio></span></span></p> <p align=left><span>typedef</span><span> <span>void</span> (*<span>fun</span>)(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>); <br></span><span>void</span><span> <span>f1</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>);</span><br><span>void</span><span> <span>f2</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>);</span><br><span>void</span><span> <span>f3</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>);</span></p> <p align=left><span>void</span><span> <span>f1</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>)<br>{<br><span>     </span><span>fun</span> <span>f</span>[2]={<span>f1</span>,<span>f2</span>};</span></p> <p align=left><span><span>     </span><span>printf</span>(<span>"%d\n"</span>,<span>i</span>);<br><span>     </span><span>f</span>[<span>i</span>+1==<span>n</span>](<span>i</span>+1,<span>n</span>);<br>}</span><br><span>void</span><span> <span>f2</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>)<br>{<br><span>     </span><span>fun</span> <span>f</span>[2]={<span>f2</span>,<span>f3</span>};<br><span>     </span><span>printf</span>(<span>"%d\n"</span>,<span>i</span>);<br><span>     </span><span>f</span>[<span>i</span>==1](<span>i</span>-1,<span>n</span>);<br>}</span><br><span>void</span><span> <span>f3</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>) {}</span></p> <p><span>int</span><span> <span>main</span>()<br>{<br><span>     </span><span>f1</span>(1,100);<br>}</span></p> 不过我们有更z的Ҏ?br>短\法和逗号表达式粉墨登ZQ一行搞定~<br> <p align=left><span>#include</span><span> <span><cstdio></span></span></p> <p align=left><span>void</span><span> <span>f</span>(<span>int</span> <span>i</span>,<span>int</span> <span>n</span>)<br>{<br><span>     </span><span>printf</span>(<span>"%d\n"</span>,<span>i</span>),(<span>i</span><<span>n</span>)&&(<span>f</span>(<span>i</span>+1,<span>n</span>),<span>printf</span>(<span>"%d\n"</span>,<span>i</span>));<br>}</span></p> <p><span>int</span><span> <span>main</span>()<br>{<br><span>     </span><span>f</span>(1,100);<br>}</span></p> <img src ="http://m.shnenglu.com/shifan3/aggbug/35767.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/shifan3/" target="_blank">shifan3</a> 2007-11-02 18:05 <a href="http://m.shnenglu.com/shifan3/archive/2007/11/02/35767.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]用户态非抢占式线E库实现http://m.shnenglu.com/shifan3/archive/2007/03/16/19968.htmlshifan3shifan3Fri, 16 Mar 2007 08:33:00 GMThttp://m.shnenglu.com/shifan3/archive/2007/03/16/19968.htmlhttp://m.shnenglu.com/shifan3/comments/19968.htmlhttp://m.shnenglu.com/shifan3/archive/2007/03/16/19968.html#Feedback4http://m.shnenglu.com/shifan3/comments/commentRss/19968.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/19968.html阅读全文

shifan3 2007-03-16 16:33 发表评论
]]>
[yc]垃圾回收QC++资源理杂谈http://m.shnenglu.com/shifan3/archive/2007/01/24/17963.htmlshifan3shifan3Wed, 24 Jan 2007 10:02:00 GMThttp://m.shnenglu.com/shifan3/archive/2007/01/24/17963.htmlhttp://m.shnenglu.com/shifan3/comments/17963.htmlhttp://m.shnenglu.com/shifan3/archive/2007/01/24/17963.html#Feedback3http://m.shnenglu.com/shifan3/comments/commentRss/17963.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/17963.html说到 C/C++ 的资源管理,Zh都会头痛半天。自?/span> C++0x Q就?/span> C++09 了)标准漏出风声之后Q?/span> C++ 标准是否会引入自动垃圑֛收机制就成ؓ了众?/span> C++ 爱好者谈论的话题。但是实际上Q在 C++ 标准的探索上Q垃圑֛收一直处在一个十分低下的C。造成其这一处境的原因很多,也很复杂。我们来看看站在 C++ E序员的角度上看Q资源管理机制现在所面的局ѝ?/span>

从系l结构上来讲Q?/span> C/C++ 支持 3 U内存管理方式,Z栈的自动理Q基于堆的动态管理,和基于全局区的静态管理。由?/span> RAII 的理念,对于 C++ 来说Q内存管理和其他资源理本质上没有区别。因此对于资源而言Q也p然的拥有q样 3 U管理方式?/span>

首先要的介绍一?/span> RAII ?/span> RAII 的全U是 Resource Acquisition Is initialization 。这个思想的基本手法是对于一U想要用的资源Qؓ其书写一?/span> guard c,在该cȝ构造函数里q行资源的请求,在析构函数里q行资源的释放。例如假设我们想理一个互斥锁Q可能的方式是:

struct  lock_guard
{
        lock_guard()
{ lock ();}
        
~ lock_guard() {unlock();}
}
;


     此后Q对q个对象使用什么内存管理方式,也就{h于对q个互斥锁用什么内存管理方式?/p>

         借助?/span> RAII Q以后我们可以只讨论内存资源的管理方式,其它资源的管理方式可以?/span> RAII 来同L实现。现在我们已l很自然的获得了资源理?/span> 3 U方式:Z堆的动态方式、基于栈的自动方式和全局。值得一提的是,q?/span> 3 U方式中比较不容易出错的后两U实际上可以解决大部分的资源理需求。因为绝大部分资源,都属于获?/span> - 使用 - 释放型的Q例如很多同步对象,文g锁, WinGDI 里的许多 GDI 对象。我们缺乏管理的Q只有那些一ơ获得,多个环境拥有Qƈ且只能有一ơ释攄数资源?/span>

         回到内存模型来看Q有一点让我们无法内存与其它资源{同Q反q来Q把其它资源和内存等同却是可以的Q,那就是@环引用?/span> A 内存可以持有指向 B 内存的引用, B 内存也可以反q来持有 A 内存的引用。@环引用导致内存管理不可以?#8220;是否有指向该内存的引?#8221;来区分一块内存是否可以回收。从而׃一个绝佳的理手段。但是在没有循环引用的场合下Q我们还是有非常z高效的理Ҏ的。那是引用计数?/span>

         引用计数是在没有循环引用场合下进行内存管理的l佳手段Q它h轻量、高效、即时、可控的优点。而且?/span> C++ 里,引用计数已经非常成熟Q只需要?/span> boost.shared_ptr 或者其它非官方的引用计数指针库可以了Q而且据悉 C++09 很可能把 boost.shared_ptr U_标准库。引用计数的原则是,如果一个对象没有别的指针或引用来指向它Q那么这个对象就是可以释攄。具体的手法有大把大把的资料可以查阅Q这里就不详l说明了。引用计数通常可以处理哪些场合的资源管理问题呢Q首先,对于单方向的资源理Q也是多个 A 的实体拥?/span> 1 ?/span> B Q然?/span> B q不会反q来依赖?/span> A Q例如多个对象共享一个日志)Q引用计数是非常合适的。其ơ,对于拥有 - 反作用的场合Q也是 1 个或多个 A 的实体拥?/span> 1 个或多个 B Q?/span> B 也拥有这?/span> A 的实体的引用Q但?/span> B 的生存期仍然军_?/span> A 的生存期Q例如父H口拥有若干子窗口,子窗口也h parent 指针指向父窗口,但是子窗口的生存期决定于父窗口的生存期)Q这个时?/span> A 可以?/span> B 使用引用计数指针Q?/span> B 可以?/span> A 使用原生的普通指针,同样的可以很好的解决问题?/span>

         现在所剩下的,只有生存期的@环依赖了。如?/span> AB 互相持有Ҏ的引用,而且 AB 互相的存在都依赖于对方,q样引用计数无法解决了。但是如果仔l想一下就会发玎ͼq种情况?/span> C++ 里几乎不可能存在。生存期循环依赖只有 2 U后果,要么 A ?/span> B 的析构函数里互相析构Q当然就挂了Q,要么互相都不析构Q当然就泄露了)。而这两种都是在正常编E中不会出现的情c所以如果即使仅仅用引用计敎ͼ我们也可以解军_乎所有的资源理问题?/span>

现在q剩下那么一丁点极少出现的不能处理的情况Q我们可以用更加复杂的 gc 来实现。可惜的是,实现一?/span> gc 所要耗费的精力实在太大,而且几乎不可避免的要成ؓ侵入式的库。所以有点得不偿失。而且 gc 通常会生更多的毛病Q?/span>

1Q?/font>               你无法却知对象析构的具体旉Q从而无法真正知道媄响程序性能的瓶颈在什么地斏V?/span>

2Q?/font>               gc 都們֐于大量的使用内存Q直到内存不够的时候再q行清理Q这样会DE序的内存用量严重颠,q且产生大量的换c?/span>

3Q?/font>               q度的依赖于 gc 会ɽE序员大量的把可以由之前提到的各U方法来处理的资源交l?/span> gc 来处理,无故的加重了 gc 的负担?/span>

4Q?/font>               gc 的管理方法和 C++ 的析构函数有可能产生语义上的冲突?/span>

q就是ؓ什?/span> C++ 标准对垃圑֛收的态度如此恶劣的原因?/span>

 

我们现在回过头来?/span> Java/C# q样的内|?/span> gc 的语a。这L语言׃使用?/span> gc Q就不可避免的放弃了析构函数。ؓ什?/span> gc 会和析构函数产生冲突呢?一?/span> gc 一般会希望在进行垃圑֛收的时候,整个q程是一个原子的Q但析构函数会破坏这一点,在释攑ֆ存的时候如果还要执行代码,那么隑օ会对整个 gc 环境产生破坏性的影响。由于没有析构函敎ͼq些语言׃可能做到 RAII Q也是_它们?/span> gc 所能够理的,也就仅仅只有内存而已了。对于其他资源, Java {就必须手动释放。虽?/span> C# 提供?/span> with 关键字来~解q一问题Q但仍然无法d的解冟?/span>

q有什么麻烦呢Q之前说的那 4 点全部都有。虽?/span> JVM 的速度在不断的提高Q但是内存用这一点却完全没有发展Q不能不说是 gc 说导致。它所带来了什么好处呢Q是内存理的自动化Q而不是资源管理的自动化?/span>

 

所以说 C++ q不是世人所惌的那样需?/span> gc Q?/span> C++ 本n已l提供了_强大的资源管理能力。基于栈的自动管理,或者用引用计敎ͼ几乎可以辑ֈ?/span> gc 同样的覆盖面Q而且没有 gc 的那些问题, RAII 使得 C++ 在管理非内存资源的时候还更加有优势,Z么不使用呢?

 

ps. 设计一个非官方?/span> gc 库还是可以的。但是毕竟不会成Z了?/span>



shifan3 2007-01-24 18:02 发表评论
]]>
[yc]详解linkhttp://m.shnenglu.com/shifan3/archive/2007/01/05/17325.htmlshifan3shifan3Fri, 05 Jan 2007 08:03:00 GMThttp://m.shnenglu.com/shifan3/archive/2007/01/05/17325.htmlhttp://m.shnenglu.com/shifan3/comments/17325.htmlhttp://m.shnenglu.com/shifan3/archive/2007/01/05/17325.html#Feedback4http://m.shnenglu.com/shifan3/comments/commentRss/17325.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/17325.html有些人写C/C++(以下假定为C++)E序Q对unresolved external link或者duplicated external simbol的错误信息不知所措(因ؓq样的错误信息不能定位到某一行)。或者对语言的一些部分不知道Z么要Q或者不要)q样那样设计。了解本文之后,或许会有一些答案?br>    首先看看我们是如何写一个程序的。如果你在用某UIDEQVisual StudioQElicpseQDev C++{)Q你可能不会发现E序是如何组lv来的Q很多h因此而反对初学者用IDEQ。因Z用IDEQ你所做的事情Q就是在一个项目里新徏一pd?cpp?h文gQ编写好之后在菜单里点击“~译”Q就万事大吉了。但其实以前Q程序员写程序不是这L。他们首先要打开一个编辑器Q像~写文本文g一L写好代码Q然后在命o行下?br>    cc 1.cpp -o 1.o
    cc 2.cpp -o 2.o
    cc 3.cpp -o 3.o
q里cc代表某个C/C++~译器,后面紧跟着要编译的cpp文gQƈ且以-o指定要输出的文gQ请原谅我没有用Q何一个流行编译器作ؓ例子Q。这样当前目录下׃出现Q?br>    1.o 2.o 3.o
最后,E序员还要键?br>    link 1.o 2.o 3.o -o a.out
来生成最l的可执行文件a.out。现在的IDEQ其实也同样늅着q个步骤Q只不过把一切都自动化了?br>    让我们来分析上面的过E,看看能发C么?br>    首先Q对源代码进行编译,是对各个cpp文g单独q行的。对于每一ơ编译,如果排除在cpp文g里include别的cpp文g的情况(q是C++代码~写中极光误的写法Q,那么~译器仅仅知道当前要~译的那一个cpp文gQ对其他的cpp文g的存在完全不知情?br>    其次Q每个cpp文g~译后,产生?o文gQ要被一个链接器(link)所dQ才能最l生成可执行文g?br>    好了Q有了这些感性认识之后,让我们来看看C/C++E序是如何组l的?br>    
    首先要知道一些概念:
    ~译Q编译器Ҏ代码q行~译Q是以文本形式存在的源代码译为机器语a形式的目标文件的q程?br>    ~译单元Q对于C++来说Q每一个cpp文g是一个编译单元。从之前的编译过E的演示可以看出Q各个编译单元之间是互相不可知的?br>    目标文gQ由~译所生成的文Ӟ以机器码的Ş式包含了~译单元里所有的代码和数据,以及一些其他的信息?br>    
    下面我们具体看看~译的过E。我们蟩q语法分析等Q直接来到目标文件的生成。假设我们有一?.cpp文g
     int n = 1;

    void f()
     {
        ++n;
    }

    它编译出来的目标文g1.o׃有一个区域(假定名称?q制D)Q包含了以上数据Q函敎ͼ其中有n, fQ以文g偏移量的形式l出很可能就是:
    偏移?nbsp;   内容    长度
    0x000    n    4
    0x004    f     ??
    注意Q这仅仅是猜,不代表目标文件的真实布局。目标文件的各个数据不一定连l,也不一定按照这个顺序,当然也不一定从0x000开始?br>    现在我们看看?x004开始f函数的内容(?x86q_下的猜测Q:
    0x004 inc DWORD PTR [0x000]
    0x00? ret
    注意n++已经被翻译ؓQinc DWORD PTR [0x000]Q也是把本单元0x000位置上的一个DWORD(4字节)??br>    
    下面如果有另一?.cppQ如?br>    extern int n;
    void g()
    {
        ++n;
    }
    那么它的目标文g2.o?q制D就应该?br>    偏移?nbsp;   内容    长度
    0x000    g     ??
    Z么这里没有n的空_也就是n的定义)Q因为n被声明ؓexternQ表明n的定义在别的~译单元里。别忘了~译的时候是不可能知道别的编译单元的情况的,故编译器不知道nI竟在何处,所以这个时候g的二q制代码里没有办法填写inc DWORD PTR [???]中的Q?Q部分。怎么办呢Q这个工作就只能交给后来的链接器d理。ؓ了让链接器知道哪些地方的地址是没有填好的Q所以目标文件还要有一?#8220;未解决符可”Q也是unresolved symbol table. 同样,提供n的定义的目标文g(也就?.o)也要提供一?#8220;导出W号?#8221;Qexport symbol table, 来告诉链接器自己可以提供哪些地址?br>    让我们理一下思\Q现在我们知道,每一个目标文Ӟ除了拥有自己的数据和二进制代码之外,q要臛_提供2个表Q未解决W号表和导出W号表,分别告诉链接器自己需要什么和能够提供什么。下面的问题是,如何?个表之间建立对应关系。这里就有一个新的概念:W号。在C/C++中,每一个变量和函数都有自己的符受例如变量n的符号就?#8220;n”。函数的W号要更加复杂,它需要结合函数名及其参数和调用惯例等Q得C个唯一的字W串。f的符号可能就?_f"Q根据不同编译器可以有变化)?br>    所以,1.o的导出符可是
    W号    地址
    n    0x000
    _f    0x004
    而未解决W号表ؓI?br>    2.o的导出符可?br>    W号    地址
    _g    0x000
    未解决符可?br>    W号    地址    
    n    0x001    
    q里0x001Z0x000开始的inc DWORD PTR [???]的二q制~码中存???的v始地址(q里假设inc的机器码的第2Q?字节+1的绝对地址Q需要知道确切情况可查手?。这个表告诉链接器,在本~译单元0x001的位|上有一个地址Q该地址g明,但是hW号n?br>    链接的时候,链接器在2.o里发C未解决符号nQ那么在查找所有编译单元的时候,?.o中发C导出W号nQ那么链接器׃n的地址0x000填写?.o?x001的位|上?br>    “打住”Q可能你׃跛_来指责我了。如果这样做得话Q岂不是g的内容就会变成inc DWORD PTR [0x000]Q按照之前的理解Q这是将本单元的0x000地址?字节?Q而不是将1.o的对应位|加1。是的,因ؓ每个~译单元的地址都是?开始的Q所以最l拼接v来的时候地址会重复。所以链接器会在拼接的时候对各个单元的地址q行调整。这个例子中Q假?.o?x00000000地址被定位在可执行文件的0x00001000上,?.o?x00000000地址被定位在可执行文件的0x00002000上,那么实际上对链接器来_1.o的导出符可其实
    W号    地址
    n    0x000 + 0x2000
    _f    0x004 + 0x2000
    而未解决W号表ؓI?br>    2.o的导出符可?br>    W号    地址
    _g    0x000 + 0x1000
    未解决符可?br>    W号    地址            
    n    0x001 + 0x1000
所以最lg的代码会变ؓinc DWORD PTR [0x000 + 0x2000]?br>    最后还有一个漏z,既然最后n的地址变ؓ0x2000了,那么以前f的代码inc DWORD PTR [0x000]是错误的了。所以目标文件ؓ此还要提供一个表Q叫做地址重定向表address redirect table?br>    对于1.o来说Q它的重定向表ؓ
    地址
    0x005
    q个表不需要符P当链接器处理q个表的时候,发现地址?x005的位|上有一个地址需要重定向Q那么直接在?x005开始的4个字节上加上0x2000可以了?br>    让我们ȝ一下:~译器把一个cpp~译为目标文件的时候,除了要在目标文g里写入cpp里包含的数据和代码,q要臛_提供3个表Q未解决W号表,导出W号表和地址重定向表?br>    未解决符可提供了所有在该编译单元里引用但是定义q不在本~译单元里的W号及其出现的地址?br>    导出W号表提供了本编译单元具有定义,q且愿意提供l其他编译单元用的W号及其地址?br>    地址重定向表提供了本~译单元所有对自n地址的引用的记录?br>    链接器进行链接的时候,首先军_各个目标文g在最l可执行文g里的位置。然后访问所有目标文件的地址重定向表Q对其中记录的地址q行重定向(卛_上该~译单元实际在可执行文g里的起始地址Q。然后遍历所有目标文件的未解决符可Qƈ且在所有的导出W号表里查找匚w的符Pq在未解决符可中所记录的位|上填写实际的地址Q也要加上拥有该W号定义的编译单元实际在可执行文仉的v始地址Q。最后把所有的目标文g的内容写在各自的位置上,再作一些别的工作,一个可执行文g出炉了?br>    最llink 1.o 2.o .... 所生成的可执行文g大概?br>    0x00000000  ????Q别的一些信息)
    ....
    0x00001000  inc DWORD PTR [0x00002000]              //q里?.o的开始,也就是g的定?br>    0x00001005  ret                                  //假设inc?个字节,q里是g的结?br>    ....
    0x00002000  0x00000001                           //q里?.o的开始,也是n的定义(初始化ؓ1Q?br>    0x00002004  inc DWORD PTR [0x00002000]         //q里是f的开?br>    0x00002009  ret                                  //假设inc?个字节,q里是f的结?br>    ...
    ...
    实际链接的时候更为复杂,因ؓ实际的目标文仉把数据/代码分ؓ好几个区Q重定向{要按区q行Q但原理是一L?br>

    
    现在我们可以来看看几个经典的链接错误了:
    unresolved external link..
    q个很显Ӟ是链接器发现一个未解决W号Q但是在导出W号表里没有扑ֈ对应的項?br>    解决Ҏ么,当然是在某个编译单元里提供q个W号的定义就行了。(注意Q这个符号可以是一个变量,也可以是一个函敎ͼQ也可以看看是不是有什么该链接的文件没有链?br>    duplicated external simbols...
    q个则是导出W号表里出现了重复项Q因此链接器无法定应该使用哪一个。这可能是用了重复的名Uͼ也可能有别的原因?br>

    我们再来看看C/C++语言里针对这一些而提供的Ҏ:
    extern:q是告诉~译器,q个W号在别的编译单元里定义Q也是要把q个W号攑ֈ未解决符可里去。(外部链接Q?br>    
    static:如果该关键字位于全局函数或者变量的声明的前面,表明该编译单元不导出q个函数Q变量的W号。因此无法在别的~译单元里用。(内部链接Q。如果是static局部变量,则该变量的存储方式和全局变量一P但是仍然不导出符受?br>    
    默认链接属性:对于函数和变量,模认外部链接Q对于const变量Q默认内部链接。(可以通过dextern和static改变链接属性)

    外部链接的利弊:外部链接的符P可以在整个程序范围内使用Q因为导ZW号Q。但是同时要求其他的~译单元不能导出相同的符P不然是duplicated external simbols)

    内部链接的利弊:内部链接的符P不能在别的编译单元内使用。但是不同的~译单元可以拥有同样名称的内部链接符受?br>
    Z么头文g里一般只可以有声明不能有定义Q头文g可以被多个编译单元包含,如果头文仉有定义,那么每个包含q个头文件的~译单元都会对同一个符可行定义,如果该符号ؓ外部链接Q则会导致duplicated external simbols。因此如果头文g里要定义Q必M证定义的W号只能h内部链接?br>
    Z么常量默认ؓ内部链接Q而变量不是:
        q就是ؓ了能够在头文仉如const int n = 0q样的定义常量。由于常量是只读的,因此即每个~译单元都拥有一份定义也没有关系。如果一个定义于头文仉的变量拥有内部链接,那么如果出现多个~译单元都定义该变量Q则其中一个编译单元对该变量进行修改,不会影响其他单元的同一变量Q会产生意想不到的后果?br>
    Z么函数默认是外部链接Q?br>        虽然函数是只ȝQ但是和变量不同Q函数在代码~写的时候非常容易变化,如果函数默认h内部链接Q则Z会們֐于把函数定义在头文g里,那么一旦函数被修改Q所有包含了该头文g的编译单元都要被重新~译。另外,函数里定义的静态局部变量也被定义在头文g里?br>
    Z么类的静态变量不可以地初始化:所谓就地初始化是cM于这L情况Q?br>        class A
        {
            static char msg[] = "aha";
        };
不允许这样做得原因是Q由于class的声明通常是在头文仉Q如果允许这样做Q其实就相当于在头文仉定义了一个非const变量?br>
    在C++里,头文件定义一个const对象会怎么P
        一般不会怎么Pq个和C里的在头文g里定义const int一P每一个包含了q个头文件的~译单元都会定义q个对象。但׃该对象是const的,所以没什么媄响。但是:?U情况可能破坏这个局面:
        1。如果涉及到对这个const对象取地址q且依赖于这个地址的唯一性,那么在不同的~译单元里,取到的地址可以不同。(但一般很这么做Q?br>        2。如果这个对象具有mutable的变量,某个~译单元对其q行修改Q则同样不会影响到别的编译单元?br>
    Z么类的静态常量也不可以就地初始化Q?br>        因ؓq相当于在头文g里定义了const对象。作Z外,int/char{可以进行就地初始化Q是因ؓq些变量可以直接被优化ؓ立即敎ͼ和宏一栗?br>
    内联函数Q?br>        C++里的内联函数׃cM于一个宏Q因此不存在链接属性问题?br>
    Z么公׃用的内联函数要定义于头文仉Q?br>        因ؓ~译时编译单元之间互怸知道Q如果内联函数被定义?cpp文g中,~译其他使用该函数的~译单元的时候没有办法找到函数的定义Q因此无法对函数q行展开。所以说如果内联函数定义?cpp文g里,那么只有这个cpp文g可以是用q个函数?br>
    头文仉内联函数被拒l会怎样Q?br>        如果定义于头文g里的内联函数被拒l,那么~译器会自动在每个包含了该头文g的编译单元里定义q个函数q且不导出符受?br>
    如果被拒l的内联函数里定义了静态局部变量,q个变量会被定义于何处:
        早期的编译器会在每个~译单元里定义一个,q因此生错误的l果Q较新的~译器会解决q个问题Q手D|知?br>
    Z么export关键字没人实玎ͼ
        export要求~译器跨~译单元查找函数定义Q得编译器实现非常困难?br>



  ~译和静态链接就分析到这里,我会带着动态链接和load的详解杀回来








shifan3 2007-01-05 16:03 发表评论
]]>
[yc]ȝ一下C++的名U查N?/title><link>http://m.shnenglu.com/shifan3/archive/2006/12/27/16902.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Wed, 27 Dec 2006 03:04:00 GMT</pubDate><guid>http://m.shnenglu.com/shifan3/archive/2006/12/27/16902.html</guid><wfw:comment>http://m.shnenglu.com/shifan3/comments/16902.html</wfw:comment><comments>http://m.shnenglu.com/shifan3/archive/2006/12/27/16902.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://m.shnenglu.com/shifan3/comments/commentRss/16902.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/shifan3/services/trackbacks/16902.html</trackback:ping><description><![CDATA[     摘要:   1。符h找(对于函数此时只看名字Q不看参敎ͼ    大致序?nbsp;   (1)如果有限定名( XXX:: )那么q接在XXX里查?nbsp;   (2)函数局部名字空?nbsp;   (3)(如果是成?cd字空?nbsp;   (4)递归向上x有基cȝ...  <a href='http://m.shnenglu.com/shifan3/archive/2006/12/27/16902.html'>阅读全文</a><img src ="http://m.shnenglu.com/shifan3/aggbug/16902.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/shifan3/" target="_blank">shifan3</a> 2006-12-27 11:04 <a href="http://m.shnenglu.com/shifan3/archive/2006/12/27/16902.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]伪typeofhttp://m.shnenglu.com/shifan3/archive/2006/12/21/16690.htmlshifan3shifan3Thu, 21 Dec 2006 06:29:00 GMThttp://m.shnenglu.com/shifan3/archive/2006/12/21/16690.htmlhttp://m.shnenglu.com/shifan3/comments/16690.htmlhttp://m.shnenglu.com/shifan3/archive/2006/12/21/16690.html#Feedback5http://m.shnenglu.com/shifan3/comments/commentRss/16690.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/16690.html
发信? shifan (学习云技?, 杉K: C++
?nbsp; ? 伪typeof
发信? 飘ؓ水云?(Tue Dec 19 16:38:45 2006), 转信
 1 /*
 2 用标准C++实现typeof是不可能?br> 3 q个是我写的一个approached typeof
 4 所有需要被静态反出来的cd必须先用DECL_TYPE注册
 5 模板如果仅仅带有1个参数可以用DECL_TEMPLATE_1注册
 6 多个参数的模板还不支持。?br> 7 主要是没惛_~码
 8 
 9 d能注?4个类?br>10 可以通过MAX_TYPE_NUMBER讄
11 
12 支持的模板嵌套层数大Uؓ32 Q?nbsp;log2(MAX_TYPE_NUMBER)
13 MAX_TYPE_NUMBER必须?的整ơ数q?br>14 */
15 namespace my_typeof
16 {
17 
18   const int MAX_TYPE_NUMBER = 64;
19 
20   template <int N>
21   struct dummy
22   {
23     int a[N];
24   };
25 
26 
27   template <int N, typename Arg1>
28   struct select_by_number_1;
29 
30   template <int N>
31   struct select_by_number
32   {
33     typedef typename select_by_number_1<% MAX_TYPE_NUMBER, typename
34 select_by_number</ MAX_TYPE_NUMBER>::type>::type type;
35   };
36 
37 
38   template <typename T>
39   struct number_of
40   {
41     static const int v = sizeof(generic_f(*(T*)0)) / sizeof(int);
42   };
43 
44 
45 #define DECL_TYPE(T, N) \
46   namespace my_typeof{  \
47   template<>\
48   struct select_by_number<N> \
49   {\
50     typedef T type;\
51   };\
52   dummy <N> generic_f(const T&);}
53 
54 
55 #define DECL_TEMPLATE_1(T, N) \
56   namespace my_typeof{        \
57   template<typename Arg1>\
58   struct select_by_number_1<N, Arg1>\
59   {\
60     typedef T<Arg1> type;\
61   };\
62   template <typename Arg1>\
63   dummy<+ number_of<Arg1>::v * MAX_TYPE_NUMBER > generic_f(const T<Arg1>&);}
64 
65 
66 
67 #define TYPE_OF(x) my_typeof::select_by_number<sizeof(my_typeof::generic_f(x)) /
68 sizeof (int)>::type
69 
70 }
71 
72 
73 //sample
74 #include <iostream>
75 #include <vector>
76 #include <list>
77 
78 
79 DECL_TYPE(int1);
80 DECL_TEMPLATE_1(std::vector, 2);
81 DECL_TEMPLATE_1(std::list, 3);
82 DECL_TYPE(double4)
83 
84 using namespace std;
85 int main(intchar*[])
86 {
87   vector<list<vector<list<double> > > > v1;
88   TYPE_OF(v1) v2;
89   v1 = v2;
90   return 0;
91 }
92 
93 


--
You well 撒法QYou well all 撒法Q?br>
?内容修改:·shifan ?Dec 21 14:21:57 修改本文内容·[FROM: shifan]
?来源:·飘ؓ水云?freecity.cn·[FROM: shifan]


shifan3 2006-12-21 14:29 发表评论
]]>
[yc]Multi Bit Maskhttp://m.shnenglu.com/shifan3/archive/2006/10/26/14264.htmlshifan3shifan3Thu, 26 Oct 2006 15:37:00 GMThttp://m.shnenglu.com/shifan3/archive/2006/10/26/14264.htmlhttp://m.shnenglu.com/shifan3/comments/14264.htmlhttp://m.shnenglu.com/shifan3/archive/2006/10/26/14264.html#Feedback2http://m.shnenglu.com/shifan3/comments/commentRss/14264.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/14264.htmlboost的integer/integer_mask.hpp仅仅做了单个位的bit mask
要多个位必须写很多遍high_bit_mask_t
使用low_bits_mask_t也不能完全解决问?br>所以自qTypelist的U写法写了一?/p>

用法举例
bit_mask<INT_LIST_2(2, 3)>::valueq回一个|该值的W??位被|ؓ1
其余位ؓ0

 

  1 
  2 namespace multi_bit_mask
  3 {
  4     namespace details
  5     {
  6 
  7         template <typename T>
  8         struct get_size
  9         {
 10             enum {size = sizeof(T)}; 
 11         };
 12 
 13         template <int Bit>
 14         struct bit_storage
 15         {
 16             typedef typename bit_storage<Bit - 1>::storage_type storage_type;
 17         };
 18 
 19         //---------platform dependency-----------------------
 20 
 21         typedef unsigned int smallest_storage_type;
 22         typedef unsigned long long largest_storage_type;
 23 
 24         
 25 
 26         template <>
 27         struct bit_storage<0>
 28         {
 29             typedef smallest_storage_type storage_type;
 30         };
 31 
 32         template <>
 33         struct bit_storage<get_size<smallest_storage_type>::size * 8>
 34         {
 35             typedef largest_storage_type storage_type;
 36         };
 37 
 38         //disable the 65th bit
 39         template <>
 40         struct bit_storage<get_size<largest_storage_type>::size * 8>
 41         {
 42             typedef void storage_type;
 43         };
 44         
 45         //---------end of platform dependency----------------
 46 
 47 
 48         template <unsigned int N, typename Next>
 49         struct int_list
 50         {
 51             typedef typename bit_storage<N>::storage_type storage_type;
 52             static const storage_type value = N;
 53             typedef Next next;
 54         };
 55 
 56         struct null_type{};
 57 
 58         template<typename T1, typename T2, bool is_first>
 59         struct selector
 60         {
 61             typedef T1 type;
 62         };
 63 
 64         template<typename T1, typename T2>
 65         struct compare_type
 66         {
 67             const static bool is_larger = sizeof(T1) > sizeof(T2);
 68             typedef typename selector<T1, T2, is_larger>::type large_type;
 69             typedef typename selector<T1, T2, !is_larger>::type small_type;
 70         };
 71 
 72 
 73 
 74         template<typename T1, typename T2>
 75         struct selector<T1, T2, false>
 76         {
 77             typedef T2 type;
 78         };
 79 
 80         template <typename List>
 81         class find_largest_storage
 82         {
 83             typedef typename find_largest_storage<typename List::next>::storage_type T1;
 84             typedef typename bit_storage<List::value>::storage_type T2;
 85         public:
 86             typedef typename compare_type<T1, T2>::large_type storage_type;
 87         };
 88 
 89         template <>
 90         class find_largest_storage<null_type>
 91         {
 92         public:
 93             typedef smallest_storage_type storage_type;
 94         };    
 95 
 96         
 97     }
 98 
 99 
100         
101 
102 
103     template <int N>
104     struct single_bit_mask
105     {
106         typedef typename details::bit_storage<N>::storage_type storage_type;
107         static const storage_type value 
108             = static_cast<storage_type>(single_bit_mask<- 1>::value) * 2;
109     };
110 
111     template <>
112     struct single_bit_mask<0>
113     {
114         typedef details::bit_storage<0>::storage_type storage_type;
115         static const storage_type value = 1;
116     };
117 
118     
119     typedef details::null_type null_type;
120 
121     template <int N, typename Next>
122     struct int_list_t : public details::int_list<N, Next> {};
123 
124     template <typename List>
125     struct bit_mask
126     {
127     public:
128 
129         typedef typename details::find_largest_storage<List>::storage_type storage_type;
130     
131         static const storage_type value 
132             = static_cast<storage_type>(single_bit_mask<List::value>::value) 
133             | static_cast<storage_type>(bit_mask<typename List::next>::value);
134     };
135 
136     template <>
137     struct bit_mask<null_type>
138     {
139         typedef details::bit_storage<0>::storage_type storage_type;
140         static const storage_type value = 0;
141     };
142 
143     
144 
145     
146 
147     #define INT_LIST_1(n1) multi_bit_mask::int_list_t<n1, multi_bit_mask::null_type>
148     #define INT_LIST_2(n1, n2) multi_bit_mask::int_list_t<n1, INT_LIST_1(n2) > 
149     #define INT_LIST_3(n1, n2, n3) multi_bit_mask::int_list_t<n1, INT_LIST_2(n2, n3) > 
150     #define INT_LIST_4(n1, n2, n3, n4) multi_bit_mask::int_list_t<n1, INT_LIST_3(n2, n3, n4) > 
151     #define INT_LIST_5(n1, n2, n3, n4, n5) multi_bit_mask::int_list_t<n1, INT_LIST_4(n2, n3, n4, n5) > 
152     #define INT_LIST_6(n1, n2, n3, n4, n5, n6) multi_bit_mask::int_list_t<n1, INT_LIST_5(n2, n3, n4, n5, n6) > 
153     #define INT_LIST_7(n1, n2, n3, n4, n5, n6, n7) multi_bit_mask::int_list_t<n1, INT_LIST_6(n2, n3, n4, n5, n6, n7) > 
154     #define INT_LIST_8(n1, n2, n3, n4, n5, n6, n7, n8) multi_bit_mask::int_list_t<n1, INT_LIST_7(n2, n3, n4, n5, n6, n7, n8) > 
155     
156 }
157 
158 
159 


sample

#include  < iostream >
#include 
" multi_bit_mask.h "
using   namespace  std;
int  main()
{
    cout 
<<  multi_bit_mask::bit_mask < INT_LIST_1( 1 ) > ::value  <<  endl;
    cout 
<<  multi_bit_mask::bit_mask < INT_LIST_5( 0 1 2 3 4 ) > ::value  <<  endl;
    cout 
<<  multi_bit_mask::bit_mask < INT_LIST_7( 0 1 2 3 4 4 2 ) > ::value  <<  endl;
    


shifan3 2006-10-26 23:37 发表评论
]]>
[yc]VC下typeid实现及内存布局分析http://m.shnenglu.com/shifan3/archive/2006/10/26/14187.htmlshifan3shifan3Thu, 26 Oct 2006 02:46:00 GMThttp://m.shnenglu.com/shifan3/archive/2006/10/26/14187.htmlhttp://m.shnenglu.com/shifan3/comments/14187.htmlhttp://m.shnenglu.com/shifan3/archive/2006/10/26/14187.html#Feedback5http://m.shnenglu.com/shifan3/comments/commentRss/14187.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/14187.html    q日在学校bbs上与论C++的typeid关键字的实现问题Q有人提到type_info的地址是存攑֜虚表的第一个位|上Q颇觉得不妥Q于是我在vc2003下实验了一?/p>

    在vc下,使用typeid的时候,如果typeid施加l的cd是没有vptr的class或者根本不是class
那么汇编?br>mov  dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
也就是编译器生成一个简单的type_info对象的表Qƈ且在~译期静态决定下标,做一个简单查表操作?br>

如果typeid的操作对象是hvptr的classQ但是ƈ不是一个引用或者指针的解引用Ş式,例如

A a;
typeid(a);


那么仍然仅仅会做查表操作


如果typeid的操作对象是hvptr的classQƈ且是引用或者指针的解引用Ş式,例如

* =   new  A;
A
&  r  =   * p;
typeid(
* p);
typeid(r);


那么׃调用一个叫___RTtypeid的函敎ͼq过某种Ҏ来获取type_info对象
下面是___RTtypeid的反汇编Q这里只列出关键的几条指?br>

0041213E  mov         ecx,dword ptr [inptr]    Qinptr是对象的地址
00412141   mov         edx,dword ptr [ecx] 
00412143   mov         eax,dword ptr [edx - 4
0041215F  mov         ecx,dword ptr [eax
+ 0Ch] 
00412162   mov         dword ptr [ebp - 48h],ecx 
0041216C  mov         eax,dword ptr [ebp
- 48h] 


基本上等价于C语言?br>

int  a1  =  ( int )p;  // p是对象的地址
int  a2  =   * ( int * )a1  -   4 ;
int  a3  =   * ( int * )a2  +   12 ;
int  a4  =   * ( int * )a3;

 

那么从这D代码可以看出vc下type_info对象的存放位|[如下图]



也就虚表下标?1的位|上存放了一个指向一个未知的表的指针(暂且此表命名ؓruntime_info_table)
runtime_info_table的第4g存放了type_info对象的地址
至于runtime_info_table里前3g存放的是什? q需要再研究研究
一般来说它们全?, 但是对于多重虚承的c? W二g会是4, 可能和指针的偏移量有?



shifan3 2006-10-26 10:46 发表评论
]]>
[yc]Xpressive?/title><link>http://m.shnenglu.com/shifan3/archive/2006/07/27/10590.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Thu, 27 Jul 2006 08:27:00 GMT</pubDate><guid>http://m.shnenglu.com/shifan3/archive/2006/07/27/10590.html</guid><wfw:comment>http://m.shnenglu.com/shifan3/comments/10590.html</wfw:comment><comments>http://m.shnenglu.com/shifan3/archive/2006/07/27/10590.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://m.shnenglu.com/shifan3/comments/commentRss/10590.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/shifan3/services/trackbacks/10590.html</trackback:ping><description><![CDATA[Xpressive是一个C++的正则表辑ּ库,目前是Boost的候选库?br>Xpressive和Boost.Regex的区别很大。首先,Xpressive是一个纯头文件的库,也是_在用之前不需要预先编译。其ơ,Xpressive支持cM于Spirit的静态语义定义?br><br>我们先来看一个例子: <p> </p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)">#include </span><span style="COLOR: rgb(0,0,0)"><</span><span style="COLOR: rgb(0,0,0)">iostream</span><span style="COLOR: rgb(0,0,0)">></span><span style="COLOR: rgb(0,0,0)"><br>#include </span><span style="COLOR: rgb(0,0,0)"><</span><span style="COLOR: rgb(0,0,0)">boost</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">xpressive</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">xpressive.hpp</span><span style="COLOR: rgb(0,0,0)">></span><span style="COLOR: rgb(0,0,0)"><br><br></span><span style="COLOR: rgb(0,0,255)">using</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">namespace</span><span style="COLOR: rgb(0,0,0)"> boost::xpressive;<br><br></span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)"> main()<br>{<br>    std::</span><span style="COLOR: rgb(0,0,255)">string</span><span style="COLOR: rgb(0,0,0)"> hello( </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">hello world!</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)"> );<br><br>    sregex rex </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> sregex::compile( </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">(\\w+) (\\w+)!</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)"> );<br>    smatch what;<br><br>    </span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)">( regex_match( hello, what, rex ) )<br>    {<br>        std::cout </span><span style="COLOR: rgb(0,0,0)"><<</span><span style="COLOR: rgb(0,0,0)"> what[</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">] </span><span style="COLOR: rgb(0,0,0)"><<</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">; </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> whole match</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">        std::cout </span><span style="COLOR: rgb(0,0,0)"><<</span><span style="COLOR: rgb(0,0,0)"> what[</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">] </span><span style="COLOR: rgb(0,0,0)"><<</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">; </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> first capture</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">        std::cout </span><span style="COLOR: rgb(0,0,0)"><<</span><span style="COLOR: rgb(0,0,0)"> what[</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">] </span><span style="COLOR: rgb(0,0,0)"><<</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">; </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> second capture</span><span style="COLOR: rgb(0,128,0)"><br></span><span style="COLOR: rgb(0,0,0)">    }<br><br>    </span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">;<br>}</span></div> <p>q是使用Xpressive动态语义定义的例子Q其中sregex::compile函数~译一个表C正则文法的Ԍq返回一个正则对象sregex<br>使用regex_match来用这个正则对象匹配一个串。结果储存在what?br>其中what[0]q回整个Ԍwhat[1]~what[n]q回文法中用于标记的部分(用小括号括v来的部分)<br>最后将输出<br>     hello world!<br>     hello<br>     world</p> <p>如果惛_一个串中查扄合该文法的子Ԍ可以使用regex_searchQ用法和regex_match一P此外q可以用regex_replace来进行替换?br></p> <p> </p> <p><br>静态文法:<br>Xpressive除了可以用compile来分析一个文法串之外Q还可以用类gSpirit的方式来静态的指定文法Q?br></p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex re </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">$</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> _d </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> _d;</span></div> <p>q将定义一个表C金额的Ԍ其中_d表示一个数字,相当于串 $\d+.\d\d<br>q样定义文法比之前的动态定义更加高效,q且q有一个附加的好处Q?br>分定义Q?/p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex re </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">$</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">.</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> _d </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> _d;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>sregex s </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> re </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;</span></div> <p>q样s表示为用括号括v来的re<br>通过分定义Q文法能被表C的更加清楚?br>更加的是,分定义q可以向后引用,因此能够分析EBNF</p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">sregex group, factor, term, expression;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>group       </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> by_ref(expression) </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>factor      </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">_d </span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)"> group;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>term        </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> factor </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> factor) </span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> factor));<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>expression  </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> term </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> term) </span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> term));</span></div> <p>expression定义了一个四则表辑ּQ注意其中group的定义?br>q里必须使用by_ref是因为Xpressive默认是值拷贝,如果q里使用默认的方式,那么会造成一个无限@环?br><br><br>Xpressive可以在这里下?br><a >http://boost-consulting.com/vault/index.php?PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535&direction=0&order=&directory=Strings%20-%20Text%20Processing&PHPSESSID=f1d4af8b742cfa7adae7aab373cfc535</a><br>内有详细的文?/p> <img src ="http://m.shnenglu.com/shifan3/aggbug/10590.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/shifan3/" target="_blank">shifan3</a> 2006-07-27 16:27 <a href="http://m.shnenglu.com/shifan3/archive/2006/07/27/10590.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[yc]乱序Policy手法http://m.shnenglu.com/shifan3/archive/2006/07/24/10384.htmlshifan3shifan3Sun, 23 Jul 2006 17:06:00 GMThttp://m.shnenglu.com/shifan3/archive/2006/07/24/10384.htmlhttp://m.shnenglu.com/shifan3/comments/10384.htmlhttp://m.shnenglu.com/shifan3/archive/2006/07/24/10384.html#Feedback8http://m.shnenglu.com/shifan3/comments/commentRss/10384.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/10384.html看了546@C++@Freecity之后Q发觉非常有意?由此产生一些想?/p>

很多时候写一个类的时候,需要多个模版参敎ͼ例如一个遗传算法的法c,需要一个模版参数来指定交配方式Q另一个模版参数来指定子代选择的方式,q要一个参数来指定变异的方式。那么一般来_q个cM写成Q?/p>

template<class T                                                //描述问题的一个类
        , class CrossPolicy = AvgCrossPolicy                        //杂交方式
        , class SelectPolicy = DefaultSelectPolicy                //子代选择的方?br>        , class VariationPolicy = ReverseVariationPolicy>        //变异方式
class Gene
        : private AvgCrossPolicy
        , private SelectPolicy
        , private VariationPolicy
{
        ....
};

q样用户要用该cȝ时候,可以直接指定TQ就行了Q然而如果要指定变异方式Q那么就必须把所有的参数都显式的写出来,很不方便

546提供了一U有效的ҎQ可以让我们仅仅指定变异参数Q而不用写出另两个Policy
甚至允许我们以Q意的序书写几个Policy参数Q都不会有问?/p>

预备知识:
TypeList
一个TypeList是一个类型的容器
template <typename Type_, typename Next_>
struct TypeList
{
        typedef Type_ Type;
        typedef Next_ Next;
};
q就是一个TypeList?br>看这个写法,是不是像一个链表?
首先定义一个类型来表示链表:class NullType{};
现在一个包含了2个类型的TypeList可以写为:
TypeList<T1, TypeList<T2, NullType>  >

如何在一个TypeList中查找一个类型的子类Q?br>首先要有一个IsDerivedFrom<Base, T>
q个比较?br>template<class Base, class T>
class IsDerivedFrom
{
        struct large{char a[2];};
        static char pred(Base*);
        static large pred(...);
public:
        enum {Is = sizeof(pred((T*)0)) == sizeof(char)};
};

然后FindChild容易了
template <class List, class Base>
struct FindChild
{
        template <bool IsChild>
        struct Select
        {
                typedef typename List::Type Type;
        };

        template <>
        struct Select<false>
        {
                typedef typename FindChild<typename List::Next, Base>::Type Type;
        };

        typedef typename Select<IsDerivedFrom<Base, typename List::Type> >::Type Type;
};

当然q要对一些特D情况进行特化,例如NullType
template <class Base>
struct FindChild<NullType, Base>
{
        typedef NullType Type;
};
q里使用NullType来表明没扑ֈ

实际操作Q?br>首先需要给3个Policy3个基c,分别?br>class AvgCrossPolicyBase{};
class SelectPolicyBase{};
class VariationPolicyBase{};
内容为空p了,q样也没有虚函数调用的开销


然后声明一个类来表C默认情况:
class DefaultPolicy{};

定义一个宏
#define TYPELIST_3_N(a, b, c) TypeList<a, TypeList<b, TypeList<c, NullType> > >

下面要写一些选择?用于把合适的cd选择出来Q如果没扑ֈQ则要用默认的cd
template <class List, class Base, class DefaultType>
struct Selector
{
        template <class RetType>
        struct Judge
        {
                typedef RetType Type;
        };
       
        template<>
        struct Judge<NullType>
        {
                typedef DefaultType Type;
        };
        typedef typename Judge<typename FindChild<List, Base>::Type >::Type Type;
};

好啦Q现在整个类的声明可以写?/p>

template<class T
        , class CrossPolicy_ = DefaultPolicy
        , class SelectPolicy_ = DefaultPolicy
        , class VariationPolicy_ = DefaultPolicy     //其后的参数用户不可指?br>        , class List = TYPELIST_3_N(CrossPolicy_, SelectPolicy_, VariationPolicy_)
        , class CrossPolicy = typename Selector<List, CrossPolicyBase,  AvgCrossPolicy>::Type
        , class SelectPolicy = typename Selector<List,  SelectPolicyBase,  DefaultSelectPolicy>::Type
        , class VariationPolicy = typename Selector<List,  VariationPolicyBase,  ReverseVariationPolicy>::Type
        >
class Gene
        : private CrossPolicy
        , private SelectPolicy
        , private VariationPolicy
{
       
        ....
};


其中W?-7个参敎ͼListQCrossPolicyQSelectPolicy和VariationPolicyQ是不由用户指定的,仅仅是ؓ了v一个别?br>W一个参数T必须指定Q然?Q?Q?q?个参数就可以L的改变顺序了
例如Q可以写Gene<T, DefaultSelectPolicy, AvgCrossPolicy>而不会有M问题
如果不想要最后面几个参数的话也行Q但是代码就要稍微长一?br>而且最好在c里面进?个typedef
typedef typename Selector<List, CrossPolicyBase,  AvgCrossPolicy>::Type CrossPolicy;
{,以便在实现的时候?/p>

shifan3 2006-07-24 01:06 发表评论
]]>
[yc]自己实现LambdaQ第二部分)http://m.shnenglu.com/shifan3/archive/2006/07/15/10099.htmlshifan3shifan3Sat, 15 Jul 2006 07:32:00 GMThttp://m.shnenglu.com/shifan3/archive/2006/07/15/10099.htmlhttp://m.shnenglu.com/shifan3/comments/10099.htmlhttp://m.shnenglu.com/shifan3/archive/2006/07/15/10099.html#Feedback0http://m.shnenglu.com/shifan3/comments/commentRss/10099.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/10099.html阅读全文

shifan3 2006-07-15 15:32 发表评论
]]>
[yc]自己实现Lambdahttp://m.shnenglu.com/shifan3/archive/2006/06/09/8334.htmlshifan3shifan3Fri, 09 Jun 2006 05:23:00 GMThttp://m.shnenglu.com/shifan3/archive/2006/06/09/8334.htmlhttp://m.shnenglu.com/shifan3/comments/8334.htmlhttp://m.shnenglu.com/shifan3/archive/2006/06/09/8334.html#Feedback6http://m.shnenglu.com/shifan3/comments/commentRss/8334.htmlhttp://m.shnenglu.com/shifan3/services/trackbacks/8334.html阅读全文

shifan3 2006-06-09 13:23 发表评论
]]>
[yc]boost::spirit初体?/title><link>http://m.shnenglu.com/shifan3/archive/2005/12/18/1857.html</link><dc:creator>shifan3</dc:creator><author>shifan3</author><pubDate>Sun, 18 Dec 2005 04:02:00 GMT</pubDate><guid>http://m.shnenglu.com/shifan3/archive/2005/12/18/1857.html</guid><wfw:comment>http://m.shnenglu.com/shifan3/comments/1857.html</wfw:comment><comments>http://m.shnenglu.com/shifan3/archive/2005/12/18/1857.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://m.shnenglu.com/shifan3/comments/commentRss/1857.html</wfw:commentRss><trackback:ping>http://m.shnenglu.com/shifan3/services/trackbacks/1857.html</trackback:ping><description><![CDATA[<p><font face="Courier New">    最qؓ了解析SQL语法Q怀着试一试的心态去Mboost的spirit库,因ؓ该库的文的介里写着LL parser framework  represents parsers directly as EBNF grammars in inlined C++。看着frameworkq个词自然觉得这个库很牛BQ试用了一下果然如此?br>    所谓EBNFx展巴克斯范式Q是一U描qContext-Free Language的文法。在目前常见的非自然语言中,大部分都可以用EBNF表示。例如:<br><span id="axjtvyk" class=identifier>      group  </span><span id="ugsorwf" class=special>::=</span><span id="wmzoabs" class=literal>'('</span><span id="bgfyhri" class=identifier><span id="erlbvzj" class=identifier>exp </span></span></font><font face="Courier New"><span id="xgydtrt" class=literal>')'<br></span>      <span id="ypukegb" class=identifier>factor </span><span id="jlbvpgb" class=special>::=</span><span id="ofglyid" class=identifier>integer</span><span id="iglqsnt" class=special>|</span></font> <font face="Courier New"><span id="uwqgage" class=identifier>group<br></span>      <span id="lgwqvmh" class=identifier>term   </span><span id="msxldfh" class=special>::=</span><span id="ciyktzq" class=identifier>factor</span><span id="vqvlbtu" class=special>((</span><span id="evpuhji" class=literal>'*'</span><span id="pdmglgi" class=identifier>factor</span><span id="tvseyek" class=special>)</span><span id="mlbrlcx" class=special>|</span><span id="wglydci" class=special>(</span><span id="topysyx" class=literal>'/'</span><span id="pkeysyl" class=identifier>factor</span></font> <font face="Courier New"><span id="uaqvakq" class=special>))*<br></span>      <span id="bwfdmom" class=identifier>exp    </span><span id="ioxcavx" class=special>::=</span><span id="kcdtyxz" class=identifier>term</span><span id="cqrlfdf" class=special>((</span><span id="szeyzni" class=literal>'+'</span><span id="dcwmcdu" class=identifier>term</span><span id="bgtchyx" class=special>)</span><span id="ymyhqlc" class=special>|</span><span id="gfoirxz" class=special>(</span><span id="esxvakc" class=literal>'-'</span><span id="thqktkr" class=identifier>term</span></font> <span id="vichxof" class=special><font face="Courier New">))*<br>q是一个整数表辑ּ的EBNF。该D|q用spirit在C++中的实现则是Q?br>   </font> </span></p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">   <img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">rule</span><span style="COLOR: rgb(0,0,0)"><></span><span style="COLOR: rgb(0,0,0)"> group, factor, term, exp;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   group  </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> exp </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   factor </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> int_p </span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)"> group;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   term   </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> factor </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> factor) </span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> factor));<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   exp    </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> term </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">((</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> term) </span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> term));<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div> <p><font face="Courier New">q里使用=代替::=, ?gt;>代替I格q接。ƈ且由于C++语法所限,EBNF中后|的*在spirit中改为前|?br>{式左边的单词被UCؓ一个ruleQ等式右边ؓrule的定义。我们可以看Z个group是一个exp加上一ҎP一个factor是一个整数或者一个group,一个term是一个或多个factor?/q接Q一个exp是一个或多个term?-q接。处于最端的exp可以据此识别Z下表辑ּ<br></font><font face="Courier New"><span id="yqghqlr" class=number>   </span> </font></p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">   <img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">12345</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   (</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">) </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)">)<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   (</span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">) </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)">)<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> ((</span><span style="COLOR: rgb(0,0,0)">6</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">200</span><span style="COLOR: rgb(0,0,0)">) </span><span style="COLOR: rgb(0,0,0)">-</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">20</span><span style="COLOR: rgb(0,0,0)">) </span><span style="COLOR: rgb(0,0,0)">/</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">6</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   (</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">3</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,0)">4</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">5</span><span style="COLOR: rgb(0,0,0)">))))<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div> <p><font face="Courier New">    得到一个rule之后Q我们就可以?/font> <span id="yxvayih" class=identifier><font face="Courier New">parse函数对一个串q行识别了。例?br>         </font> </span></p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">         parse(</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">(1 + (2 + (3 + (4 + 5))))</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">, exp);</font> </span></div> <p><font face="Courier New"><br>该函数返回一个结构parse_infoQ可以通过讉K其中的full成员来判断是否成功识别,也可以访问stop成员来获知失败的位置。这里要特别提一点,关于各个W号之间的空|spirit的文的正文说的是给parse再传一个参数space_pQ通知parse跌所有的I格Q然而在FAQ中又提到Q如果用以上方法定义ruleQ第三个参数传space_p会失败。原因是使用rule默认定义的规则被UCؓcharacter level parsingQ即字符U别解析Q而parse的第3个参C适用于phrase level parsingQ即语法U别解析。要使用W?个参数可以有几种Ҏ?br>      1。在parse的第二个参数直接传入一个EBNF表达式,不创建rule对象?br>         <span id="rfztylc" class=identifier></span></font> </p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">            parse(</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">hello world</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">"</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">, </font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">*</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">anychar_p, space_p);  </font> </span></div> <p><font face="Courier New"><span id="qfzmcmd" class=special><br>      2。以rule<phrase_scanner_t>创徏rule?br>         </span> </font></p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><span style="COLOR: rgb(0,0,0)"><font face="Courier New">            rule</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New"><</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">phrase_scanner_t</font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New">></font> </span><span style="COLOR: rgb(0,0,0)"><font face="Courier New"> exp; </font> </span></div> <p><font face="Courier New">注意虽然可以用这两个办法屏蔽I格Q但是这样可能完全改变EBNF文法的语义,其是在语言本n需要识别空格的时候。对于这U情况,可以不用第三个参数Qƈ在需要出现空格的地方加上space_p,或?space_p?space_pQ其??分别表示后面的符可l出Cơ以上和0ơ以上。例如一个以I格分隔的整数列表可以写成int_p >> *(+space_p >> int_p)<br>   如上使用parse可以识别一个串Q但q不能做更多的操作,例如语法里的各个成分提取出来。对于这L需求,可以通过actor实现。下面是使用actor的一个简单例?br>   <span id="sludbsy" class=keyword></span></font> </p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New"><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   <span style="COLOR: rgb(0,0,255)">bool</span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   parse_numbers(</span><span style="COLOR: rgb(0,0,255)">char</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)"> str, vector</span><span style="COLOR: rgb(0,0,0)"><</span><span style="COLOR: rgb(0,0,255)">double</span><span style="COLOR: rgb(0,0,0)">>&</span><span style="COLOR: rgb(0,0,0)"> v)<br><img id=Codehighlighter1_61_247_Open_Image onclick="this.style.display='none'; Codehighlighter1_61_247_Open_Text.style.display='none'; Codehighlighter1_61_247_Closed_Image.style.display='inline'; Codehighlighter1_61_247_Closed_Text.style.display='inline';" src="http://m.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_61_247_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_61_247_Closed_Text.style.display='none'; Codehighlighter1_61_247_Open_Image.style.display='inline'; Codehighlighter1_61_247_Open_Text.style.display='inline';" src="http://m.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>   </span><span id=Codehighlighter1_61_247_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://m.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_61_247_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>      </span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)"> parse(str,<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>   </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">  Begin grammar</span><span style="COLOR: rgb(0,128,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: rgb(0,0,0)">      (<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>         real_p[push_back_a(v)] </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(0,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> real_p[push_back_a(v)])<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>      )<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>      ,<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>      </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">  End grammar</span><span style="COLOR: rgb(0,128,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: rgb(0,0,0)">      space_p).full;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>   }</span></span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div> <p><font face="Courier New">注意?span class=identifier>real_p后面的[]Q中括号里面是一个仿函数Q函数指针或者函数对象)Q该仿函数具有如下调用型?br>   </span></font> </p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">   <img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(IterT first, IterT last) </span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(NumT val) </span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top>   </span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">operator</span><span style="COLOR: rgb(0,0,0)">()(CharT ch) </span><span style="COLOR: rgb(0,0,255)">const</span><span style="COLOR: rgb(0,0,0)">;</span></font> </div> <p><span id="apysqwc" class=special><span id="ychtgfw" class=special><span id="fuzpyql" class=special><font face="Courier New"><br>一旦spase发现了匹?span class=identifier>real_p的子Ԍ׃调用该functor。不同的rule可能会对应不同的调用型别?/span><br>W一个型别针对一般规则,first和lastZ个指向字W的q代器(一般ؓchar*Q?匚w的子串ؓ[first, last)<br>W二个型别针Ҏ字型规则Q如real_p和int_p, 参数val是一个数字类型?br>W三个性别针对单字W型规则Q如space_p, 参数ch是一个字W类型?br><span id="peyhbob" class=identifier>real_p</span><span id="laqzmsr" class=special>[</span><span id="osboidu" class=identifier>push_back_a</span><span id="hwmrhci" class=special>(</span><span id="olfktdu" class=identifier>v</span><span id="slfglcm" class=special>)]中的push_back_a是一个spirit已经定义好的functorQ它会将匚w好的内容依照匚w到的旉序调用v的push_back函数加入到v中?br><br>   到此spirit的常用功能就都介l完了。要详细深入了解可以参考spirit的文档?br><br>最后在题一个注意要炏Vspirit的各UEBNFq接都是指针q接Q因此才能在expression被赋值前在group的定义里面用。所以在使用EBNF的时候一定要心不要局部变量的rule提供l全局或者类成员变量使用Q例如:<br>   </span></font> </span></span></span></p> <div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><font face="Courier New">   <img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)"> A<br><img id=Codehighlighter1_11_166_Open_Image onclick="this.style.display='none'; Codehighlighter1_11_166_Open_Text.style.display='none'; Codehighlighter1_11_166_Closed_Image.style.display='inline'; Codehighlighter1_11_166_Closed_Text.style.display='inline';" src="http://m.shnenglu.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_11_166_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_11_166_Closed_Text.style.display='none'; Codehighlighter1_11_166_Open_Image.style.display='inline'; Codehighlighter1_11_166_Open_Text.style.display='inline';" src="http://m.shnenglu.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>   </span><span id=Codehighlighter1_11_166_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://m.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_11_166_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>      rule</span><span style="COLOR: rgb(0,0,0)"><></span><span style="COLOR: rgb(0,0,0)"> s;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>      A()<br><img id=Codehighlighter1_45_161_Open_Image onclick="this.style.display='none'; Codehighlighter1_45_161_Open_Text.style.display='none'; Codehighlighter1_45_161_Closed_Image.style.display='inline'; Codehighlighter1_45_161_Closed_Text.style.display='inline';" src="http://m.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_45_161_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_45_161_Closed_Text.style.display='none'; Codehighlighter1_45_161_Open_Image.style.display='inline'; Codehighlighter1_45_161_Open_Text.style.display='inline';" src="http://m.shnenglu.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>      </span><span id=Codehighlighter1_45_161_Closed_Text style="BORDER-RIGHT: rgb(128,128,128) 1px solid; BORDER-TOP: rgb(128,128,128) 1px solid; DISPLAY: none; BORDER-LEFT: rgb(128,128,128) 1px solid; BORDER-BOTTOM: rgb(128,128,128) 1px solid; BACKGROUND-COLOR: rgb(255,255,255)"><img src="http://m.shnenglu.com/Images/dot.gif"></span><span id=Codehighlighter1_45_161_Open_Text><span style="COLOR: rgb(0,0,0)">{<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>         rule</span><span style="COLOR: rgb(0,0,0)"><></span><span style="COLOR: rgb(0,0,0)"> r </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> int_p </span><span style="COLOR: rgb(0,0,0)">|</span><span style="COLOR: rgb(0,0,0)"> hex_p;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/InBlock.gif" align=top>         s </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> r </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">*</span><span style="COLOR: rgb(0,0,0)">(</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">space_p </span><span style="COLOR: rgb(0,0,0)">>></span><span style="COLOR: rgb(0,0,0)"> r); </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">error, r destructed after return </span><span style="COLOR: rgb(0,128,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top></span><span style="COLOR: rgb(0,0,0)">      }</span></span><span style="COLOR: rgb(0,0,0)"><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>   }</span></span><span style="COLOR: rgb(0,0,0)">;<br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://m.shnenglu.com/Images/OutliningIndicators/None.gif" align=top></span></font> </div> <p><span id="txrpqwn" class=special><span id="fudejav" class=identifier><font face="Courier New"><span id="txcstsy" class=special><span id="dlfoqms" class=identifier><span id="lenhfek" class=special><span id="qydxrbs" class=special><span id="mbkxvbs" class=special><span id="yydbkbl" class=special>如果真想使用局部作用域Q可以在局部的rule前面加上static.</span> </span></span></span></span></span></font></span></span></p> <img src ="http://m.shnenglu.com/shifan3/aggbug/1857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.shnenglu.com/shifan3/" target="_blank">shifan3</a> 2005-12-18 12:02 <a href="http://m.shnenglu.com/shifan3/archive/2005/12/18/1857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.chaigan.cn" target="_blank">97Ʒ˾þþô߽97</a>| <a href="http://www.laobianjing.cn" target="_blank">re99þ6Ʒ</a>| <a href="http://www.jsfkf.cn" target="_blank">þþƷ˘AV</a>| <a href="http://www.108bto.cn" target="_blank">ձƷһþþ</a>| <a href="http://www.skgv0713.cn" target="_blank">þþƷƵ</a>| <a href="http://www.114out.cn" target="_blank">˾þۺ</a>| <a href="http://www.yslianzheng.cn" target="_blank">Ʒ99þ99þþ</a>| <a href="http://www.mb71.cn" target="_blank">þݺҹҹվ</a>| <a href="http://www.xsoczv19.cn" target="_blank">ŷۺϾþþ</a>| <a href="http://www.setocaster.cn" target="_blank">鶹WWWþöڲƷ</a>| <a href="http://www.fuzd88.cn" target="_blank">޹ƷAVþۺӰԺ</a>| <a href="http://www.laowang66.com.cn" target="_blank">91þþþþۺ</a>| <a href="http://www.jjj41.cn" target="_blank">һþþƷ</a>| <a href="http://www.xiaomaidou.cn" target="_blank">þþƷavӰԺ</a>| <a href="http://www.mdjzyz.cn" target="_blank">þþþþAvӰԺ</a>| <a href="http://www.mfuq.cn" target="_blank">Ʒžžžþþž</a>| <a href="http://www.aimingshi.cn" target="_blank">þ99Ļþ</a>| <a href="http://www.ysmyy.com.cn" target="_blank">ձƷþþþĻ</a>| <a href="http://www.daami.cn" target="_blank">LƷþ</a>| <a href="http://www.bobofans.cn" target="_blank">99þþƷѿ</a>| <a href="http://www.linglonggegame.cn" target="_blank">ƷŮþþþavˬ</a>| <a href="http://www.btclt.cn" target="_blank">þþƷWWW456C0M</a>| <a href="http://www.chenghuilin.cn" target="_blank">þˬ˾ƷƵ</a>| <a href="http://www.rfgjqh.cn" target="_blank">һþþƷһ</a>| <a href="http://www.dgltjsh.cn" target="_blank">޾Ʒþþþþ</a>| <a href="http://www.awcy.cn" target="_blank">Avþ</a>| <a href="http://www.wwwocj.com.cn" target="_blank">þۺϾɫۺϾƷ</a>| <a href="http://www.wufayulecheng.cn" target="_blank">þ99Ʒŷ</a>| <a href="http://www.shangxuewenhua.cn" target="_blank">þþžѸƵ</a>| <a href="http://www.czcsbsb.com.cn" target="_blank">þۺϾƷþ</a>| <a href="http://www.nicnr.cn" target="_blank">þþþþëƬѲ</a>| <a href="http://www.vzaw.cn" target="_blank">ŮƷþþ</a>| <a href="http://www.unicity642.com.cn" target="_blank">ŷԴսþþþþ </a>| <a href="http://www.t6s.com.cn" target="_blank">þþƷavպ</a>| <a href="http://www.3gdd.cn" target="_blank">avþþþòվ</a>| <a href="http://www.whpcjs.cn" target="_blank">þ99Ʒһ</a>| <a href="http://www.fyhd.net.cn" target="_blank">þAVԴվ</a>| <a href="http://www.jlife-pal.cn" target="_blank">AVþþƷ</a>| <a href="http://www.bibi81.cn" target="_blank">ŷƷһþ˵</a>| <a href="http://www.yk999.cn" target="_blank">ɫ͵͵88ŷƷþþ</a>| <a href="http://www.mayishenggou.cn" target="_blank">ھƷþþþþ99</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>