﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-cfmonkey的笔记本</title><link>http://www.cppblog.com/cfmonkey/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 16 Apr 2026 20:00:51 GMT</lastBuildDate><pubDate>Thu, 16 Apr 2026 20:00:51 GMT</pubDate><ttl>60</ttl><item><title>[py snippets] Time Fetcher</title><link>http://www.cppblog.com/cfmonkey/archive/2010/12/04/135410.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Fri, 03 Dec 2010 19:42:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2010/12/04/135410.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/135410.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2010/12/04/135410.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/135410.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/135410.html</trackback:ping><description><![CDATA[<p><font style="background-color: #ffff00" size="2" face="Arial"><strong>RFC868</strong></font></p> <p><font face="Arial">Network Working Group&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; J. Postel - ISI</font> <p><font face="Arial">Request for Comments: 868&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; K. Harrenstien - SRI</font> <p><font face="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; May 1983</font> <p><font face="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Time Protocol</font> <p><font face="Arial">This RFC specifies a standard for the ARPA Internet community.&nbsp; Hosts on</font> <p><font face="Arial">the ARPA Internet that choose to implement a Time Protocol are expected</font> <p><font face="Arial">to adopt and implement this standard.</font> <p><font face="Arial">This protocol provides a site-independent, machine readable date and</font> <p><font face="Arial">time.&nbsp; The Time service sends back to the originating source the time in</font> <p><font face="Arial">seconds since midnight on January first 1900.</font> <p><font face="Arial">One motivation arises from the fact that not all systems have a</font> <p><font face="Arial">date/time clock, and all are subject to occasional human or machine</font> <p><font face="Arial">error.&nbsp; The use of time-servers makes it possible to quickly confirm or</font> <p><font face="Arial">correct a system's idea of the time, by making a brief poll of several</font> <p><font face="Arial">independent sites on the network.</font> <p><font face="Arial">This protocol may be used either above the Transmission Control Protocol</font> <p><font face="Arial">(TCP) or above the User Datagram Protocol (UDP).</font> <p><font face="Arial">When used via TCP the time service works as follows:</font> <p><font face="Arial">&nbsp;&nbsp; S: Listen on port 37 (45 octal).</font> <p><font face="Arial">&nbsp;&nbsp; U: Connect to port 37.</font> <p><font face="Arial">&nbsp;&nbsp; S: Send the time as a 32 bit binary number.</font> <p><font face="Arial">&nbsp;&nbsp; U: Receive the time.</font> <p><font face="Arial">&nbsp;&nbsp; U: Close the connection.</font> <p><font face="Arial">&nbsp;&nbsp; S: Close the connection.</font> <p><font face="Arial">&nbsp;&nbsp; The server listens for a connection on port 37.&nbsp; When the connection</font> <p><font face="Arial">&nbsp;&nbsp; is established, the server returns a 32-bit time value and closes the</font> <p><font face="Arial">&nbsp;&nbsp; connection.&nbsp; If the server is unable to determine the time at its</font> <p><font face="Arial">&nbsp;&nbsp; site, it should either refuse the connection or close it without</font> <p><font face="Arial">&nbsp;&nbsp; sending anything.</font> <p><font face="Arial">RFC 868&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; May 1983</font> <p><font face="Arial">Time Protocol&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font> <p><font face="Arial">When used via UDP the time service works as follows:</font> <p><font face="Arial">&nbsp;&nbsp; S: Listen on port 37 (45 octal).</font> <p><font face="Arial">&nbsp;&nbsp; U: Send an empty datagram to port 37.</font> <p><font face="Arial">&nbsp;&nbsp; S: Receive the empty datagram.</font> <p><font face="Arial">&nbsp;&nbsp; S: Send a datagram containing the time as a 32 bit binary number.</font> <p><font face="Arial">&nbsp;&nbsp; U: Receive the time datagram.</font> <p><font face="Arial">&nbsp;&nbsp; The server listens for a datagram on port 37.&nbsp; When a datagram</font> <p><font face="Arial">&nbsp;&nbsp; arrives, the server returns a datagram containing the 32-bit time</font> <p><font face="Arial">&nbsp;&nbsp; value.&nbsp; If the server is unable to determine the time at its site, it</font> <p><font face="Arial">&nbsp;&nbsp; should discard the arriving datagram and make no reply.</font> <p><font face="Arial">The Time</font> <p><font face="Arial">The time is the number of seconds since 00:00 (midnight) 1 January 1900</font> <p><font face="Arial">GMT, such that the time 1 is 12:00:01 am on 1 January 1900 GMT; this</font> <p><font face="Arial">base will serve until the year 2036.</font> <p><font face="Arial">For example:</font> <p><font face="Arial">&nbsp;&nbsp; the time&nbsp; 2,208,988,800 corresponds to 00:00&nbsp; 1 Jan 1970 GMT,</font> <p><font face="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2,398,291,200 corresponds to 00:00&nbsp; 1 Jan 1976 GMT,</font> <p><font face="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2,524,521,600 corresponds to 00:00&nbsp; 1 Jan 1980 GMT,</font> <p><font face="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2,629,584,000 corresponds to 00:00&nbsp; 1 May 1983 GMT,</font> <p><font face="Arial">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; and -1,297,728,000 corresponds to 00:00 17 Nov 1858 GMT.</font> <p><font size="2" face="Courier New"></font>&nbsp;</p> <p><font size="2" face="Courier New">#!/usr/bin/env python<br></font><font size="2" face="Courier New"># udp</font></p> <p><font size="2" face="Courier New">import socket, sys, struct, time</font></p> <p><font size="2" face="Courier New">def main():<br>&nbsp;&nbsp;&nbsp; host = socket.gethostbyname('stdtime.gov.hk')<br>&nbsp;&nbsp;&nbsp; port = 37<br>&nbsp;&nbsp;&nbsp; s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)<br>&nbsp;&nbsp;&nbsp; s.sendto('', (host, port))<br>&nbsp;&nbsp;&nbsp; buf = s.recvfrom(2048)[0]<br></font></p> <p><font size="2" face="Courier New">&nbsp;&nbsp;&nbsp; if len(buf) != 4:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print 'wrong size replies: %d: %s' % (len(buf), buf)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sys.exit(-1)<br>&nbsp;&nbsp;&nbsp; secs = struct.unpack('!I', buf)[0]<br>&nbsp;&nbsp;&nbsp; secs -= 2208988800<br>&nbsp;&nbsp;&nbsp; print time.ctime(int(secs))</font></p> <p><font size="2" face="Courier New">if __name__ == '__main__':<br>&nbsp;&nbsp;&nbsp; main()</font></p><img src ="http://www.cppblog.com/cfmonkey/aggbug/135410.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2010-12-04 03:42 <a href="http://www.cppblog.com/cfmonkey/archive/2010/12/04/135410.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python Regex Cheatsheet</title><link>http://www.cppblog.com/cfmonkey/archive/2010/09/23/127427.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Thu, 23 Sep 2010 10:31:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2010/09/23/127427.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/127427.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2010/09/23/127427.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/127427.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/127427.html</trackback:ping><description><![CDATA[<span style="FONT-FAMILY: monospace; WHITE-SPACE: pre; FONT-SIZE: 13px"><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> re <br></span><span style="COLOR: rgb(0,0,255)">def</span><span style="COLOR: rgb(0,0,0)"> regexp():<br>&nbsp;&nbsp;&nbsp; s </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">&lt;html&gt;&lt;head&gt;&lt;title&gt;Title&lt;/title&gt;</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,128,0)">#</span><span style="COLOR: rgb(0,128,0)"> with pre compiled pattern</span><span style="COLOR: rgb(0,128,0)"> <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,0)">pattern </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> re.compile(</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">title</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)">)<br>&nbsp;&nbsp; &nbsp;match </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> pattern.search(s) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,128,0)">#</span><span style="COLOR: rgb(0,128,0)">check for existence</span><span style="COLOR: rgb(0,128,0)"> <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,0)"></span><span style="COLOR: rgb(0,0,255)">print</span><span style="COLOR: rgb(0,0,0)"> match <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,128,0)">#</span><span style="COLOR: rgb(0,128,0)"> &gt;&gt; &lt;_sre.SRE_Match object at 0x011E0E58&gt;</span><span style="COLOR: rgb(0,128,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)">loop through all matches<br></span><span style="COLOR: rgb(0,0,0)">&nbsp;&nbsp;&nbsp; match </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> pattern.findall(s) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,255)">print</span><span style="COLOR: rgb(0,0,0)"> match <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,128,0)">#</span><span style="COLOR: rgb(0,128,0)"> &gt;&gt; ['title', 'title']</span><span style="COLOR: rgb(0,128,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)">grouping matches</span><span style="COLOR: rgb(0,128,0)"> <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,0)">s </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">&lt;html&gt;&lt;head&gt;&lt;title&gt;Title&lt;/title&gt;</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> <br>&nbsp;&nbsp;&nbsp; pattern </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> re.compile(</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">(head).*(title)</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)">) <br>&nbsp;&nbsp;&nbsp; match </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> pattern.search(s) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,255)">print</span><span style="COLOR: rgb(0,0,0)"> match.group(0) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,128,0)">#</span><span style="COLOR: rgb(0,128,0)"> &gt;&gt;head&gt;&lt;title&gt;Title&lt;/title</span><span style="COLOR: rgb(0,128,0)"> <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,0)"></span><span style="COLOR: rgb(0,0,255)">print</span><span style="COLOR: rgb(0,0,0)"> match.group(</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,128,0)">#</span><span style="COLOR: rgb(0,128,0)"> &gt;&gt;head</span><span style="COLOR: rgb(0,128,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)">replace</span><span style="COLOR: rgb(0,128,0)"> <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,0)">pattern </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> re.compile(</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">title</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)">) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,255)">print</span><span style="COLOR: rgb(0,0,0)"> pattern.sub(</span><span style="COLOR: rgb(128,0,0)">"</span><span style="COLOR: rgb(128,0,0)">ersetzt</span><span style="COLOR: rgb(128,0,0)">"</span><span style="COLOR: rgb(0,0,0)">,s) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,128,0)">#</span><span style="COLOR: rgb(0,128,0)"> &gt;&gt; &lt;html&gt;&lt;head&gt;&lt;ersetzt&gt;Title&lt;/ersetzt&gt;</span><span style="COLOR: rgb(0,128,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)">split</span><span style="COLOR: rgb(0,128,0)"> <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,0)">pattern </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> re.compile(</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">title</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)">) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,255)">print</span><span style="COLOR: rgb(0,0,0)"> pattern.split(s) <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,128,0)">#</span><span style="COLOR: rgb(0,128,0)"> &gt;&gt; ['&lt;html&gt;&lt;head&gt;&lt;', '&gt;Title&lt;/', '&gt;']</span><span style="COLOR: rgb(0,128,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)">replace alle lines in file by "eineZeile"</span><span style="COLOR: rgb(0,128,0)"> <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,0)">f </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> open(</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">test.txt</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)">,</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">r</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)">) <br>&nbsp;&nbsp;&nbsp; l</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> [</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(128,0,0)">eineZeile</span><span style="COLOR: rgb(128,0,0)">'</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">for</span><span style="COLOR: rgb(0,0,0)"> l </span><span style="COLOR: rgb(0,0,255)">in</span><span style="COLOR: rgb(0,0,0)"> f.readlines()] <br>&nbsp;&nbsp;&nbsp; f.close() <br>&nbsp;&nbsp;&nbsp; </span><span style="COLOR: rgb(0,0,255)">print</span><span style="COLOR: rgb(0,0,0)"> l <br>&nbsp;&nbsp;&nbsp; f</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">open(</span><span style="COLOR: rgb(128,0,0)">"</span><span style="COLOR: rgb(128,0,0)">test.txt</span><span style="COLOR: rgb(128,0,0)">"</span><span style="COLOR: rgb(0,0,0)">, </span><span style="COLOR: rgb(128,0,0)">"</span><span style="COLOR: rgb(128,0,0)">w</span><span style="COLOR: rgb(128,0,0)">"</span><span style="COLOR: rgb(0,0,0)">)<br>&nbsp;&nbsp;&nbsp; f.writelines(l) <br>&nbsp;&nbsp;&nbsp; f.close()&nbsp;<br><br>regexp()</span></span> 
<img src ="http://www.cppblog.com/cfmonkey/aggbug/127427.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2010-09-23 18:31 <a href="http://www.cppblog.com/cfmonkey/archive/2010/09/23/127427.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>LIBEVENT WEBSERVER IN 40LINES OF C</title><link>http://www.cppblog.com/cfmonkey/archive/2010/04/14/112574.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Wed, 14 Apr 2010 11:43:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2010/04/14/112574.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/112574.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2010/04/14/112574.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/112574.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/112574.html</trackback:ping><description><![CDATA[<span  style="color: rgb(85, 85, 85); font-family: Verdana, 'BitStream vera Sans', Helvetica, sans-serif; font-size: 12px; "><h2 style="margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 5px; padding-bottom: 3px; padding-left: 5px; font-weight: bolder; letter-spacing: -0.07em; font-family: Verdana, 'BitStream vera Sans'; font-size: 16px; display: block; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(204, 204, 204); ">libevent webserver in 40 lines of c</h2><div class="info" style="margin-top: 5px; margin-right: 5px; margin-bottom: 5px; margin-left: 5px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><span class="date" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 22px; background-image: url(http://3.rdrail.net/blog/wp-content/themes/inove/img/icons.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; height: 16px; line-height: 16px; display: block; font-size: 11px; float: left; background-position: 0px -48px; background-repeat: no-repeat no-repeat; ">March 25th, 2008</span><div class="act" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; height: 16px; float: right; "><span class="comments" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 15px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 22px; background-image: url(http://3.rdrail.net/blog/wp-content/themes/inove/img/icons.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; height: 16px; line-height: 16px; display: block; font-size: 11px; float: left; background-position: 0px -96px; background-repeat: no-repeat no-repeat; "><a href="http://3.rdrail.net/blog/libevent-webserver-in-40-lines-of-c/#comments" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(41, 112, 166); text-decoration: none; ">Goto comments</a></span><span class="addcomment" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 15px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 22px; background-image: url(http://3.rdrail.net/blog/wp-content/themes/inove/img/icons.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; height: 16px; line-height: 16px; display: block; font-size: 11px; float: left; background-position: 0px -112px; background-repeat: no-repeat no-repeat; "><a href="http://3.rdrail.net/blog/libevent-webserver-in-40-lines-of-c/#respond" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(41, 112, 166); text-decoration: none; ">Leave a comment</a></span><div class="fixed" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; clear: both; "></div></div><div class="fixed" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; clear: both; "></div></div><div class="content" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 5px; padding-right: 0px; padding-bottom: 5px; padding-left: 5px; line-height: 17px; overflow-x: hidden; overflow-y: hidden; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; "><a href="http://www.monkey.org/~provos/libevent/" title="libevent" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(41, 112, 166); text-decoration: none; ">Libevent</a>&nbsp;provides cross-platform asynchronous callbacks on sockets and file descriptors. Different operating systems have different ways of handling this efficiently, for example linux has kernel support for this operation which can scale to tens of thousands of sockets. It&#8217;s all pretty complicated but libevent makes it very simple. Along with a basic&nbsp;<a href="http://www.monkey.org/~provos/libevent/doxygen/index.html" title="libevent docs" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(41, 112, 166); text-decoration: none; ">api</a>&nbsp;that is used by highly scalable projects like&nbsp;<a href="http://danga.com/memcached/" title="memcached" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(41, 112, 166); text-decoration: none; ">memcached</a>&nbsp;and&nbsp;<a href="http://developers.facebook.com/thrift/" title="thrift" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: rgb(41, 112, 166); text-decoration: none; ">thrift,</a>&nbsp;it also has asyncronus a dns lookup api and a http server api.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">Here&#8217;s an example of how simple it is to write a basic http server.</p><pre name="code" class="c" style="margin-top: 5px; margin-right: 0px; margin-bottom: 5px; margin-left: 0px; padding-top: 8px; padding-right: 12px; padding-bottom: 8px; padding-left: 36px; background-image: url(http://3.rdrail.net/blog/wp-content/themes/inove/img/blockquote.gif); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: rgb(244, 245, 247); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dashed; border-right-style: dashed; border-bottom-style: dashed; border-left-style: dashed; border-top-color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); background-position: 3px 3px; background-repeat: no-repeat no-repeat; ">#include &lt;sys/types.h&gt;
#include &lt;sys/time.h&gt;
#include &lt;sys/queue.h&gt;#include &lt;stdlib.h&gt;

#include &lt;err.h&gt;
#include &lt;event.h&gt;
#include &lt;evhttp.h&gt;

void generic_handler(struct evhttp_request *req, void *arg)
{
        struct evbuffer *buf;
        buf = evbuffer_new();

        if (buf == NULL)
            err(1, "failed to create response buffer");

        evbuffer_add_printf(buf, "Requested: %sn", evhttp_request_uri(req));
        evhttp_send_reply(req, HTTP_OK, "OK", buf);
}

int main(int argc, char **argv)
{
    struct evhttp *httpd;

    event_init();
    httpd = evhttp_start("0.0.0.0", 8080);

    /* Set a callback for requests to "/specific". */
    /* evhttp_set_cb(httpd, "/specific", another_handler, NULL); */

    /* Set a callback for all other requests. */
    evhttp_set_gencb(httpd, generic_handler, NULL);

    event_dispatch();

    /* Not reached in this code as it is now. */
    evhttp_free(httpd);

    return 0;
}</pre><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">But is it fast? check out the benchmarks (on my laptop):</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">ab -c 1000 -n 10000 http://localhost/</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">Apache2: Requests per second: 1274.14 [#/sec] (mean)</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">libevent: Requests per second: 1584.37 [#/sec] (mean)</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">Kickass!</p></div></span>
<img src ="http://www.cppblog.com/cfmonkey/aggbug/112574.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2010-04-14 19:43 <a href="http://www.cppblog.com/cfmonkey/archive/2010/04/14/112574.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Sicp笔记1.1节</title><link>http://www.cppblog.com/cfmonkey/archive/2009/01/20/72397.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Tue, 20 Jan 2009 13:58:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2009/01/20/72397.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/72397.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2009/01/20/72397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/72397.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/72397.html</trackback:ping><description><![CDATA[<p>sicp刚进大学的时候看过三章, 现在基本上忘光了. 只能从头看, 希望这次能看完.</p>
<p>我用的scheme环境是<a href="http://plt-scheme.org/">drscheme</a>, 功能十分好. scheme是一门很简单的函数式语言, 看一遍它的<a href="http://www.cppblog.com/Files/cfmonkey/r5rscn.pdf">R5RS标准</a>基本上就可以用了. </p>
<p><br><br>full text version <a href="http://mitpress.mit.edu/sicp">http://mitpress.mit.edu/sicp</a>
<p>The acts of the mind, wherein it exerts its power over simple ideas, are chiefly these three: 1. Combining several simple ideas into one compound one, and thus all complex ideas are made. 2. The second is bringing two ideas, whether simple or complex, together, and setting them by one another so as to take a view of them at once, without uniting them into one, by which it gets all its ideas of relations. 3. The third is separating them from all other ideas that accompany them in their real existence: this is called abstraction, and thus all its general ideas are made.
<p><a></a>John Locke, <em>An Essay Concerning Human Understanding</em> (1690)
<p>前缀表示法(prefix notation)的两个优点:
<p>1. 可以适应带有任意多个参数的过程.<br>2. 允许组合式层层嵌套, 即组合式本身可以作为别的组合式的基本元素. e.g<br>&nbsp;&nbsp;&nbsp; (+ (* 3 5)(- 10 6)).
<p>Lisp obeys the convention that <em><strong>every expression has a value</strong></em>. This convention, together with the old reputation of Lisp as an inefficient language, is the source of the quip by Alan Perlis (paraphrasing Oscar Wilde) that ``<em>Lisp programmers know the value of everything but the cost of nothing</em>.''
<p>通过使用(define varible value)语法定义变量的行为, 使得解释器必须具备一种保持 变量名---值 匹配对的存储能力. 也就是解释器要维护一张表, 来查询 变量名---值的对映关系. 这被称作Global Environment, Environment是具有普遍性的概念, 它为求值过程提供上下文.
<p>组合式(Combination)
<p>e.g
<p>(+ (+ 2 (* 4 6))<br>&nbsp;&nbsp; (+ 3 5 7))
<p>的计算过程
<p><a href="http://www.cppblog.com/images/cppblog_com/cfmonkey/WindowsLiveWriter/Sicp1.1_134DA/ch1-Z-G-1_2.gif"><img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=247 alt=ch1-Z-G-1 src="http://www.cppblog.com/images/cppblog_com/cfmonkey/WindowsLiveWriter/Sicp1.1_134DA/ch1-Z-G-1_thumb.gif" width=292 border=0></a>
<p>In fact, the "<strong>percolate values upward</strong>" form of the evaluation rule is an example of a general kind of process known as <a></a><strong><em>tree accumulation</em>. </strong>这种一般性求值规则还有两种意外情况, 一种就是define操作, 它具有自己的求值规则.&nbsp;
<p>针对特殊语法规则的脚注：<br><a></a><a></a><a></a><a></a><a></a><a></a><a></a>Special syntactic forms that are simply convenient alternative surface structures for things that can be written in more uniform ways are sometimes called <em>syntactic sugar</em>, to use a phrase coined by Peter Landin. In comparison with users of other languages, Lisp programmers, as a rule, are less concerned with matters of syntax. (By contrast, examine any Pascal manual and notice how much of it is devoted to descriptions of syntax.) This disdain for syntax is due partly to the flexibility of Lisp, which makes it easy to change surface syntax, and partly to the observation that many ``convenient'' syntactic constructs, which make the language less uniform, end up causing more trouble than they are worth when programs become large and complex. In the words of Alan Perlis, ``Syntactic sugar causes cancer of the semicolon.''
<p>定义过程的一般形式: <br>&nbsp;&nbsp; (define (&lt;name&gt; &lt;formal parameter&gt;) &lt;body))
<p>求值的两种顺序: 正则序(normal order)和应用序(applicative order)
<p><strong>正则序</strong>: 完全展开然后归约.&nbsp; <strong>应用序</strong>: 先求值参数然后应用.
<p>通过cond表达式和if表达式实现的abs函数.
<p>;; (cond (&lt;p1&gt; &lt;e1&gt;)<br>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (&lt;pn&gt; &lt;en&gt;)<br>;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (else &lt;ee&gt;))<br>(define (abs1 x)<br>&nbsp; (cond ((&lt; x 0) (- 0 x))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (else x)))<br>;; (if &lt;predicate&gt; &lt;consequent&gt; &lt;alternative&gt;)<br>(define (abs2 x)<br>&nbsp; (if (&lt; x 0) (- 0 x) (x)))
<p>谓词: &lt;, =, &gt;, (and &lt;e1&gt;...&lt;en&gt;), (or &lt;e1&gt;...&lt;en&gt;), (not &lt;e&gt;)
<hr>
<p><strong>ex1.3</strong> Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.
<p>(define (sum a b c)<br>&nbsp; (if (&gt; (+ b c) (if (&gt; (+ a b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a c))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a c)))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ b c) (if (&gt; (+ a b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a c))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a c))))
<p>--------------------------<br>(define (sum a b c)<br>&nbsp; (define x (if (&gt; (+ a b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a c))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ a c)))<br>&nbsp; (if (&gt; (+ b c) x)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (+ b c) x))
<p>lisp/scheme一个十分好的特性是符号谓词过程都可以以一个基本元素的形式充当参数或者是返回值. e.g
<p>(define (a-plus-abs-b a b)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((if (&gt; b 0) + -) a b))
<p><strong>ex1.5 </strong>Ben Bitdiddle has invented a test to determine whether the interpreter he is faced with is using applicative-order evaluation or normal-order evaluation. He defines the following two procedures:
<p><tt>(define (p) (p))<br>(define (test x y)<br>&nbsp; (if (= x 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; y))<br></tt>
<p>Then he evaluates the expression
<p><tt>(test 0 (p))<br></tt>
<p>What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What behavior will he observe with an interpreter that uses normal-order evaluation? Explain your answer. <a></a><a></a>(Assume that the evaluation rule for the special form <tt>if</tt> is the same whether the interpreter is using normal or applicative order: The predicate expression is evaluated first, and the result determines whether to evaluate the consequent or the alternative expression.)
<p>用两种规则进行代换:
<p>正则序求值时, 将参数完全展开然后归约. 所以(test 0 (p))展开为:
<p>(if (= 0 0)<br>&nbsp;&nbsp;&nbsp;&nbsp; 0<br>&nbsp;&nbsp;&nbsp; (p))
<p>应用序求值时, 先对参数进行求值, 然后归约, 所以(test 0 (p))对参数(p)求值, 陷入死循环中.<br>DrScheme采用的是应用序规则. 所以运行这段程序没有响应.<br>
<p><strong>ex1.6</strong>
<p>Alyssa P. Hacker doesn't see why <tt>if</tt> needs to be provided as a special form. ``Why can't I just define it as an ordinary procedure in terms of <tt>cond</tt>?'' she asks. Alyssa's friend Eva Lu Ator claims this can indeed be done, and she defines a new version of <tt>if</tt>:
<p><tt>(define (new-if predicate then-clause else-clause)<br>&nbsp; (cond (predicate then-clause)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (else else-clause)))<br></tt>
<p>Eva demonstrates the program for Alyssa:
<p><tt>(new-if (= 2 3) 0 5)<br><em>5</em><br>(new-if (= 1 1) 0 5)<br><em>0</em><br></tt>
<p>Delighted, Alyssa uses <tt>new-if</tt> to rewrite the square-root program:
<p><tt>(define (sqrt-iter guess x)<br>&nbsp; (new-if (good-enough? guess x)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; guess<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (sqrt-iter (improve guess x)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x)))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (c1)<br></tt>
<p>What happens when Alyssa attempts to use this to compute square roots? Explain.
<p>这样做是很危险的, 因为换置if的new-if是一个过程, 那么若它的参数求值规则是应用序的话, 上面代码c1处的sqrt-iter在判断条件是否满足前就已经开始计算. 所以最后的结果是错的.&nbsp;&nbsp; </p>
<img src ="http://www.cppblog.com/cfmonkey/aggbug/72397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2009-01-20 21:58 <a href="http://www.cppblog.com/cfmonkey/archive/2009/01/20/72397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Scheme 语言介绍</title><link>http://www.cppblog.com/cfmonkey/archive/2009/01/20/72367.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Tue, 20 Jan 2009 05:25:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2009/01/20/72367.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/72367.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2009/01/20/72367.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/72367.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/72367.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Wolfgang Kreutzer翻译：寒蝉退士原文：http://www.cosc.canterbury.ac.nz/~wolfgang/cosc302/Chap2.3.html译者声明：译者对译文不做任何担保，译者对译文不拥有任何权利并且不负担任何责任和义务。APL 如同钻石，有着美妙的晶体结构；它的所有部分都以一致和优美的方式关联在一起。但是如果你尝试以任何方式扩展这种结构 ...&nbsp;&nbsp;<a href='http://www.cppblog.com/cfmonkey/archive/2009/01/20/72367.html'>阅读全文</a><img src ="http://www.cppblog.com/cfmonkey/aggbug/72367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2009-01-20 13:25 <a href="http://www.cppblog.com/cfmonkey/archive/2009/01/20/72367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用livewriter记笔记</title><link>http://www.cppblog.com/cfmonkey/archive/2009/01/18/72257.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Sun, 18 Jan 2009 06:06:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2009/01/18/72257.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/72257.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2009/01/18/72257.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/72257.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/72257.html</trackback:ping><description><![CDATA[<p><a href="http://www.ycool.com/space.php?uid=1024488">Rock</a> @ 2007-06-14 18:23 </p>
<p>灌片水, 打发点时间... ...<br>话说<br>我在The CppBlog 申请了一个帐号用来记些看书时候的笔记.<br>不过为了记点小东西登录来登录去的. 就委实要把人弄疯了, 本来够不正常了.<br>所以我就换用一个本地的blog程序.<br>原来使用的是菊子曰, 重装系统以后找不到, 图省事, 找了一个LiveWriter用.<br>下载<a href="http://download.microsoft.com/download/0/a/c/0acde950-f25e-4734-962f-3be70e0578f3/Writer.msi">LiveWriter</a>, 安装需要.NetFramework<br>启动程序, 在添加帐号向导的Choose Blog Type 中选择" Another Weblog Service", 点Next,&nbsp;&nbsp;<br>输入博客地址, 用户名,密码, Next, 在Select Provider 中选择Custom(Metaweblog API), 在Remote Posting URL中填<br>http://www.cppblog.com/cfmonkey/services/metablogapi.aspx<br>将高亮部分替换为自己的用户名, 完成<br>记代码自然需要代码高亮了, 有老外写的Plugin,&nbsp; <a href="http://deedee.brainstream.net/ct.ashx?id=9b792274-b923-4164-9361-cde590efcac5&amp;url=http://deedee.brainstream.net/content/binary/CodeFormatterPluginSetup.exe">CodeFormatterPlugin</a>,&nbsp;<br>安装后启动LiveWriter, 在Insert中即出现了InsertCode选项, 以后要插入高亮代码, 即点击改选项输入代码..&nbsp;<br>end. </p>
<img src ="http://www.cppblog.com/cfmonkey/aggbug/72257.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2009-01-18 14:06 <a href="http://www.cppblog.com/cfmonkey/archive/2009/01/18/72257.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>What's wrong with CS research </title><link>http://www.cppblog.com/cfmonkey/archive/2008/07/31/57671.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Thu, 31 Jul 2008 13:13:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2008/07/31/57671.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/57671.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2008/07/31/57671.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/57671.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/57671.html</trackback:ping><description><![CDATA[<h3 class=post-title>What's wrong with CS research <a title="external link" href="http://unqualified-reservations.blogspot.com/2007/08/whats-wrong-with-cs-research.html"></a></h3>
<div class=post-body>
<div style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">The other day I was glaring obsessively at my sad, dwindling traffic numbers, and I noticed that a couple of weeks ago someone seems to have sent my post on the <a href="http://unqualified-reservations.blogspot.com/2007/07/my-navrozov-moments.html"><font color=#5588aa>decline and fall of the American university system</font></a> to <a href="http://programming.reddit.com/"><font color=#5588aa>reddit.programming</font></a>, where it got - I thought quite amusingly - 46 "upvotes" and 36 "downvotes."<br><br>Obviously, UR is not a programming blog. And in a post that warms up with a 75-mile-long blockquote about Hegel, I didn't really think of myself as writing for a technical audience. Technical audiences are not to be underrated, however, and I've noticed that a lot of UR readers are in this category. So I thought I'd say a few more words about CS research.<br><br>This is not a subject that interests all. And if it doesn't interest you, no one can conceivably require you to read about it. And I recommend you just skip this post.<br><br>First, the <a href="http://programming.reddit.com/info/25o3x/comments"><font color=#5588aa>Reddit comment thread</font></a> raised various criticisms which I didn't see in time to refute. Let me start by answering two of these points, and sneakily segue into what I think is wrong with CS research.<br><br>One: Guy Steele is a system software designer, not a PL researcher. In other words, he is in a class with Dennis Ritchie, Alan Kay, Brendan Eich, John McCarthy, John Warnock, John Ousterhout, Bjarne Stroustrup, Rob Pike, Larry Wall, Ted Codd, Tim Berners-Lee, Leslie Lamport, Ken Thompson, Dave Cutler, Sergey Brin, Luis von Ahn, Guido van Rossum, Linus Torvalds, and anyone else who has designed fundamental architectural components of code which everyone on earth points their CPU at a zillion times a day. Frankly, these men are heroes. They are <span style="FONT-STYLE: italic">literally warriors of God</span>. And anyone who insults them is an asshole.<br><br>I'm sure some of the above individuals - perhaps even most - were, at some time in their long and productive careers, funded by various grants or other sweetheart deals with the State. For that matter, I'm sure few if any of them would endorse the extreme opinions I express below. But if anyone with a forehead steeper than a halfpipe has ever described their work as, for example, "grant-savvy," I am a Cape buffalo.<br><br>So here's the first thing that's wrong with CS research: there's no such thing as CS research. First, there is no such thing as "computer science." Except for a few performance tests and the occasional usability study, nothing any CS researcher does has anything to do with the Scientific Method. Second, there is no such thing as "research." Any activity which is not obviously productive can be described as "research." The word is entirely meaningless. All just semantics, of course, but it's hardly a good sign that even the <span style="FONT-STYLE: italic">name</span> is fraudulent.<br><br>When we look at what "CS researchers" actually do, we see three kinds of people. We can describe them roughly as <span style="FONT-STYLE: italic">creative programmers</span>, <span style="FONT-STYLE: italic">mathematicians</span>, and <span style="FONT-STYLE: italic">bureaucrats</span>.<br><br><span style="FONT-STYLE: italic">Creative programmers</span> write interesting, cool, and relevant software. The only workable system for generating interesting, cool, and relevant software is well-known. Find a bunch of really smart programmers and point them at a large problem space for which there are actual users, and for which new solutions are unconstrained by old designs. Give them a manager who's just as smart and knows how and when to stay out of their way, and turn them loose.<br><br>Depending on the people and the problem, this approach may or may not produce results. But certainly nothing else will. More or less the above strategy was followed at the MIT AI Lab, at Bell Labs in the early Unix days, at Engelbart's lab, at Xerox PARC, at Berkeley CSRG, etc. It produced most of the aforementioned pioneers of system software.<br><br>And it is the <span style="FONT-STYLE: italic">farthest possible thing</span> from academic CS research as practiced today, which I think is the main reason why we see so little good come out of the field.<br><br>Of course, creative programmers can be hard to inhibit. Academic CS programs do bring together a lot of very smart people, and sometimes they still get out of control and actually build something useful. Thus, for example, Google. Note that the idea that became Google was not a part of anyone's research project, it was not assigned by Page and Brin's advisors, it had no Principal Investigator, it was just interesting, cool and relevant software.<br><br>As a general rule, this sort of thing can only happen in the first couple years of grad school, in which your basic purpose in life is to learn all the things they forgot to teach you as an undergrad. After that you are sucked into the apparat, and unless you are very good at working the system, your power to work on random cool stuff disappears. If you are extremely lucky and successful, it may reappear in fifteen years, when you have your own empire. But most creative people don't have the patience to play this game.<br><br>The problem is the funding. The reason why CS research produces so little that can be called creative programming these days is that the modern process of grant-funded research is fundamentally incompatible with the task of writing interesting, cool and relevant software. Rather, its goal is to produce publications and careers, and it's very good at that. As we'll see when we get to the <span style="FONT-STYLE: italic">bureaucrats</span>.<br><br>But because of this problem, most creative programming these days comes from free-software programmers working in their spare time. For example, the most interesting new software projects I know of are revision control systems, such as darcs, Monotone, Mercurial, etc. As far as Washington knows, this problem doesn't even exist. And yet the field has developed wonderfully.<br><br>It's very difficult for creative programmers in the academic CS world to compete with those in the free-software world. Academics have one advantage: money. Free-software programmers have another: freedom. Ideally one would have both, but if you have to pick, pick freedom. If you look at the salary of a grad student or a postdoc, it's not that hard to support yourself at the same standard of living by working intermittently in the corporate salt mines. Besides, you might actually learn something.<br><br>Next we have the <span style="FONT-STYLE: italic">mathematicians</span>, who prove interesting, cool, and relevant propositions. Unfortunately, most of the really interesting, cool, and relevant propositions in computational mathematics were proved before 1960, but there is still some fun stuff left. Genuine computational mathematics typically goes under the name "algorithms" in CS, although cryptography is also of course math.<br><br>Obviously, computational mathematics and creative programming are only barely related. In my humble opinion, if something is math, it should be in the math department. As we'll see, managing math and programming as if they were one field has produced disastrous results.<br><br>This brings us to the third group, the <span style="FONT-STYLE: italic">bureaucrats</span>. Bureaucrats build academic empires which churn out meaningless solutions to irrelevant problems.<br><br>The CS-research bureaucrat's main difficulty is that no one wants to fund bureaucrats. Therefore, he must pretend to be either a creative programmer or a mathematician, preferably both. Since this task is critical to his survival, he is extremely good at it.<br><br>The bureaucrat has many strategies. But probably his best is to take an area of creative programming and devour it like a locust, by turning it into a form of mathematics.<br><br>Math outcompetes creative programming in the funding process, simply because it appears to be more rigorous. It <span style="FONT-STYLE: italic">is</span> more rigorous, and it generates a longer, deeper river of more impressive publications. And, because its area is nominally applied, it doesn't have to compete with the real mathematicians over in "algorithms," who would clean the bureaucrats' clocks in five minutes.<br><br>The problem with math is that there's an infinite supply of it. It is always possible to create new problems to solve and new formalisms to apply. Math is always interesting and cool, at least to mathematicians, and after your field has been parasitized by mathematicians for a decade or two, everyone in it will be a mathematician. There's enough work for everyone.<br><br>It's possible to describe anything in mathematical notation. I recall seeing some paper once in which someone had created a mathematical description of C. (I forget whether or not this included the preprocessor.) As an achievement, this is somewhat like building a full-size model of the Eiffel Tower out of tongue depressors. It's clearly not the act of a talentless man, but you have to wonder what he said when he applied for his grant.<br><br>Whatever their tactics, what CS bureaucrats always sacrifice is relevance. Of course everyone has a conscience, and everyone would like to be actually relevant. But, especially when the only people checking up are your own godfathers in the funding agencies, it's much easier to pretend to be relevant. Actual relevance is extremely difficult to achieve, and hardly rewarding at all. In fact it's embarrassing, because everyone who isn't relevant and knows it has an automatic grudge against you. Since CS research is quite competitive, evolution has its way, and relevance goes the way of the snake's legs.<br><span style="FONT-STYLE: italic"></span><br>When the responsibility of relevance has been lifted, it's easy to write as many interesting and cool papers as you like. The point of these papers is to prove that you, the researcher, are smart. Of course, not only would the world be a much better place if a smart person such as yourself was working on something relevant, but you yourself would be having more fun. But this is the trap.<br><br>No field has been more infested by irrelevant formalisms than that of programming languages - also known as "PL research." So when I say Guy Steele isn't a PL researcher, what I mean is that he's not a bureaucrat. Rather, he's a creative programmer who writes interesting, cool, and relevant software, which happens to consist of programming languages.<br><br>The only way to understand the horrific trainwreck that is PL research is to actually look, in detail, at the ways it's discarded relevance in favor of irrelevance. To that end, let me answer another of the Reddit readers' complaints.<br><br>So, two: it was perhaps a little light-hearted of me to describe proof-carrying code as the world's most pointless compression scheme. But the argument is basically accurate.<br><br>The whole idea of <a href="http://en.wikipedia.org/wiki/Proof-carrying_code"><font color=#5588aa>proof-carrying code</font></a> is that it's a binary format for executable code whose correctness can be automatically verified. The term cannot imply a source format, because a source format whose correctness can be automatically verified is best known as a "type-safe programming language."<br><br>Such a binary format is useful because it saves CPU cycles across the entire network. If the source format can be verified but the binary can't - a trivial, and generally universal, property of anything anyone could describe as a "compiler" - obviously, you cannot ensure correctness unless you send the source rather than the binary. This requires you to perform the same compilation step on every machine for every piece of code it runs. An obvious, and obviously massive, source of global inefficiency.<br><br>Unfortunately for the researchers working on this problem, now and for the foreseeable future, the cost of client-side compilation is quite moot. It may have mattered at a time when computers were much slower. In fact, I will go so far as to say it probably did matter, say, as recently as 1990. However, with modern incremental compilation it is not even worth considering. Everyone who browses the web is compiling code from source, with every click. What is HTML? What is Javascript? Not chopped liver. Source-based systems have won, because they are simply simpler - they pass what Rohit Khare calls the "<a href="http://www.ics.uci.edu/~rohit/IEEE-L7-applcore.html"><font color=#5588aa>telnet test</font></a>" - and they are easily fast enough on any modern machine.<br><br>If you can check the source but you can't check the binary, it's probably better to just send the source. If the binary is smaller than the source, a naive compression algorithm should do pretty well, too. If you like the fact that the binary is opaque and hard to decompile, it's not at all hard to write a shrouder (automatic code obfuscator) that achieves the same goals. If you want to support multiple source languages, pick one which covers the entire feature space of the binary verifier, and compile the others to it instead. If all this fails and you really need secure binaries, use a cryptographic signing service. (People who <span style="FONT-STYLE: italic">really care</span> might enjoy this <a href="http://www.research.att.com/~trevor/PCC2000/panel.html"><font color=#5588aa>amusing discussion</font></a> of "The Future of PCC" from 2000.)<br><br>Because the price of PCC or anything like it is inevitably a file format whose definition is a 80-page LaTeX paper, including many strange, squiggly marks which for the average coder might as well be Sumerian cuneiform. There is a reason why IETF RFCs are ASCII-only, and at least the good ones are quite short. Therefore, the chance that PCC or any design involving it will ever be approvable by any standards process not involving a caoutchouc-based engraved ink applicator is, to put it mildly, remote. In standards, complexity is death.<br><br>Therefore, because the entire goal of a network protocol is to be standardized, PCC cannot possibly achieve its own goal. <span style="FONT-STYLE: italic"></span>And therefore, every CS researcher working on verification algorithms for generated code is wasting time at public expense.<br><br>There is a name for this. The name is <a href="http://en.wikipedia.org/wiki/Patronage"><span style="FONT-STYLE: italic"><font color=#5588aa>patronage</font></span></a>, and most historians consider it a criminal abuse of government power. CS research is only a tiny brick in the great pyramid of academic patronage that is the university and educational system, and yes - if you didn't, someone else would. But if you only steal a candybar, you're still a thief.<br><br>And this is what I think is wrong with CS research: it's best understood as a massive patronage scheme. Compared to all the other wholesale patronage operations run by our benign, caring masters, the financial cost of this particular scheme is relatively small. However, its human and economic cost is much higher, because it sucks in many young, talented people who could otherwise be engaged in productive work.<br><br>Again, any unproductive activity can be described as "research." There is no endeavor so obviously noble that its value to others cannot be evaluated. Nor is there any endeavor whose toilers will happily report to you that they're wasting their time, and their funding should be cut. There is no substitute for actual critical thinking.<br><br>If you feel the point is made, please feel free to skip to the end of the post. But if you think PCC may be an exception and you're looking for more examples, by all means, let's continue.<br><br>Again, the general problem in PL research is that it's been drowned in clouds of math, whose effect is not to create better languages, but to publish more papers. Specifically, PL research today is actually the study of something called "type theory," whose correspondence to what a naive person might consider research into programming languages - designing new languages for actual users to actually use - is extremely remote.<br><br>Type theory actually has nothing to do with computers or computing. It is the modern development of the project in metamathematics (the expression of mathematical statements in mathematical terms) that originated in the late 19th century and continued into the first half of the 20th, with researchers like Frege, Russell, and Church. In other words, it dates back to when "computer" was a job description. I rest my case.<br><br>You can model computing as metamathematics, of course. You can model computing as Tinkertoys. The whole point of <a href="http://en.wikipedia.org/wiki/Church%C3%A2%C2%80%C2%93Turing_thesis"><font color=#5588aa>Church-Turing equivalence</font></a> is that pretty much any recursive model you can build is an equivalent description of computing. The only reason the lambda calculus, and other such metamathematical approaches (such as defining programs as proofs) are so popular in the world of "CS research" are that "CS research" was largely founded by a land-rush of metamathematicians. The motivation for this migration is left as an exercise for the reader.<br><br>Of course, in a sense, anything you do with in a computer can be described as "mathematics." The point is not whether or not programming is math. The point is what notation is most effective for expressing programs. Choosing the best notation is the <span style="FONT-STYLE: italic">entire problem</span> of programming language design, and this problem is neither mathematical nor scientific. A programming language is a user interface for programmers, and if you can reduce UI design to math, science, or any formal process, call Apple, not me.<br><br>I happen to prefer the ASCII-based family of notations used by working programmers, which are clearly effective for encoding the transformations of state which all programs, functional or imperative, typed or unsafe, express. I don't see why anyone whose goal is to design, explain, or specify a programming language should be using any other notation than that of the language itself, and I don't see why any language needs any non-ASCII notation.<br><br>Even academic languages like Haskell and OCaml have ASCII notations, although researchers who write papers on them are still fond of their private symbol set. As a marketing strategy this approaches the genius of <a href="http://en.wikipedia.org/wiki/Crunchy_frog"><font color=#5588aa>Crunchy Frog</font></a>. Frankly, CS research is so distrusted outside its own ghetto that even posting your work as a PDF file (let alone ps.gz) is a big red flag. Break out the squiggles and it's pretty much curtains.<br><br>Anyway, if you want to learn about type theory, you can buy <a href="http://www.amazon.com/exec/obidos/ASIN/0262162091/benjamcpierce"><font color=#5588aa>Types and Programming Languages</font></a>, by Benjamin F. Pierce. If you are at all confused after this, you can clear up any difficulties with <a href="http://www.amazon.com/Advanced-Topics-Types-Programming-Languages/dp/0262162288"><font color=#5588aa>Advanced Topics in Types and Programming Languages</font></a>, by Benjamin F. Pierce. Presumably Professor Pierce is now working on "Further Reading in Types and Programming Languages," or "Extremely Advanced Topics in Types and Programming Languages."<br><br>Each of these tomes would make a fine textbook for a graduate class, or at least upper-level undergraduate, at a top-rank American university. Certainly, anyone who can master this material is qualified to teach undergraduate programming. I'd also say they're smart enough to take any other programming job - for example, they'd make good kernel hackers. If, of course, they were fully retrained to be masters of C (though many already are).<br><br>Meanwhile, you can explain the type system of C to a fifteen-year-old in a day. And C is almost certainly the most difficult programming language in use today, except C++. (I love C, but I have never much liked C++.) It takes a decent C programmer typically a good week or two to learn basic C++, although they often emit very nasty C-isms for quite some time thereafter.<br><br>Meanwhile, you can explain the type system of Python to a retarded nine-year-old in five minutes. I exaggerate, slightly.<br><br>This perhaps explains why <a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29"><font color=#5588aa>Python</font></a> was not designed by a PL researcher. Python was not designed by a PL researcher because Python would not impress other PL researchers. And since impressing your peers is the sine qua non of any academic discipline, any academic who designed something like Python (probably the closest similar case is Ousterhout's <a href="http://en.wikipedia.org/wiki/Tcl"><font color=#5588aa>Tcl</font></a>) would be doing it simply for their own private kicks - a perverse feat of intellectual masturbation, perhaps impressing the undergrads, but hardly a source of any actual professional prestige.<br><br>It also explains why <a href="http://en.wikipedia.org/wiki/Haskell_%28programming_language%29"><font color=#5588aa>Haskell</font></a> was not designed by Guido van Rossum (designer of Python). Mynheer van Rossum, who as far as I know dropped out of kindergarten, wanted to build a language that people would find useful. And he certainly did.<br><br>A programming language like Haskell, with a generally Piercean type system that takes a semester for even the smartest undergraduates to learn, is not useful. Because one of the key ingredients of victory in a language conflict - as in any other standards war - is how many people already use the language.<br><br>This conflict is unstable. It exhibits the <a href="http://en.wikipedia.org/wiki/Matthew_effect"><font color=#5588aa>Matthew Effect</font></a>. Since a language is a UI for programmers, a language that's hard to learn has a fatal and self-reinforcing disadvantage in this contest. There's no need to learn it, because it has no chance of winning the standards war. And thus it is not a good language.<br><br>Haskell actually is quite useful - in one context. It's an excellent teaching language for advanced students in a first-rate undergraduate CS program. Learning Haskell cannot help but teach you many challenging concepts, and it is inevitable that those who are both smart and dedicated will master these concepts. The rest will not. And thus the university system performs its principal function, the assignment of rank. If you venture to suggest that the same function could be performed, at two orders of magnitude less cost, by an IQ test and three weeks at Parris Island, you are probably some kind of a fascist.<br><br>Of course, the exponents of Haskell have an answer for this. They answer that since Haskell is so more elegant and powerful than the likes of Python, it can overcome all these problems.<br><br>I am certainly a fan of pure functional programming, which Haskell offers and Python does not. In theory, pure functional programming is actually simpler than imperative programming, because the former is a subset of the latter. However, the slight advantage of removing imperative features does not even begin to make up for the Eigerlike learning curve of Haskell, whose incredible and utterly-unwarranted complexity manifests itself in more ways than I can even begin to describe.<br><br>Let me describe one of these ways by examining one of the principal features of Haskell, which is what might be called "dynamic higher-order programming."<br><br>A language has "dynamic higher-order programming" when your programs can construct new functions dynamically at runtime. If you know a little about programming, this probably sounds esoteric, and for good reason. However, Haskell uses it all the time to do just about everything.<br><br>For example, in Haskell, when you write an add function - call it <span style="FONT-WEIGHT: bold">add()</span> - that adds two integers <span style="FONT-WEIGHT: bold">a</span> and <span style="FONT-WEIGHT: bold">b</span>, the proper and approved way to do it is to first dynamically construct a function - it will have no name, but call it <span style="FONT-WEIGHT: bold">add_a(x)</span> - that adds <span style="FONT-WEIGHT: bold">a</span> to some argument <span style="FONT-WEIGHT: bold">x</span>. Then you call <span style="FONT-WEIGHT: bold">add_a(b)</span>. This is called "currying" (after the mathematician <a href="http://en.wikipedia.org/wiki/Haskell_Curry"><font color=#5588aa>Haskell Curry</font></a>).<br><br>The motivation behind this bizarre obfuscation has always escaped me. Obviously it allows each function to have only a single argument, but it is pretty easy to write an <span style="FONT-WEIGHT: bold">add()</span> function whose single argument is a pair <span style="FONT-WEIGHT: bold">(a b)</span> - hardly a recondite data structure.<br><br>And it's not just that dynamic higher-order programming is overkill for <span style="FONT-WEIGHT: bold">add()</span>. It's overkill for anything. For example, one of the most touted uses of higher-order-programming is parser generation - as performed by systems like <a href="http://legacy.cs.uu.nl/daan/parsec.html"><font color=#5588aa>Parsec</font></a> in Haskell.<br><br>The idea of parser generation is, unsurprisingly, to generate a parser. A parser is a function whose input is a text file and whose output is a data structure. Obviously, parsing is the first stage in any process which involves converting source code into executable code, ie, compiling. No programming language, for example, can exist without a parser.<br><br>The trick is that if you write a parser just as a normal program, it tends to be extremely messy. A parser is really best described as a data structure called a <a href="http://en.wikipedia.org/wiki/Formal_grammar"><span style="FONT-STYLE: italic"><font color=#5588aa>grammar</font></span></a>, and a grammar - though it may include pieces of code - is not code at all, but its own data structure.<br><br>In most programming environments which are not language-specific, there is a separate tool (called <span style="FONT-WEIGHT: bold">yacc</span> in Unix) that automatically converts a grammar into a function written in a normal language. For example, <span style="FONT-WEIGHT: bold">yacc</span> converts a yacc grammar, typically a .y file, into a C program, or .c file.<br><br>Now the way <span style="FONT-WEIGHT: bold">yacc</span> works is a nasty process, because it involves generating source, and as a general rule it's always nasty to generate source. The Haskell model - in which the grammar is converted directly into a function, by a normal program in a language designed to build functions - seems much prettier.<br><br>And it is. However, there is only one problem - the function we build is the same every time. A language is a language. Its syntax is not dynamic. By definition, one parser function is sufficient for any program written in the language.<br><br>Therefore, we have no need for dynamic higher-order programming. All we need is <span style="FONT-STYLE: italic">static</span> higher-order programming. For every program, the parser generator must be run once per grammar. Granted, you might want to load grammars dynamically at runtime, but you might want to load any function dynamically at runtime. The solution to this problem is not dynamic function construction - it is dynamic module loading.<br><br>(Note that static higher-order programming is not at all inconsistent with a system of first-class functions, like function pointers in C, closures in Lisp, etc. In a language with first-class functions, you can store functions as variables in normal data structures, but this does not imply the ability to construct new functions.)<br><br>In fact, "static higher-order programming" has another name. It's a specialty of the older, and much simpler, Lisp language family. In Lisp and its many relatives, "static higher-order programs" are called <span style="FONT-STYLE: italic">macros</span>. Unsurprisingly, your average PL researcher looks at a macro pretty much the same way your average Parisian chef looks at an Outback Steakhouse.<br><br>Even forgetting the macros, it's pretty easy to see why you don't need dynamic higher-order programming. For example, a very common operation on functions is to <span style="FONT-STYLE: italic">compose</span> them - you have <span style="FONT-WEIGHT: bold">f(x)</span> and <span style="FONT-WEIGHT: bold">g(x)</span>, you make <span style="FONT-WEIGHT: bold">h(x)</span>, defined as <span style="FONT-WEIGHT: bold">f(g(x))</span>. In the right formal model, a compose operator is really no different from addition. And once you have first-class functions - which are not absolutely necessary, but certainly useful - it seems like a trivial extension.<br><br>But is it what you, the programmer, want to do? Actually, no. It is simply bad programming style. Its only effect is to make your program less comprehensible.<br><br>Because in a language with first-class functions but without dynamic higher-order programming, all you need to do is build a data structure which is the ordered pair <span style="FONT-WEIGHT: bold">(f(x) g(x))</span>, and define <span style="FONT-WEIGHT: bold">h(x)</span> as an operation on this structure. This may be slightly more cumbersome for the programmer. At least, if one line of code counts as "slightly more cumbersome."<br><br>But it has a big benefit, which is that you're dealing with a data structure and you know it. Strictly from the perspective of user experience, it's much easier to debug data structures than to debug dynamic code. This is also the reason why self-modifying code is a bad idea, at least from a software-engineering perspective, and the bad idea of dynamic higher-order programming can be seen as a corollary of this well-known conclusion.<br><br>Of course, it may be <span style="FONT-STYLE: italic">slightly</span> easier to optimize the result of dynamic code generation, because you can throw a generic runtime optimizer at it. But this comes back to the first problem, which is that, in practice, we only need static code generation. Whatever problem we are solving by constructing <span style="FONT-WEIGHT: bold">h(x)</span>, it is probably better solved by a macro, which would perform the same composition statically.<br><br>This entire problem space comes down to a single error in the metamathematical approach to computing, which is that the 1930s metamathematicians were fascinated by the fact that they could represent any data structure as a function. While this is <a href="http://en.wikipedia.org/wiki/Church_numeral"><font color=#5588aa>true</font></a>, to describe it as perverse is an insult to perverts.<br><br>Surely, if you were actually building a programming environment, rather than trying to express the fundamentals of mathematics, your main concern would be how to represent code as data, rather than the other way around. (Again, this is the Lisp approach.)<br><br>Defining data as dynamic higher-order functions worked badly when most computing was standalone. And it works even worse now that we have these things called networks. The problem is that a dynamic higher-order function is a sort of ethereal construct, a speck of four-dimensional pixie dust, and the idea of saving it to disk or sending it over the network does not make any particular sense.<br><br>The few people who actually try to use the metamathematical languages for real work struggle manfully to get around this - for example, at <a href="http://www.janestcapital.com/tech.html"><font color=#5588aa>Jane Street Capital</font></a>, an <a href="http://en.wikipedia.org/wiki/OCaml"><font color=#5588aa>OCaml</font></a> shop, <a href="http://www.haskell.org/sitewiki/images/0/03/TMR-Issue7.pdf"><font color=#5588aa>they use a source preprocessor</font></a> to compose Lisp-style versions of their types. A thing of beauty is a joy forever. A source preprocessor is not a thing of beauty.<br><br>Okay. Let's rise slightly above this rant, and survey the wreckage. The problem, again, is that taxpayer funds are being used to employ some of the world's most brilliant and energetic people to do work of no conceivable practical utility. Perhaps it may have some serendipitous benefit, but surely if the same people were working on relevant problems they would produce much more useful results.<br><br>How can such a thing happen? How did this disastrous patronage system come to exist? Was it anyone's evil plot?<br><br>Not at all. It's just the effect of treating something that isn't a science as if it was a science. Confucius, if I may quote my namesake's teacher, said that if he were given a chance to reform the state, his first act would be to make sure all things had their proper names.<br><br>I think the world could use a charity that funds creative programming. The software systems that people use today - don't even start me on "Web 2.0" - are awful and ancient, and hardly anyone has any reasonable plan to improve them. Free-software programmers are not at all bad at supporting themselves, but nothing like Xerox PARC exists today, and it should.<br><br>But the US Government is not a charity, and creative programming is not "computer science." And the result of treating these things as if they were things that they aren't is abominable. It's the morass of busywork, waste and fraud that is CS research today. By far the simplest treatment for this mess is to just abolish it.<br><br>Because anyone who's not involved in CS research treats the products of this endeavor as if they were smallpox-infected blankets. Even when it is clearly - in my opinion - good, it winds up ignored. Because of the inescapable grant-related propaganda, it's impossible to tell what's good and what's not.<br><br>For example, recently some of the same people involved in the PL research I so dislike built a language called <a href="http://en.wikipedia.org/wiki/Cyclone_programming_language"><font color=#5588aa>Cyclone</font></a>, which adds some very useful safety features to C. There are still zillions of free-software projects written in C, and probably most of them could benefit from upgrading to Cyclone. But the thing has the academic kiss of death on it, and no one will touch it. The mailing list is virtually empty.<br><br>This is not just prejudice. It is rational mistrust. Academics, as we've seen, have no incentive to build software that's actually relevant, and every incentive to build software that appears to be relevant. They have every incentive to overpromote, and no incentive at all to build an actual user base. In fact, an actual user base is an enormous drag for a CS researcher, because it demands actual support, which does not advance the researcher's career at all. Also, because of the nefarious <a href="http://en.wikipedia.org/wiki/Bayh-Dole_Act"><font color=#5588aa>Bayh-Dole</font></a> act, CS researchers are frequently armwrestled into patenting their work, which of course they have no incentive to disclose. If the rest of these factors didn't give you a reason not to use academic software, this certainly would.<br><br>The result is a world of Potemkin software which appears to be enormously useful, even revolutionary. In reality it is unusable. The researchers are some of the smartest people in the world, and surely some of what they're doing has some merit. But it is almost impossible to figure out what's wheat and what's chaff, and most sensible people just don't come near it.<br><br>For example, maybe seven years ago I was in a design meeting at a small company which was at the time the unquestioned innovation leader in its field, mobile Web browsing. (I admit that this is a pathetic field to be an "innovation leader" in, and in fact most of our "innovations" turned out to be worthless. I'm just describing the perception here, not the reality.)<br><br>The conversation turned to something and one employee, Patrick, who'd been recently poached from Nokia and didn't know the vibe, said "maybe we could research that."<br><br>Bruce, the CTO, promptly said: "if Alain [the CEO] heard you use that word, he'd rip off your head and spit down your neck."<br><br>I said, "I take back everything bad I ever said about Alain." </div>
</div>
<p class=post-footer><a href="http://unqualified-reservations.blogspot.com/2007/08/whats-wrong-with-cs-research.html">http://unqualified-reservations.blogspot.com/2007/08/whats-wrong-with-cs-research.html</a><font face="Trebuchet MS" color=#999999 size=2></font></p>
<img src ="http://www.cppblog.com/cfmonkey/aggbug/57671.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2008-07-31 21:13 <a href="http://www.cppblog.com/cfmonkey/archive/2008/07/31/57671.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[WxPython笔记2] after Hello world</title><link>http://www.cppblog.com/cfmonkey/archive/2008/05/22/50710.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Wed, 21 May 2008 16:48:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2008/05/22/50710.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/50710.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2008/05/22/50710.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/50710.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/50710.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">#</span><span style="COLOR: #008000">&nbsp;2008&nbsp;.&nbsp;May.&nbsp;21</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;wx<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MyFrame(wx.Frame):<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;title,&nbsp;pos,&nbsp;size):<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wx.Frame.</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;None,&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;title,&nbsp;pos,&nbsp;size)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;menuFile&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;wx.Menu()&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;menuFile.Append(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">&amp;About<img src="http://www.cppblog.com/Images/dot.gif"></span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;menuFile.AppendSeparator()&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;menuFile.Append(</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">E&amp;xit</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;menuBar&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;wx.MenuBar()&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;menuBar.Append(menuFile,&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">&amp;File</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.SetMenuBar(menuBar)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.CreateStatusBar()&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.SetStatusText(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Welcome&nbsp;to&nbsp;wxPython!</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.Bind(wx.EVT_MENU,&nbsp;self.OnAbout,&nbsp;id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.Bind(wx.EVT_MENU,&nbsp;self.OnQuit,&nbsp;id</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;OnQuit(self,&nbsp;event):&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.Close()&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;OnAbout(self,&nbsp;event):&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wx.MessageBox(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">This&nbsp;is&nbsp;a&nbsp;wxPython&nbsp;Hello&nbsp;world&nbsp;sample</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">About&nbsp;Hello&nbsp;World</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,&nbsp;wx.OK&nbsp;</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">&nbsp;wx.ICON_INFORMATION,&nbsp;self)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MyApp(wx.App):<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;OnInit(self):<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.frame&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;MyFrame(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">hello&nbsp;world</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;(</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">60</span><span style="COLOR: #000000">),&nbsp;(</span><span style="COLOR: #000000">450</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">340</span><span style="COLOR: #000000">))<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.frame.Show()<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.SetTopWindow(self.frame)<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;True<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__name__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">__main__</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;app&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;MyApp(False)&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;app.MainLoop()&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<br>Most of the wxPython toolkit is accessed through the <span style="COLOR: #ff6600">wx</span> package which you <br>access using the<span style="COLOR: #ff6600"> import wx</span> statement. Every wxPython program must have <br>an application object—an instance of&nbsp; a <span style="COLOR: #ff6600">wx.App</span> subclass that defines an <br><span style="COLOR: #ff6600">OnInit()</span> method. Most wxPython programs will have one or more <br>frames—instances of subclasses of <span style="COLOR: #ff6600">wx.Frame</span>. A frame is the large, movable, <br>resizeable window-like container that appears on screen, often with a menu, <br>status bar, tool bars, and other widgets. Control of your program passes to <br>wxPython when you call your application&#8217;s <span style="COLOR: #ff6600">MainLoop()</span> method. <br><br><img height=250 alt="" src="http://www.cppblog.com/images/cppblog_com/cfmonkey/wxpython_win.jpg" width=372 border=0>
<img src ="http://www.cppblog.com/cfmonkey/aggbug/50710.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2008-05-22 00:48 <a href="http://www.cppblog.com/cfmonkey/archive/2008/05/22/50710.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分形图[1]</title><link>http://www.cppblog.com/cfmonkey/archive/2008/05/12/49613.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Mon, 12 May 2008 02:26:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2008/05/12/49613.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/49613.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2008/05/12/49613.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/49613.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/49613.html</trackback:ping><description><![CDATA[<img height=159 alt="" src="http://www.cppblog.com/images/cppblog_com/cfmonkey/SNAG-063.jpg" width=162 border=0><br><br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;wx<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>dc&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;wx.PaintDC(self)<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>dc.SetPen(wx.Pen(wx.Colour(</span><span style="COLOR: #000000">66</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">77</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">88</span><span style="COLOR: #000000">,&nbsp;wx.ALPHA_OPAQUE)))<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>dc.SetBrush(wx.Brush(wx.Colour(</span><span style="COLOR: #000000">66</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">77</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">88</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">128</span><span style="COLOR: #000000">)))<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;drawFrac(xcenter,&nbsp;ycenter,&nbsp;bdim):<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;side&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;bdim</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;side&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;left&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;xcenter&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;side</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;top&nbsp;&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;ycenter&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;side</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;right&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;xcenter&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;side</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;bottom&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;ycenter&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;side</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;drawFrac(left,&nbsp;top,&nbsp;bdim</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;drawFrac(left,&nbsp;bottom,&nbsp;bdim</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;drawFrac(right,&nbsp;top,&nbsp;bdim</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;drawFrac(right,&nbsp;bottom,&nbsp;bdim</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">23</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;dc.DrawRectangle(left,&nbsp;top,&nbsp;right</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">left,&nbsp;bottom</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">top)<br></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>drawFrac(</span><span style="COLOR: #000000">200</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">200</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">300</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">27</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<img src ="http://www.cppblog.com/cfmonkey/aggbug/49613.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2008-05-12 10:26 <a href="http://www.cppblog.com/cfmonkey/archive/2008/05/12/49613.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>GCC内嵌汇编</title><link>http://www.cppblog.com/cfmonkey/archive/2008/02/26/43236.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Mon, 25 Feb 2008 16:31:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2008/02/26/43236.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/43236.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2008/02/26/43236.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/43236.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/43236.html</trackback:ping><description><![CDATA[&nbsp;在内嵌汇编中，可以将C语言表达式指定为汇编指令的操作数，而且不用去管如何将C语言表达式的值读入哪个寄存器，以及如何将计算结果写回C 变量，你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可， GCC会自动插入代码完成必要的操作。 <br><br>1、简单的内嵌汇编 <br>例： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__ __volatile__("hlt"); &#8220;__asm__&#8221;表示后面的代码为内嵌汇编，&#8220;asm&#8221;是&#8220;__asm__&#8221;的别名。&#8220;__volatile__&#8221;表示编译器不要优化代码，后面的指令保留原样，&#8220;volatile&#8221;是它的别名。括号里面是汇编指令。 <br>
<p>&nbsp;在内嵌汇编中，可以将C语言表达式指定为汇编指令的操作数，而且不用去管如何将C语言表达式的值读入哪个寄存器，以及如何将计算结果写回C 变量，你只要告诉程序中C语言表达式与汇编指令操作数之间的对应关系即可， GCC会自动插入代码完成必要的操作。 <br><br>1、简单的内嵌汇编 <br>例： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__ __volatile__("hlt"); &#8220;__asm__&#8221;表示后面的代码为内嵌汇编，&#8220;asm&#8221;是&#8220;__asm__&#8221;的别名。&#8220;__volatile__&#8221;表示编译器不要优化代码，后面的指令保留原样，&#8220;volatile&#8221;是它的别名。括号里面是汇编指令。 <br><br>2、内嵌汇编举例 <br>&nbsp;&nbsp;使用内嵌汇编，要先编写汇编指令模板，然后将C语言表达式与指令的操作数相关联，并告诉GCC对这些操作有哪些限制条件。例如在下面的汇编语句： <br>&nbsp;&nbsp;&nbsp;__asm__ __violate__ ("movl %1,%0" : "=r" (result) : "m" (input)); &nbsp; <br><br>&#8220;movl %1,%0&#8221;是指令模板；&#8220;%0&#8221;和&#8220;%1&#8221;代表指令的操作数，称为占位符，内嵌汇编靠它们将C 语言表达式与指令操作数相对应。指令模板后面用小括号括起来的是C语言表达式，本例中只有两个：&#8220;result&#8221;和&#8220;input&#8221;，他们按照出现的顺序分别与指令操作数&#8220;%0&#8221;，&#8220;%1&#8221;对应；注意对应顺序：第一个C 表达式对应&#8220;%0&#8221;；第二个表达式对应&#8220;%1&#8221;，依次类推，操作数至多有10 个，分别用&#8220;%0&#8221;,&#8220;%1&#8221;&#8230;.&#8220;%9&#8221;表示。在每个操作数前面有一个用引号括起来的字符串，字符串的内容是对该操作数的限制或者说要求。&#8220;result&#8221;前面的限制字符串是&#8220;=r&#8221;，其中&#8220;=&#8221;表示&#8220;result&#8221;是输出操作数，&#8220;r&#8221;表示需要将&#8220;result&#8221;与某个通用寄存器相关联，先将操作数的值读入寄存器，然后在指令中使用相应寄存器，而不是&#8220;result&#8221;本身，当然指令执行完后需要将寄存器中的值存入变量&#8220;result&#8221;，从表面上看好像是指令直接对&#8220;result&#8221;进行操作，实际上GCC做了隐式处理，这样我们可以少写一些指令。&#8220;input&#8221;前面的&#8220;r&#8221;表示该表达式需要先放入某个寄存器，然后在指令中使用该寄存器参加运算。 <br>&nbsp;&nbsp;C表达式或者变量与寄存器的关系由GCC自动处理，我们只需使用限制字符串指导GCC如何处理即可。限制字符必须与指令对操作数的要求相匹配，否则产生的汇编代码将会有错，读者可以将上例中的两个&#8220;r&#8221;，都改为&#8220;m&#8221;(m表示操作数放在内存，而不是寄存器中)，编译后得到的结果是： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movl input, result <br>很明显这是一条非法指令，因此限制字符串必须与指令对操作数的要求匹配。例如指令movl允许寄存器到寄存器，立即数到寄存器等，但是不允许内存到内存的操作，因此两个操作数不能同时使用&#8220;m&#8221;作为限定字符。 <br>内嵌汇编语法如下： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__(汇编语句模板: 输出部分: 输入部分: 破坏描述部分) <br>共四个部分：汇编语句模板，输出部分，输入部分，破坏描述部分，各部分使用&#8220;:&#8221;格开，汇编语句模板必不可少，其他三部分可选，如果使用了后面的部分，而前面部分为空，也需要用&#8220;:&#8221;格开，相应部分内容为空。例如： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__ __volatile__("cli": : :"memory") <br><br>1、汇编语句模板 <br>&nbsp;&nbsp;&nbsp;汇编语句模板由汇编语句序列组成，语句之间使用&#8220;;&#8221;、&#8220;\n&#8221;或&#8220;\n\t&#8221;分开。指令中的操作数可以使用占位符引用C语言变量，操作数占位符最多10个，名称如下：%0，%1，&#8230;，%9。指令中使用占位符表示的操作数，总被视为long型（4个字节），但对其施加的操作根据指令可以是字或者字节，当把操作数当作字或者字节使用时，默认为低字或者低字节。对字节操作可以显式的指明是低字节还是次字节。方法是在%和序号之间插入一个字母，&#8220;b&#8221;代表低字节，&#8220;h&#8221;代表高字节，例如：%h1。 <br><br>2、输出部分 <br>&nbsp;&nbsp;&nbsp;输出部分描述输出操作数，不同的操作数描述符之间用逗号格开，每个操作数描述符由限定字符串和C 语言变量组成。每个输出操作数的限定字符串必须包含&#8220;=&#8221;表示他是一个输出操作数。 <br>例： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x) ) <br>描述符字符串表示对该变量的限制条件，这样GCC 就可以根据这些条件决定如何分配寄存器，如何产生必要的代码处理指令操作数与C表达式或C变量之间的联系。 <br><br>3、输入部分 <br>输入部分描述输入操作数，不同的操作数描述符之间使用逗号格开，每个操作数描述符由限定字符串和C语言表达式或者C语言变量组成。 <br>例1 ： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt)); <br>例二（bitops.h）： <br>Static __inline__ void __set_bit(int nr, volatile void * addr) <br>{ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__asm__( <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"btsl %1,%0" <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:"=m" (ADDR) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:"Ir" (nr)); <br>} <br><br>后例功能是将(*addr)的第nr位设为1。第一个占位符%0与C 语言变量ADDR对应，第二个占位符%1与C语言变量nr对应。因此上面的汇编语句代码与下面的伪代码等价：btsl nr, ADDR，该指令的两个操作数不能全是内存变量，因此将nr的限定字符串指定为&#8220;Ir&#8221;，将nr 与立即数或者寄存器相关联，这样两个操作数中只有ADDR为内存变量。 <br><br>4、限制字符 <br>&nbsp;&nbsp;4.1、限制字符列表 <br>&nbsp;&nbsp;限制字符有很多种，有些是与特定体系结构相关，此处仅列出常用的限定字符和i386中可能用到的一些常用的限定符。它们的作用是指示编译器如何处理其后的C语言变量与指令操作数之间的关系。 <br><br>&nbsp;&nbsp;分类 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;限定符 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;描述 <br>&nbsp;通用寄存器 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;a&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入eax <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这里有一个问题：假设eax已经被使用，那怎么办？ <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其实很简单：因为GCC 知道eax 已经被使用，它在这段汇编代码 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;的起始处插入一条语句pushl %eax，将eax 内容保存到堆栈，然 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后在这段代码结束处再增加一条语句popl %eax，恢复eax的内容 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;b&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入ebx <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;c&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入ecx <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;d&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入edx <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;s&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入esi <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;d&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入edi <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;q&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入eax，ebx，ecx，edx中的一个 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;r&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入通用寄存器，也就是eax，ebx，ecx， <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;edx，esi，edi中的一个 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;A&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;把eax和edx合成一个64 位的寄存器(use long longs) <br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;内存 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;m&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;内存变量 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;o&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作数为内存变量，但是其寻址方式是偏移量类型， <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;也即是基址寻址，或者是基址加变址寻址 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;V&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作数为内存变量，但寻址方式不是偏移量类型 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220; &#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作数为内存变量，但寻址方式为自动增量 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;p&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作数是一个合法的内存地址（指针） <br><br>&nbsp;&nbsp;&nbsp;&nbsp;寄存器或内存 &nbsp;&nbsp;&nbsp;&#8220;g&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;将输入变量放入eax，ebx，ecx，edx中的一个 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;或者作为内存变量 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;X&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作数可以是任何类型 <br><br>&nbsp;&nbsp;&nbsp;&nbsp;立即数 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;I&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0-31之间的立即数（用于32位移位指令） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;J&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0-63之间的立即数（用于64位移位指令） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;N&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0-255之间的立即数（用于out指令） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;i&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;立即数 &nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;n&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;立即数，有些系统不支持除字以外的立即数， <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这些系统应该使用&#8220;n&#8221;而不是&#8220;i&#8221; <br><br>&nbsp;&nbsp;&nbsp;&nbsp;匹配 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220; 0 &#8221;， &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;表示用它限制的操作数与某个指定的操作数匹配， <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;1&#8221; ... &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;也即该操作数就是指定的那个操作数，例如&#8220;0&#8221; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;9&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;去描述&#8220;％1&#8221;操作数，那么&#8220;%1&#8221;引用的其实就 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;是&#8220;%0&#8221;操作数，注意作为限定符字母的0－9 与 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;指令中的&#8220;％0&#8221;－&#8220;％9&#8221;的区别，前者描述操作数， <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;后者代表操作数。 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;该输出操作数不能使用过和输入操作数相同的寄存器 <br><br>&nbsp;&nbsp;&nbsp;操作数类型 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;=&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作数在指令中是只写的（输出操作数） &nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;+&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;操作数在指令中是读写类型的（输入输出操作数） <br><br>&nbsp;&nbsp;&nbsp;&nbsp;浮点数 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;f&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;浮点寄存器 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;t&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第一个浮点寄存器 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;u&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;第二个浮点寄存器 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#8220;G&#8221; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;标准的80387浮点常数 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;% &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;该操作数可以和下一个操作数交换位置 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;例如addl的两个操作数可以交换顺序 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;（当然两个操作数都不能是立即数） <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;部分注释，从该字符到其后的逗号之间所有字母被忽略 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;表示如果选用寄存器，则其后的字母被忽略 <br><br>5、破坏描述部分 <br>&nbsp;&nbsp;破坏描述符用于通知编译器我们使用了哪些寄存器或内存，由逗号格开的字符串组成，每个字符串描述一种情况，一般是寄存器名；除寄存器外还有&#8220;memory&#8221;。例如：&#8220;%eax&#8221;，&#8220;%ebx&#8221;，&#8220;memory&#8221;等。 <br></p>
<img src ="http://www.cppblog.com/cfmonkey/aggbug/43236.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2008-02-26 00:31 <a href="http://www.cppblog.com/cfmonkey/archive/2008/02/26/43236.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Common Project Subdirectory Names Directory</title><link>http://www.cppblog.com/cfmonkey/archive/2007/08/05/29368.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Sat, 04 Aug 2007 19:14:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2007/08/05/29368.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/29368.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2007/08/05/29368.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/29368.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/29368.html</trackback:ping><description><![CDATA[<table cellSpacing=0 cellPadding=5 rules=groups width="100%" frame=hsides>
    <caption>
    <h5 class=docTableTitle>Common Project Subdirectory Names</h5>
    </caption>
    <colgroup span=2 align=left>
    <thead>
        <tr>
            <th class=docTableHeader vAlign=center>
            <p class=docText><span class=docEmphStrong>Directory</span></p>
            </th>
            <th class=docTableHeader vAlign=center align=middle>
            <p class=docText><span class=docEmphStrong>Contents</span></p>
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">src</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Source code</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">TLD (e.g., <span style="COLOR: #993300">org</span> or<span style="COLOR: #993300"> edu</span>)</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Root of Java source code</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">main</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Source code for the main program; platform-independent, excludes libraries</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">program-name</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Source code for program-name</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">lib</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Library source code</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">lib<span style="COLOR: #808000"><em>name</em></span></p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Library name source code</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">common</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Code elements shared between applications</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">include</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Common C and C++ header files</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">doc</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Documentation</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">man</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Unix manual pages</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">rc / res</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Microsoft Windows (bitmaps, resource files dialogs, icons) in source/compiled form</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">arch</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Code specific to a given processor architecture</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">os</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Operating system&#8211;specific code</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">CVS / RCS / SCCS</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Revision control system files</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">build / compile / classes / obj / Release / Debug</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Compilation directory</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">tools</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Tools used during the build process</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">test</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Test scripts and input and output files</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">conf</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Buildtime configuration information</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">etc</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Runtime configuration information</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">eg</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Examples</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt; COLOR: #993300">bin</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">Depository for executable files and shell scripts</p>
            </td>
        </tr>
        <tr>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">contrib</p>
            </td>
            <td style="FONT-SIZE: 10pt" vAlign=top>
            <p style="FONT-SIZE: 10pt">User-contributed tools and code; typically maintained outside the main project</p>
            </td>
        </tr>
    </tbody>
</table>
<img src ="http://www.cppblog.com/cfmonkey/aggbug/29368.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2007-08-05 03:14 <a href="http://www.cppblog.com/cfmonkey/archive/2007/08/05/29368.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux内核编程风格</title><link>http://www.cppblog.com/cfmonkey/archive/2007/07/21/28534.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Sat, 21 Jul 2007 15:39:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2007/07/21/28534.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/28534.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2007/07/21/28534.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/28534.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/28534.html</trackback:ping><description><![CDATA[<p></p> <p><b><a title="http://www.linuxforum.net/forum/gshowflat.php?Cat=&amp;Board=program&amp;Number=393381&amp;page=7&amp;view=collapsed&amp;sb=5&amp;o=all&amp;fpart=" href="http://www.linuxforum.net/forum/gshowflat.php?Cat=&amp;Board=program&amp;Number=393381&amp;page=7&amp;view=collapsed&amp;sb=5&amp;o=all&amp;fpart=">http://www.linuxforum.net/forum/gshowflat.php?Cat=&amp;Board=program&amp;Number=393381&amp;page=7&amp;view=collapsed&amp;sb=5&amp;o=all&amp;fpart=</a></b> <p><b></b>&nbsp; <p>原文见 /usr/src/linux/Documentation/CodingStyle。 <pre><b>		Linux内核编程风格</b></pre><br>这篇短小的文档用于描述linux内核编程中推荐的编程风格。编程风格是很个人 <br>化的东西，我不想把我的观点_强加_给任何人，但这是我必须维护的代码中所遵守 <br>的，我也建议其他部分的代码也能遵守它。请至少给这里的观点一些考虑。 <br>首先，我建议你打印一份GNU代码风格，不是去读它，而是把它烧了，这是个很 <br>不错的姿态。 <br>不废话了，下面就是Linux内核编程风格： <pre><b>		第一章：缩进</b></pre><br>制表符（tabs）占8个字符，所以缩进也是8个字符。有些异端运动想使用4个字符 <br>（甚至是2个字符）的缩进，这和把PI（圆周率）定为3没什么两样。 <br>原因：缩进的根本目的是用来清晰地标识一个控制块的起始。特别是当你连续盯 <br>着屏幕看了20 个小时后，你就会体会到更长的缩进的好处了。 <br>现在，有些人提出8字符缩进会使得代码太偏向右边，当使用80字符的终端 <br>时很难阅读。答案是如果你需要三层以上的缩进，那么你已经完蛋了，应该改改 <br>你的程序了。 <br>简而言之，8字符缩进使得阅读代码更为容易，并且在你的缩进层次过深时提出 <br>警告。应该留心这样的警告。 <pre><b>		第二章：括号的位置</b></pre><br>括号位置的问题在C编程风格中经常被提出。和缩进大小不同，括号位置的选择 <br>并没有太多技术上的原因，而更多的是个人的喜好。比如Kernighan和Ritchie的 <br>弟子们把左括号放在一行的最后，把右括号放在一行的开始，象这样： <pre><br>	if (x is true) {
<br>		we do y
<br>	}
<br></pre><br>但是，函数是一种特殊的情况，函数的左括号放在下一行的开始，象这样： <pre><br>	int function(int x)
<br>	{
<br>		body of function
<br>	}
<br></pre><br>全世界的异端人士指出这种不一致的做法 ...嗯... 不太一致，但是所有思维正 <br>确的人知道 (a) K&amp;R是_对_的 (b) K&amp;R是对的。而且，函数确实是特殊的（你在C <br>中无法对函数进行嵌套）。 <br>注意到右括号完全占有单独的一行，_除非_当它后面还有未完成的语句，比如do <br>语句中的“while”或者if语句中的“else”，想这样： <pre><br>	do {
<br>		body of do-loop
<br>	} while (condition);
<br></pre><br>和 <pre><br>	if (x == y) {
<br>		..
<br>	} else if (x &gt; y) {
<br>		...
<br>	} else {
<br>		....
<br>	}
<br></pre><br>原因：K&amp;R。 <br>还有，注意到这种括号的布局方法还减少了空行（或者说是几乎是空行）的数目， <br>而且没有减小可读性。因为你屏幕上的空行是不可回收资源（这里想一下25行的 <br>终端屏幕），这样你会有更多的空行用于加注释。 <pre><b>		第三章：命名</b></pre><br>C是个斯巴达式（崇尚简洁风格的）语言，所以你的命名方法也应该如此。与 <br>Modula-2和Pascal程序员不同，C程序员不使用 <br>ThisVariableIsATemporaryCounter这样可爱的名字。一个C程序员会把一个变量 <br>叫做“tmp”，这样的变量名更容易写，而且理解起来也不算太难。 <br>_但是_，尽管人人都会对大小写混杂的名字皱眉头，全局变量名则必须如此。管 <br>一个全局函数叫“foo”是故意找岔。 <br>_全局_变量（只有在_真正_需要时才使用）需要有个描述性强的名字，这点和全 <br>局函数一样。如果你有个函数用于对活跃用户进行计数，你婴儿叫它 <br>“count_active_users()”，而不是“cntusr()”。 <br>把函数的类型加入到名字中（所谓的匈牙利命名法）是脑损伤的表现 - 编译器 <br>知道类型，能够对它进行检查，这种命名法只会把程序员自己搞晕。难怪微软做 <br>了那么多充满bug的程序。 <br>_局部_变量应该短小扼要。如果你有个随机的整数循环变量，可能最好叫它“i”。 <br>把它叫做“loop_counter”是效率低下的，在不会发生混淆的情况下。类型地， <br>“tmp”可以被用于任何类型的存储临时值的变量。 <br>如果你担心混淆你的局部变量，那么你就会有另一个问题，所谓的函数膨胀荷尔 <br>蒙失衡综合症，请看下一章。 <pre><b>		第四章：函数</b></pre><br>函数应该短小而甜美，而且只能做一件事。他们应该只用一两屏幕（我们都知道， <br>ISO／ANSI标准屏幕大小是80x24）就能装下，只做并且做好一件事。 <br>函数的最大长度应该与函数的复杂性和缩进层次成反比。所以，如果你有个只有 <br>一个很长（但很简单）的case语句的函数，对许多case做一些很少的操作，那么 <br>这个函数长点也没有关系。 <br>但是，如果你有一个复杂的函数，你担心一个中等智力的高一学生可能无法理解， <br>那么你应该更严格地遵守最大长度限制。使用有描述性名字的帮助函数（你可以 <br>让编译器in-line这些帮助函数，如果你认为性能很重要的话，而且编译器恐怕 <br>会比你做的要好）。 <br>函数的另一个指标是局部变量的数目，局部变量的数目不应超过5-10个，否则一 <br>定是哪里有问题了。再设计一下这个函数，把它分解得更小一些。人的大脑一般 <br>可以同时跟踪7个不同的东西，超过了7个就会晕菜。虽然你很聪明，不过可能你 <br>有时会想理解一下两星期前所写的代码。 <pre><b>		第五章：注释</b></pre><br>注释是好东西，不过存在过分注释的危险。_永远_不要在注释中解释你的代码是 <br>如何工作的：更好的做法是写出工作方式显而易见的代码，解释糟糕的代码是浪 <br>费时间。 <br>一般来说，注释应该说明代码在做什么，而不是怎么做。并且，不要把注释加在 <br>函数主体中：如果函数太复杂以至于必须对各个部分进行注释，那么你可能要再 <br>去读读第四章。你可以加入一些短小的注释来提醒或警告一些聪明（或难看）的 <br>做法，但不要太过度。更好的选择是，把注释放在函数头，说明函数在做什么， <br>可能还包括它为什么做。 <pre><b>		第六章：你的代码乱七八糟</b></pre><br>没什么，我们都遇到过。你可能从老Unix用户那里听说过“GNU emacs”会自动 <br>对齐C源代码，但缺省的设置不是很好（事实上，缺省设置比胡乱敲打还糟糕 - <br>一群使用GNU emacs猴子永远不会做出漂亮的程序）。 <br>所以，你或者彻底仍掉GNU emacs，或者采用更理智的设置。如果选择后者，你 <br>可一把下面的代码加到你的.emacs文件中： <pre><br>(defun linux-c-mode ()
<br>  "C mode with adjusted defaults for use with the Linux kernel."
<br>  (interactive)
<br>  (c-mode)
<br>  (c-set-style "K&amp;R")
<br>  (setq c-basic-offset 8))
<br></pre><br>这会定义 M-x linux-c-mode 命令。当编写Linux模块时，如果你把字符串“-*- <br>linux-c -*-”放在文件的头两行中，这个模式就会被自动激活。还有，如果你 <br>想在编辑/usr/src/linux目录下的源文件时linux-c-mode被自动激活，你在你的. <br>emacs文件中需要加入 <br>(setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode) <br>auto-mode-alist)) <br>但是即使你用不了emacs，并不是世界末日：你还可以使用“indent”。 <br>又一次，GNU indent使用了和GNU emacs一样的脑死亡设置，所以你需要给它一 <br>些命令行选项。但是，这不算太坏，因为即使是GNU indent的作者们也意识到了 <br>K&amp;R的权威性（GNU的人也不是魔鬼，他们只是在这件事上被误导了），所以你可 <br>以使用选项“-kr -i8”（表示“K&amp;R，8字符缩进”）运行indent。 <br>“indent”有很多选项，特别是注释布局部分，你可能想看看它的man手册。但 <br>是请记住：“indent”不能修改糟糕的程序。 <pre><b>		第七章：配置文件</b></pre><br>配置选项 (arch/xxx/config.in，以及所有Config.in文件）使用了有些不同的 <br>缩进方式。 <br>代码中使用的是3字符缩进，config-选项中应该使用2字符缩进标识依赖关系。 <br>后者只应用于bool/tristat选项。对于其他选项，采用你认为最合适的缩进方式 <br>就可以了。例如： <pre><br>if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
<br>   tristate 'Apply nitroglycerine inside the keyboard (DANGEROUS)' CONFIG_BOOM
<br>   if [ "$CONFIG_BOOM" != "n" ]; then
<br>      bool '  Output nice messages when you explode' CONFIG_CHEER
<br>   fi
<br>fi
<br></pre><br>一般来说，所有不稳定的选项应该标为CONFIG_EXPERIMENTAL。所有可能损坏数 <br>据的的选项应该标为(DANGEROUS)，其他的试验选项应该标为(EXPERIMENTAL)。 <pre><b>		第八章：数据结构</b></pre><br>供多线程使用的数据结构应该采用引用计数（reference counts）。在内核中， <br>垃圾回收（garbage collection）是不存在的（内核之外的垃圾回收效率不高）， <br>这意味着你_必须_使用引用计数。 <br>引用计数的使用能避免锁的使用，使不同的用户能够并行使用数据结构 - 不需 <br>要担心结构会因为睡眠而突然消失。 <br>注意到加锁_不是_引用计数的替代物。加锁用于保证数据结构的完整性，而引用 <br>计数是一个内存管理技术。通常你两个都需要，不应该有任何混淆不清的地方。 <br>一些数据结构可能使用两层的引用计数，当对不同的“类”都有使用的时候。子 <br>类的计数统计所有子类用户的数目，当子类的计数为零时只对总计数减一。 <br>这种“多层引用计数”的例子可以在内存管理代码（“struct mm_struct”： <br>mm_users和mm_cout）和文件系统代码（“struct super_block”：s_count和 <br>s_active）中找到。 <br>记住：如果另一个线程能够看见你的数据结构，而你却没有对它使用引用计数， <br>那么几乎可以肯定会有bug存在。 <img src ="http://www.cppblog.com/cfmonkey/aggbug/28534.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2007-07-21 23:39 <a href="http://www.cppblog.com/cfmonkey/archive/2007/07/21/28534.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python笔记9 : 数据结构</title><link>http://www.cppblog.com/cfmonkey/archive/2007/07/17/28225.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Tue, 17 Jul 2007 14:38:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2007/07/17/28225.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/28225.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2007/07/17/28225.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/28225.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/28225.html</trackback:ping><description><![CDATA[<p>python中有三种内建的数据结构-----列表(List), 元组(Tuple), 字典(Dict)</p> <h3>List</h3> <h4>example:</h4> <blockquote><pre><font color="#808000">#!/usr/bin/python
# Filename: using_list.py
# This is my shopping list</font>

shoplist = ['apple', 'mango', 'carrot', 'banana']
<span style="color: #0000ff">print</span> 'I have', len(shoplist),'items to purchase.'
<strong><span style="color: #0000ff">print</span> 'These items are:', <font color="#808000"># Notice the comma at end of the line</font></strong>
for item in shoplist:
    <span style="color: #0000ff">print</span> item,
<span style="color: #0000ff">print</span> '\nI also have to buy rice.'
shoplist.append('rice')
<span style="color: #0000ff">print</span> 'My shopping list is now', shoplist
<span style="color: #0000ff">print</span> 'I will sort my list now'
shoplist.sort()
<span style="color: #0000ff">print</span> 'Sorted shopping list is', shoplist
<span style="color: #0000ff">print</span> 'The first item I will buy is', shoplist[0]
olditem = shoplist[0]
del shoplist[0]
<span style="color: #0000ff">print</span> 'I bought the', olditem
<span style="color: #0000ff">print</span> 'My shopping list is now', shoplist <br><strong>shoplist.remove("apple") <font color="#808000">#will throw a exception like the red words</font></strong><br><font color="#0000ff">print</font> shoplist<br>shoplist.pop()<br><font color="#0000ff">print</font> shoplist</pre></blockquote>
<h4>output:</h4>
<blockquote>
<p><code><font color="#400000">$ python using_list.py<br>I have 4 items to purchase.<br>These items are: apple mango carrot banana<br>I also have to buy rice.<br>My shopping list is now ['apple', 'mango', 'carrot', 'banana', 'rice']<br>I will sort my list now<br>Sorted shopping list is ['apple', 'banana', 'carrot', 'mango', 'rice']<br>The first item I will buy is apple<br>I bought the apple<br>My shopping list is now ['banana', 'carrot', 'mango', 'rice'] <br></font><font color="#ff0000">Traceback (innermost last): File "&lt;interactive input&gt;", line 1, in ? ValueError: list.remove(x): x not in list<br></font><font color="#400000">'rice'<br>['banana', 'carrot', 'mango']</font></code></p></blockquote>
<blockquote></blockquote>
<ol>
<li>可以在列表中添加任何类型的数据. 使用append()函数. 
<li>List是一个可变结构, 即可以改变列表内容和长度等. 
<li>使用for...in....在列表中各项目间递归. 
<li>我们在<code>print</code>语句的结尾使用了一个 <dfn>逗号(comma)</dfn> 来消除每个<code>print</code>语句自动打印的换行符。 
<li>使用del删除列表项. Python从0开始计数. 
<li><tt>remove</tt> <em>仅仅</em> 删除一个值的首次出现。 在这里, <tt>'new'</tt> 在 list 中出现了两次, 但 <tt>li.remove("new")</tt> 只删除了 <tt>'new'</tt> 的首次出现。
<li>如果在 list 中没有找到值, Python 会引发一个异常来响应 <tt>index</tt> 方法。
<li><tt>pop</tt> 是一个有趣的东西。它会做两件事: 删除 list 的最后一个元素, 然后返回删除元素的值。请注意, 这与 <tt>li[-1]</tt> 不同, 后者返回一个值但不改变 list 本身。也不同于 <tt>li.remove(<i>value</i>)</tt>, 后者改变 list 但并不返回值。
<li>help(list)</li></ol>
<h4>list的运算符:</h4>
<blockquote>
<p>Lists 也可以用 <tt>+</tt> 运算符连接起来。 <tt><i>list</i> = <i>list</i> + <i>otherlist</i></tt> 相当于 <tt><i>list</i>.extend(<i>otherlist</i>)</tt>。 但 <tt>+</tt> 运算符把一个新 (连接后) 的 list 作为值返回, 而 <tt>extend</tt> 只修改存在的 list。 也就是说, 对于大型 list 来说, <tt>extend</tt> 的执行速度要快一些。 <br>Python 支持 <tt>+=</tt> 运算符。 <tt>li += ['two']</tt> 等同于 <tt>li.extend(['two'])</tt>。 <tt>+=</tt> 运算符可用于 list, 字符串和整数, 并且它也可以被重载用于用户自定义的类中.<br><tt>*</tt> 运算符可以作为一个重复器作用于 list。 <tt>li = [1, 2] * 3</tt> 等同于 <tt>li = [1, 2] + [1, 2] + [1, 2]</tt>, 即将三个 list 连接成一个。</p></blockquote>
<h3>Tuple</h3>
<h3>DIct</h3>
<ol>
<li>Dict没有sort()方法, 建立数据的时候需要自己进行排序. 
<li>Dict的key是大小写敏感的.&nbsp;e.g<br><font face="Courier New">&gt;&gt;&gt; d = {}<br>&gt;&gt;&gt; d["<span style="color: #8b0000">key</span>"] = "<span style="color: #8b0000">value</span>"<br>&gt;&gt;&gt; d["<span style="color: #8b0000">key</span>"] = "<span style="color: #8b0000">other value</span>" <br>&gt;&gt;&gt; d<br><font color="#0080ff">{'key': 'other value'}</font><br>&gt;&gt;&gt; d["<span style="color: #8b0000">Key</span>"] = "<span style="color: #8b0000">third value</span>" <br>&gt;&gt;&gt; d<br><font color="#0080ff">{'Key': 'third value', 'key': 'other value'}</font></font> 
<li>Dict的删除<br>&gt;&gt;&gt; del d[...]<br>&gt;&gt;&gt; d.clear() 
<li>可以通过 key 来引用其值, 但是不能通过值获取 key。所以 <tt>d["server"]</tt> 的值为 <tt>'mpilgrim'</tt>, 而使用 <tt>d["mpilgrim"]</tt> 会引发一个异常, 因为 <tt>'mpilgrim'</tt> 不是一个 key。e.g<br><font face="Courier New">&gt;&gt;&gt; d = {"<span style="color: #8b0000">server</span>":"<span style="color: #8b0000">mpilgrim</span>", "<span style="color: #8b0000">database</span>":"<span style="color: #8b0000">master</span>"} <br>&gt;&gt;&gt; d<br>{'server': 'mpilgrim', 'database': 'master'}<br>&gt;&gt;&gt; d["<span style="color: #8b0000">database</span>"]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>'master'<br>&gt;&gt;&gt; d["<span style="color: #8b0000">mpilgrim</span>"]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br></font><font face="Courier New" color="#ff0000">Traceback (innermost last):<br>&nbsp; File "<span style="color: #8b0000">&lt;interactive input&gt;</span>", line 1, in ?<br>KeyError: mpilgrim</font> </li></ol><img src ="http://www.cppblog.com/cfmonkey/aggbug/28225.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2007-07-17 22:38 <a href="http://www.cppblog.com/cfmonkey/archive/2007/07/17/28225.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>const使用详解(zz from vckbase)</title><link>http://www.cppblog.com/cfmonkey/archive/2007/07/06/27585.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Thu, 05 Jul 2007 16:15:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2007/07/06/27585.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/27585.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2007/07/06/27585.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/27585.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/27585.html</trackback:ping><description><![CDATA[<p></p> <h5>const使用详解</h5> <p>&nbsp;<br>作者:康建东 <br>关于C++中的const关键字的用法非常灵活，而使用const将大大改善程序的健壮性，现将本人的一些体会总结如下，期望对大家有所帮助： <br>一 const基础 <br>如果const关键字不涉及到指针，我们很好理解，下面是涉及到指针的情况： <br>int b = 500; <br>const int* a = &amp;b; [1] <br>int const *a = &amp;b; [2] <br>int* const a = &amp;b; [3] <br>const int* const a = &amp;b; [4] <br>如果你能区分出上述四种情况，那么，恭喜你，你已经迈出了可喜的一步。不知道，也没关系，我们可以参考《Effective c++》Item21上的做法，如果const位于星号的左侧，则const就是用来修饰指针所指向的变量，即指针指向为常量；如果const位于星号的右侧，const就是修饰指针本身，即指针本身是常量。因此，[1]和[2]的情况相同，都是指针所指向的内容为常量（const放在变量声明符的位置无关），这种情况下不允许对内容进行更改操作，如不能*a = 3 ；[3]为指针本身是常量，而指针所指向的内容不是常量，这种情况下不能对指针本身进行更改操作，如a++是错误的；[4]为指针本身和指向的内容均为常量。 <br>另外const 的一些强大的功能在于它在函数声明中的应用。在一个函数声明中，const 可以修饰函数的返回值，或某个参数；对于成员函数，还可以修饰是整个函数。有如下几种情况，以下会逐渐的说明用法：A&amp; operator=(const A&amp; a); <br>void fun0(const A* a ); <br>void fun1( ) const; // fun1( ) 为类成员函数 <br>const A fun2( ); <br>二 const的初始化 <br>先看一下const变量初始化的情况 <br>1) 非指针const常量初始化的情况：A b; <br>const A a = b; <br>2) 指针(引用)const常量初始化的情况：A* d = new A(); <br>const A* c = d; <br>或者：const A* c = new A(); <br>引用： <br>A f; <br>const A&amp; e = f; // 这样作e只能访问声明为const的函数，而不能访问一般的成员函数； <br>[思考1]： 以下的这种赋值方法正确吗？ <br>const A* c=new A(); <br>A* e = c; <br>[思考2]： 以下的这种赋值方法正确吗？ <br>A* const c = new A(); <br>A* b = c; <br>三 作为参数和返回值的const修饰符 <br>其实，不论是参数还是返回值，道理都是一样的，参数传入时候和函数返回的时候，初始化const变量 <br>1 修饰参数的const，如 void fun0(const A* a ); void fun1(const A&amp; a); <br>调用函数的时候，用相应的变量初始化const常量，则在函数体中，按照const所修饰的部分进行常量化，如形参为const A* a，则不能对传递进来的指针的内容进行改变，保护了原指针所指向的内容；如形参为const A&amp; a，则不能对传递进来的引用对象进行改变，保护了原对象的属性。 <br>[注意]：参数const通常用于参数为指针或引用的情况; <br>2 修饰返回值的const，如const A fun2( ); const A* fun3( ); <br>这样声明了返回值后，const按照"修饰原则"进行修饰，起到相应的保护作用。const Rational operator*(const Rational&amp; lhs, const Rational&amp; rhs) <br>{ <br>return Rational(lhs.numerator() * rhs.numerator(), <br>lhs.denominator() * rhs.denominator()); <br>} <br>返回值用const修饰可以防止允许这样的操作发生:Rational a,b; <br>Radional c; <br>(a*b) = c; <br>一般用const修饰返回值为对象本身（非引用和指针）的情况多用于二目操作符重载函数并产生新对象的时候。 <br>[总结] 一般情况下，函数的返回值为某个对象时，如果将其声明为const时，多用于操作符的重载。通常，不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。 <br>原因如下： <br>如果返回值为某个对象为const（const A test = A 实例）或某个对象的引用为const（const A&amp; test = A实例） ，则返回值具有const属性，则返回实例只能访问类A中的公有（保护）数据成员和const成员函数，并且不允许对其进行赋值操作，这在一般情况下很少用到。 <br>[思考3]： 这样定义赋值操作符重载函数可以吗？ <br>const A&amp; operator=(const A&amp; a); <br>四 类成员函数中const的使用 <br>一般放在函数体后，形如：void fun() const; <br>如果一个成员函数的不会修改数据成员，那么最好将其声明为const，因为const成员函数中不允许对数据成员进行修改，如果修改，编译器将报错，这大大提高了程序的健壮性。 <br>五 使用const的一些建议 <br>1 要大胆的使用const，这将给你带来无尽的益处，但前提是你必须搞清楚原委； <br>2 要避免最一般的赋值操作错误，如将const变量赋值，具体可见思考题； <br>3 在参数中使用const应该使用引用或指针，而不是一般的对象实例，原因同上； <br>4 const在成员函数中的三种用法（参数、返回值、函数）要很好的使用； <br>5 不要轻易的将函数的返回值类型定为const; <br>6除了重载操作符外一般不要将返回值类型定为对某个对象的const引用; <br>本人水平有限，欢迎批评指正，可以联系 <a href="mailto:kangjd@epri.ac.cn">kangjd@epri.ac.cn</a><br>[思考题答案] <br>1 这种方法不正确，因为声明指针的目的是为了对其指向的内容进行改变，而声明的指针e指向的是一个常量，所以不正确； <br>2 这种方法正确，因为声明指针所指向的内容可变； <br>3 这种做法不正确； <br>在const A::operator=(const A&amp; a)中，参数列表中的const的用法正确，而当这样连续赋值的时侯，问题就出现了： <br>A a,b,c: <br>(a=b)=c; <br>因为a.operator=(b)的返回值是对a的const引用，不能再将c赋值给const常量。 </p><img src ="http://www.cppblog.com/cfmonkey/aggbug/27585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2007-07-06 00:15 <a href="http://www.cppblog.com/cfmonkey/archive/2007/07/06/27585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>zz Python学习备忘录</title><link>http://www.cppblog.com/cfmonkey/archive/2007/07/05/27575.html</link><dc:creator>cfmonkey</dc:creator><author>cfmonkey</author><pubDate>Thu, 05 Jul 2007 14:55:00 GMT</pubDate><guid>http://www.cppblog.com/cfmonkey/archive/2007/07/05/27575.html</guid><wfw:comment>http://www.cppblog.com/cfmonkey/comments/27575.html</wfw:comment><comments>http://www.cppblog.com/cfmonkey/archive/2007/07/05/27575.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cfmonkey/comments/commentRss/27575.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cfmonkey/services/trackbacks/27575.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 原帖地址：http://www.devfront.com:8080/?q=node/199Python学习备忘录Wed, 2006-10-11 08:14 — Marchday类中的特殊方法一般说来，特殊的方法都被用来模仿某个行为。例如，如果你想要为你的类使用x[key]这样的索引操作（就像列表和元组一样），那么你只需要实现__getitem__()方法就可以了。想一下，Pyt...&nbsp;&nbsp;<a href='http://www.cppblog.com/cfmonkey/archive/2007/07/05/27575.html'>阅读全文</a><img src ="http://www.cppblog.com/cfmonkey/aggbug/27575.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cfmonkey/" target="_blank">cfmonkey</a> 2007-07-05 22:55 <a href="http://www.cppblog.com/cfmonkey/archive/2007/07/05/27575.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>