Tuesday, December 21, 2004

Tech Link

Microsoft 社区
http://www.microsoft.com/china/MSDN/library/default.mspx MSDN技术资源库
http://www.microsoft.com/china/technet/default.mspx Microsoft Tectnet
http://blog.joycode.com/ 博客堂 http://www.cnblogs.com/ 博客园
http://www.cnblogs.com/team/DesignPattern.html DotNet Design & Pattern团队
http://www.microsoft.com/China/Community/ Microsoft中国社区
http://www.gotdotnet.com/ GotDotNet: The Microsoft .NET Framework Community
http://www.csdn.net/ 中国开发者网络
http://msdn.microsoft.com/library/chs/ MSDN Library 简体中文
http://www.blogcn.com/ 博客中文站
http://www.umlchina.com/

http://www.tianyaclub.com/new/Publicforum/Content.asp?idWriter=0&Key=0&strItem=itinfo&idArticle=8161&flag=1 站长必去的10个网站


分层开发思想与小笼包
三层开发中容易犯的错误

星火燎原

Fire3’s Blog:Linux,Open Source,Google

[TDD开发的全过程]


.Net
ASP.NET Forms Authentication Basics
.NET设计模式系列文章
http://www.royaloo.com/articles/articles_2002/dotNetFAQ_content.htm
.NET Framework FAQ 作者Andy McMullan 译者 荣耀
http://www.dotnettools.org/2005/doc/entlib/EntLib001.htm 将Enterprise Library 放到你的应用或产品中
通过 Web 服务传递数据 http://www.microsoft.com/china/MSDN/library/data/dataAccess/hcvb04vb04i7.mspx
卢彦——利用XML实现通用WEB报表打印
讨论创建基于WSE的报表打印服务及其实现 http://msdnportal.csdn.net/Read.aspx?C=6&S=1ce99830-e58b-4729-9e1b-7e4a9c7fe580
WSE Step by Step (1)
WSE2.0 比起 WSE2.0 Tech PreView 最大的变化就是安全性。
WSE2已经发布,我今天才了解什么是WSE
COM+ Web 服务:通过复选框路由到 XML Web Services http://www.cnblogs.com/cowbird/archive/2004/06/17/16320.html
关于MTS和COM+的区别
使用Visual C#制作可伸缩个性化窗体 http://msdnportal.csdn.net/Read.aspx?C=6&S=705706c8-7013-4730-9a98-93b4639726f3
Working with the C# 2.0 Command Line Compiler http://msdn.microsoft.com/vcsharp/default.aspx?pull=/library/en-us/dnvs05/html/csharpcompiler.asp
Web Caching and Expiration, Connection Pools, and More http://msdn.microsoft.com/msdnmag/issues/05/01/WebQA/default.aspx
非.NET语言调用.NET XML Web Services返回的数据集合的两个方法 http://www.microsoft.com/China/Community/program/originalarticles/TechDoc/callwebs.mspx
在 .NET 中使用 COM+ 服务 http://www.microsoft.com/China/Community/program/originalarticles/TechDoc/usecom.mspx
身份验证和授权 http://www.microsoft.com/china/msdn/library/architecture/architecture/architecturetopic/BuildSucApp/BSAAsecmod03.mspx FlyTreeView for ASP.NET 3.2 破解攻略 DotNet控件破解

Form with Validators Not Submitting on a Rebuilt ASP.NET 1.1 Box
http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B889877 The Submit button on ASP.NET pages does not work after you install the .NET Framework 1.1 Service Pack 1

使用C#进行点对点通讯和文件传输(通讯基类部分)
使用C#进行点对点通讯和文件传输(发送接收部分)



网站
一个很好的CRM项目网站
http://www.salesforce.com/

C++
VC常用数据类型列表 及字符类型转换
CString,string,char*的综合比较(一)
CString,string,char*的综合比较(二)
CString,string,char*的综合比较(三)
http://www.vckbase.com/ VC知识库
http://www.vchome.net/ 阿蒙编程之家
http://www.vczx.com/ VC在线
http://www.china-askpro.com/ 问专家
http://www.vcfan.com/
http://www.vchelp.net/


IT从业人员必看的10个论坛
IT技术开发综合类
http://community.csdn.net/
适合人群:只适合软件开发者
技术开发最全面的论坛,里面可以遇到很多牛人,版面也很全,什么J2EE,.NET啊,该有的全上,在这里基本上可以提出任何问题,人气也是最旺的,不过一般提出的意见都有正方两面的,所以最终解决问题,还是靠自己。
评价:专业,很牛逼,就是速度慢。
http://www.itpub.net/
适合人群:数据库开发人员
数据库方面是非常著名的,牛人不少,不过,现在比较杂,什么都做,网络,操作系统,行业应用,到体育贴图,当然有些也不错,人气非常高,特别是灌水方面,^_*.
评价:强,速度一般;
http://bbs.chinaunix.net/forum/
适合人员:系统工程师
这里的特色就是操作系统方面在业界是最著名的,牛人不少,目前,在数据库,网络方面也颇有建树,当然灌水方面也不赖,呵呵,属于温柔性
评价:强,速度还可以
bbs.chinajavaworld.com/
适合人员:JAVA开发
JAVA方面非常综合的论坛了,牛人也很多,是一个难得的JAVA论坛,涉及你想象的关于JAVA目前任何技术。
评论:强,速度还可以。
http://www.huihoo.com/forum/
适合人员:中间件开发者
人气不错,版面风格独特,在开源,中间件,工作流方面非常不错,问题讨论都非常深刻、也很专业。
评价:很好,速度一般;
IT售前技术顾问综合类
http://www.sysvs.com/bbs
适合人员:IT售前及技术顾问
业界知名的售前技术顾问论坛,比较新异的知识点,各个IT行业版快划分也比较好,也非常专业,绝对是我稀饭(喜欢)的风格,网站风格业内罕见,也有很多专业文章,没有地方灌水,厉害。
评价:很好,速度比较快
网络工程类
http://www.1000bbs.com/
适合人员:布线/网络工程师
人气很旺,特色是版面比较紧凑,综合布线这一块很权威,很窄很专,时间非常久了,颜色比较明快,就是太低端了,
评价:不错,速度一般
http://www.sharecenter.net/
适合人员:网络工程师
之所以我喜欢是这个网站很多做CISCO工程都知道,也是别人介绍我去的,时间非常久了,颜色比较暗谈,属于忧郁型。
评价:不错,速度也还可以
IT管理综合类
http://club.amteam.org/
适合人员:企业策划,CIO
业界知名的知识站点,信息化管理顾问可以去看看,人也很多,可惜,都是下载,实质性内容需要改观,我记得以前是非常专业的网站,现在需要加油。
评价:不错,速度一般。
IT评论类
http://www.tianyaclub.com/ it视角
适合人群:大多数,
评论类比较多,基本上在其他媒体上看到的评论,这里都会有,要想了解IT发展的情况,就来这里看看。
评价:很好,休闲工作都可以看。

http://vipbio.blogchina.com/blog/article_180765.1051334.html windows XP 系统服务“关闭”详细列表,内存128的足够了

Tuesday, December 07, 2004

Credit Card Payment Gateway API

Four major credit card payment gateway:
1. Verisign => http://verisign.com/
2. Psigate => http://psigate.com/
3. Linkpoint => http://linkpoint.com/
4. Authorize => http://authorize.net/

Another two payment gateway:
5. 2CheckOut => http://2checkout.com/
6. Paypal => http://paypal.com/

Five Transaction Type:
0(S). Sale
1(A). Authorisation
2(D). Delayed Capture
3(C). Credit
9(V). Void

API
1. Verisign Payment Services: Payflow Pro
The Payflow Pro client resides on your computer system and is available on all major Web server platforms in a variety of formats to support integration requirements. It comes as a binary executable, activated via a Common Gateway Interface (CGI) script, or integrated as a C-interface application library. It is also available as DLL, COM, Site Server, Java Native Interface, or Perl Module
Interface

Config:
Host=test-payflow.verisign.com
Port=443

Set ccObj = CreateObject("PFProCOMControl.PFProCOMControl.1")
Query = "USER=MerchantLogin&VENDOR=MerchantLogin&PARTNER=MerchantPartner
&PWD=MerchantPassword&TRXTYPE=transactionType&TENDER=C&ACCT=accountNumber
&EXPDATE=expDate&AMT=Amount&COMMENT1=UserName&MERCHDESCR=CompanyName&MERCHSVC=CustomerTel"
Ctx = creditcardObj.CreateContext(HostAddress, HostPort, 30, "", 0, "", "")
Response = ccObj.SubmitTransaction(Ctx, Query , Len(Query))
'RESULT=0&RESPMSG=Approved&PNREF=V53A53032326
ccObj.DestroyContext (Ctx)

2. PsiGate
Config:
Host=secure.psigate.com
Port=1139

Set ccObj = CreateObject("MyServer.PsiGate")
ccObj.ConfigFile = MerchantConfig
ccObj.KeyFile = MerchantKeyFile
ccObj.Host = HostAddress
ccObj.Port = HostPort
ccObj.Result = TestMode
ccObj.Bname = cardName
ccObj.CardNumber = accountNumber
ccObj.expMonth = expMonth
ccObj.expYear = expYear
ccObj.ChargeType = transactionType
ccObj.userID = clientType
ccObj.Email = clientType
ret = ccObj.AddItem("cc transaction for CompanyName", "total price", Amount, 1, "", 0, "")
if ret = 1 then
ret = ccObj.ProcessOrder()
if ret = 1 then
Appr = ccObj.Appr 'APPROVED
Err = ccObj.Err '
OrdNo = ccObj.OrdNo '69.158.48.111-1102444389-363202-15893-7
end if
end if

3.LinkPoint: API
a collection of functions for processing payment transactions over the Internet in a highly secure manner.
Transition between COM Object versions 5.4(using 1139) and 6.0(using 1129) before Feb 2005.

Config:
Host=staging.linkpt.net
Port=1129

'=================V5.4===================================================
Set ccObj= Server.CreateObject("ComApi_3_8.ComApi")
OrderCtx = ccObj.csi_order_alloc()
ItemCtx = ccObj.csi_item_alloc()
ReqCtx = ccObj.csi_req_alloc()
Flag = ccObj.csi_req_set(ReqCtx, ReqField_Configfile, merchantconfig)
Flag = ccObj.csi_req_set(ReqCtx, ReqField_Keyfile, keylocation)
Flag = ccObj.csi_req_set(ReqCtx, ReqField_Host, hostaddress)
Flag = ccObj.csi_req_set(ReqCtx, ReqField_Port, hostport)

Flag = ccObj.csi_order_setrequest(OrderCtx, ReqCtx)
if ccObj.bStat <> Succeed Then
'Error
End If

Flag = ccObj.csi_order_set(OrderCtx, OrderField_Bname, cardname)
Flag = ccObj.csi_order_set(OrderCtx, OrderField_Cardnumber, accountnumber)
Flag = ccObj.csi_order_set(OrderCtx, OrderField_ChargeType, transactiontype)
Flag = ccObj.csi_order_set(OrderCtx, OrderField_Expmonth, expmonth)
Flag = ccObj.csi_order_set(OrderCtx, OrderField_Expyear, expyear)
Flag = ccObj.csi_order_set(OrderCtx, OrderField_Email, email)
Flag = ccObj.csi_order_set(OrderCtx, OrderField_Result, status)
Flag = ccObj.csi_item_set(ItemCtx, ItemField_Itemid, "total price")
Flag = ccObj.csi_item_set(ItemCtx, ItemField_Description, "cc transaction for companyname")
Flag = ccObj.csi_item_set(ItemCtx, ItemField_Price, amount)
Flag = ccObj.csi_item_set(ItemCtx, ItemField_Quantity, 1)
Flag = ccObj.csi_order_additem(OrderCtx, ItemCtx)
if ccObj.bStat <> Succeed Then
'Error
End If

Flag = ccObj.csi_item_drop(ItemCtx)
Flag = ccObj.csi_order_set(OrderCtx, OrderField_Subtotal, amount)
Flag = ccObj.csi_order_set(OrderCtx, OrderField_Chargetotal, amount)

Flag = ccObj.csi_order_process(OrderCtx)
if ccObj.bStat <> Succeed Then
'Error
End If

Ref = ccObj.csi_order_get(OrderCtx, OrderField_R_Ref)
Appr = ccObj.csi_order_get(OrderCtx, OrderField_R_Approved)
Err = ccObj.csi_order_get(OrderCtx, OrderField_R_Error)
Ord = ccObj.csi_order_get(OrderCtx, OrderField_R_Ordernum)

Flag = ccObj.csi_order_drop(OrderCtx)
Flag = ccObj.csi_req_drop(ReqCtx)
Set ccObj = nothing

'=================V6.0===================================================
Set order = Server.CreateObject("LpiCom_6_0.LPOrderPart")
order.setPartName("order")
Set ccObj = Server.CreateObject("LpiCom_6_0.LPOrderPart")
res=ccObj.put("ordertype", "SALE") 'PREAUTH, POSTAUTH, VOID
res=order.addPart("orderccObjtions", ccObj)

res=ccObj.put("name", bname)
res=ccObj.put("email", bemail)

res=ccObj.clear()
res=ccObj.put("zip", bzip)
res=ccObj.put("addrnum", baddrnum)
res=order.addPart("billing", ccObj)
'res=ccObj.put("oid", oid)
'res=order.addPart("transactiondetails", ccObj)

res=ccObj.clear()
res=ccObj.put("configfile", configfile)
res=order.addPart("merchantinfo", ccObj)

res=ccObj.clear()
res=ccObj.put("cardnumber", cardnumber)
res=ccObj.put("cardexpmonth", expmonth)
res=ccObj.put("cardexpyear", expyear)
res=order.addPart("creditcard", ccObj)

res=ccObj.clear()
res=ccObj.put("chargetotal", total)
res=order.addPart("payment", ccObj)

Set LPTxn = Server.CreateObject("LpiCom_6_0.LinkPointTxn")

outXml = order.toXML()
Response = LPTxn.send(keyfile, host, port, outXml)
'CSITue Dec 7 10:43:16 20040000017747459E306F-41B5F9C3-627-14FD240088730000017747:YNAM:12345678901234567890123:1102444996APPROVEDYNAM

Set LPTxn = Nothing
Set order = Nothing
Set ccObj = Nothing

4. Authorize:
The Standard Transaction Submission API defines how transactions should be submitted to the gateway using AIM. The gateway response API describes the gateway’s responses to transactions submitted to the gateway.

Config:
Host=https://secure.authorize.net/gateway/transact.dll
Port=1139

query = "x_login=MerchantLogin&amp;x_tran_key=MerchantKey&x_type=
x_type&x_amount=total&x_card_num=cardnumber&x_exp_date=
x_exp_date&x_trans_id=x_trans_id&x_first_name=x_first_name &x_last_name=x_last_name &x_email=emailaddress"
Set objsxh = Server.CreateObject("Msxml2.ServerXMLHTTP.4.0")
objsxh.open "POST", HostAddress ,false
objsxh.setRequestHeader "Content-Type","application/x-www-form-urlencoded"
objsxh.setRequestHeader "Content-Length",len(query)
objsxh.send query
Response = objsxh.responseText
'1,1,1,This transaction has been approved.,000000,P,0,,,1.00,CC,auth_capture,,,,,,,,,,,,,,,,,,,,,,,,,,C8CCAF620C1287B7C2713F10E5D1FC54,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

Friday, November 19, 2004

利用 Microsoft 的 HTML 分析器来获得 Web 站点的数据

拆取 Web 页


.Net 2.0实例学习:WebBrowser页面与WinForm交互技巧 这一篇也很不错

利用 Microsoft 的 HTML 分析器来获得 Web 站点的数据

http://www.microsoft.com/china/msdn/Archives/workshop/scrape.asp


Jeremy Rule
Microsoft Corporation
2000年5月



摘要: 本文讨论如何收集来自 Web 的信息,并借助 Internet Explorer 的可重用分析器组件,将它分布到其他 Web 页或数据库。(打印共 7 页)



程序员面临的一个共同任务就是收集 Web 站点的数据,并将它分布到数据库或其他 Web 页。例如,程序员可能需要从气象站点获得天气预报图,从在线股票经纪人那里获得股票报价,以及从新闻站点获得行业新闻。然后,这些信息被放在一个 Web 页上,供 CIO、商人或销售经理使用。或者,也许程序员需要跟踪历来的气象资料,并需要每天将来自气象站的天气预报信息存入数据库。其应用不胜枚举。



过去,这些选择相当受限制。现在,通过使用象 WinInet.dll 这样的 HTTP 组件或许多其他第三方组件,您就可以获取 Web 页,并利用几百种字符串处理功能来获得网页中您所感兴趣的部分。这一技术已在应用,但很不理想。如果您致力于计算机科学(或者有足够的时间),就会为 HTML 创建一个分析器,以标记 Web 页,然后分析您需要的网页部分。不过,由于 Internet Explorer 的体系结构中已包含了可重复使用的用分析器,这些都不需要了。



Internet Explorer 不只是一个程序,更是许多可重复使用组件的集合与容器。在拆取 Web 页时,最有意思的两个组件是 shdocvw.dllmshtml.dll。第一个组件 shdocvw.dll,包含称为 WebBrowser 的 Microsoft(R) ActiveX(R) 控件,它真实地显示 Web 页。在运行 Internet Explorer 时,显示 Web 页的主窗口就是这样的控件。第二个组件 mshtml.dll,含有能分析 WebBrowser 控件中所包含文档的 HTML 分析器。



可能有这种情况,在您的应用程序内部,已经用 WebBrowser 控件来驻留 Web 页,但仍需要重新创建一个小浏览器来启动 Web 页的拆取。


  1. 文件菜单上,请单击新建工程,以创建“标准 EXE”,然后在工程菜单上单击部件,以添加 Microsoft HTML Object LibraryMicrosoft Internet Controls。(见图 1。)


    图 1.



  2. 在工具箱中,可看见 WebBrowser 组件。拖动其中之一,文本框和主窗体上的命令按钮。将此文本框的 Text 属性设置为 “http://moneycentral.msn.com/”,将此命令按钮的 Caption 属性设置为“浏览(&B)”。(见图 2。)


    图 2.



  3. 双击该命令按钮,然后在事件处理器中放入下列代码,导航至文本框中命名的 Web 站点:
    Private Sub Command1_Click()
    WebBrowser1.Navigate Text1.Text
    End Sub



  4. 保存并运行该程序。试着按浏览按钮,导航到文本框中指定的站点。您已经创建了一个基本的 Web 浏览器 — 就其本身而言没什么用,甚至没什么意义,但它却是迈向 Web 拆取技术的第一步。



  5. 回到工程中,在代码窗口中选择 WebBrowser1 对象,然后选择 DocumentComplete 的事件处理器。一旦整个 Web 页下载到此浏览器中,即触发该事件:
    Private Sub WebBrowser1_DocumentComplete_
    (ByVal pDisp As Object, URL As Variant)

    End Sub


    传递到该事件中的 URL 就是我们导航所至的位置,它在日后确定浏览器所在的页面时将更为有用。WebBrowser 控件有一个属性称为 Document(文档),可将其视为 IHTMLDocument 来处理:


    Private Sub WebBrowser1_DocumentComplete(_ ByVal pDisp As Object, URL As Variant)
    Dim Doc As IHTMLDocument2
    Set Doc = WebBrowser1.Document
    //下一步:分析该文档
    End Sub


    较新的 IHTMLDocument2 具有 IHTMLDocument 中无法使用的特性。可对系统使用 IHTMLDocument 替代老版本的 Internet Explorer,如果您有勇气的话,甚至可以使用 IHTMLDocument3。补充说明一下,我们假设您已经导航到 Word 文档或 XML 文档,而非 HTML 文档。不要将变量 doc 声明为 IHTMLDocument2,可将其声明为 Word 的文档或 XML 的 DOMDocument


    在进行下一步之前,理解 HTML 文档的结构是非常重要的。和 XML 不一样,HTML 文档的组合有一定的自由度。例如,您会遇到未关闭标记的 HTML 文档。HTML 文档确实有某种结构。结构好的 HTML 文档通常具有下列元素:


    <HTML>
    <HEAD>
    header information like the <TITLE>
    </HEAD>
    <BODY>
    elements like <TABLE> and <A> and <IMG>
    </BODY>
    </HTML>


    请注意 HTML 的树状结构。标记包含标记又包含标记,如此等等。特别是,每一个标记元素都包含一个 0 到 n 个标记元素的集合。<TABLE> 标记可以包含 <TR> 标记。每个 <TR> 标记可以包含 <TD> 标记,后者又可以包含其他标记如锚或图像等。



  6. 现在,分析整个 http://moneycentral.msn.com/,并在带 MSFT 符号的页填上第二个 <INPUT> 标记。然后,调用此窗体上的提交
    Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Dim doc As IHTMLDocument2
    Set doc = WebBrowser1.Document

    If URL = _
    "http://moneycentral.msn.com/home.asp" Then
    '填充带输入标记的元素集合
    Dim Inputs As IHTMLElementCollection
    Set Inputs = doc.All.tags("INPUT")
    '选择第一个输入标记
    Dim Element As IHTMLElement
    Set Element = Inputs.Item(1, 1)

    '使用正确的界面
    Dim InputElement As IHTMLInputElement
    Set InputElement = Element
    InputElement.Value = Text1.Text

    '调用此页第一个窗体上的提交
    doc.Forms.Item(0, 0).submit
    End Sub


    在此您会看到,标记集合如何包含可视为其特定类型的标记。每一个标记都可用 IHTMLElement 界面表示,或用指定为该标记类型的界面表示。例如,<TABLE> 标记可用 IHTMLTableElement 或 IHTMLElement 表示。


    标记的集合都包含下列重要的方法和属性:



    • 长度。可将其理解为计数,或集合中项目的数量。



    • 项目。用于选择集合中的特殊元素。“项目”有两个参数,第二个参数即命名的标记。



    • 标记。将要过滤的元素传递给标记。标记 ("A") 将返回集合内所有锚的集合。要想有效地拆取页,就需要学会使用标记集合。



    现在可能您会问,“为什么不直接转到 http://moneycentral.msn.com/scripts/webquote.dll?ipage=qd&Symbol=msft?”当然是可以的,但这个例子告诉大家如何在更复杂的情况下操纵 HTML 窗体。


    如果您未做进一步的改动即运行该程序,就会注意到它将陷入无休止的循环,没完没了地下载同一个页面。程序不断地寻找要填充的窗体,并反复调用 DocumentComplete。要修正这个缺陷,应在 DocumentComplete 中置入一些逻辑,告诉分析器,只有在正确的页面上才提交窗体。



  7. 接下来,让我们放入这个逻辑,并引入实际的股票报价。另外,我们不捕获文本框中的 URL,而是捕获股票符号:
    Private Sub Command1_Click()
    WebBrowser1.Navigate _
    "http://moneycentral.msn.com/home.asp"
    End Sub
    Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Dim doc As IHTMLDocument2
    Set doc = WebBrowser1.Document

    If URL = "http://moneycentral.msn.com/home.asp" Then
    '填充带输入标记的元素集合
    Dim Inputs As IHTMLElementCollection
    Set Inputs = doc.All.tags("INPUT")
    '选择第一个输入标记
    Dim Element As IHTMLElement
    Set Element = Inputs.Item(1, 1)

    '使用正确的界面
    Dim InputElement As IHTMLInputElement
    Set InputElement = Element
    InputElement.Value = Text1.Text

    '调用该页第一个窗体上的提交
    doc.Forms.Item(0, 0).submit
    ElseIf URL = _
    "http://moneycentral.msn.com/scripts/webquote.dll?ipage=qd&Symbol=" _
    & Text1.Text Then
    Dim Tables As IHTMLElementCollection
    Set Tables = doc.All.tags("TABLE")
    '获得第 14 个表的第二个项目(基于 0)
    Dim Quote As IHTMLElement
    Set Quote = _
    Tables.Item(14, 14).All.tags("TD").Item(2, 2)
    '显示开始标记和结束标记之间的文本
    MsgBox Quote.innerText
    End If
    End Sub



    图 3.

    到了这最后一步,自定义的浏览器已被转入有效的 Web 拆取器。重要的是,要注意有了 IHTMLElement 之后获得文本的可用选项。有 4 个属性:



    • innerText:开始标记和结束标记之间的文本。



    • innerHTML:开始标记和结束标记之间的文本和 HTML。



    • outerText:对象的文本。



    • outerHTML:对象的文本和 HTML。



    还要注意从 4 个表(基于 0)的 11 个元素中检索到的最终报价字符串。如果 MoneyCentral? 决定重新调整该页怎么办?您最好的策略是根据合理的假定来查询页面。如果您知道报价几乎总是放在新闻标题的前面,那么就从新闻标题往回查询那个表。还有一种策略是,当更改页面的格式时,有一种简单的方法来更新分析器。一种方法就是将分析的职能细分为较小的组件。每个组件可以实现一个预定义的界面,接受要分析的 IHTMLDocument。与实际的 Web 页失去同步的分析组件可被替换。这样带来的好处是,多个编程人员都可以编写分析器,只需给定要实现的界面和要拆取的 Web 站点即可。


    为了避免复杂,将 IHTMLDocument 从 DocumentComplete 函数传递 COM DLL,后者可以分析 IHTMLDocument 并返回想要的有效负载。这有利于程序的模块化,并易于更新与 Web 站点失去同步的分析部分。它还使多个开发者能同时处理这个项目,因为他们有一个干净的界面来编写分析器。




在把新的程序推向市场以前,还有几个实际问题要考虑。首先,很可能 MoneyCentral 和其他许多站点不愿意别人下载他们的内容,也不喜欢看广告。您可能得与摘取其内容的站点签订一份协议。



还有很重要的一点要注意,即如果您是 Web 站点的操作员,那么还有更好的办法将您的内容提供给其他系统。虽然可以让其他人来拆取您的 Web 页,但这仍很笨拙。还有一个更好的方法是,提供 XML 来表现内容。并且,随着 XML 被广泛采用,Web 站点开始提供其数据的 XML 表现形式以及 HTML 界面,也不值得大惊小怪。在这样的时刻到来之前,您也许还得拆取 Web 页。Web 页的拆取往往失之笨拙,但 Microsoft HTML 分析器可令其稍微好一些。

Tuesday, October 26, 2004

在加拿大找IT专业工作的经历分享(ZT)

这个星期刚刚找到专业工作,是在donntown的一家e-business公司里的Java Programmer。想跟大家分享一下经历,因为在这个过程中的确得到不少认识和不认识的人无私的帮助,自己也说过如果有那么一天自己找到了专业工作,也会尽自己所能帮助别人。今天就从如何找到这份工作开始。   

我在国内5年工作经验,4年Java相关工作,基本是在外企,从申请到过来足足花了4年,期间也经常学习英文,但现在才确确实实知道跟西人的差别有多大,我相信这是接下来的重要任务。   

来加多伦多4个多月,其间去过LINC(level 5)班,但没有上完就准备找专业工作,所以就没有拿到英文benchmark level 6的证书,这对以后参加政府资助的一些program没有好处,不过听说ESL的语言测试可以代替,但我最后也没有去考。一开始从LINC班出来直接向Monster.ca和Workopolis.com上的工作职位发简历,用的也是中国带来的简历(以为一直都在一些外企,格式差不多),结果一两个星期没有一丝一毫的反应,才确信格式很有问题,于是参加了一个政府资助的为期三天的改简历program,期间从图书馆也借了一些书参考书,从网上http://www.scguild.com参考了其IT人士的简历(不要去骗简历,我也发现google上的确有人发布的职位就是骗简历,没有必要也不好,我们既然来到这里就要注重我们的诚信),由txt格式改成了word格式,倒弄了一两个星期后基本定型,接着给了朋友参考给意见,作了一些修改,听说最好给西人检查,包括格式,语病,习惯等等,但我也没有,听说教会里,政府资助的Programe有这样的服务的。简历改的差不多了,就接着发,除了Monster.ca和Workopolis.com外我还在google的新闻组里找工作机会(因为新闻组不要花钱发布,小公司也许会在上面发布信息,而且大家都在Monster.ca和Workopolis.com上面找,竞争比较激烈,不过正如我刚刚说,上面不少骗简历的,不要被他们给骗了,我想一般他们的网站建立的很好,而且电话,地址在网站上也有的话就比较可信)。其间我也去过图书馆的scott数据库查找多伦多软件公司的联系方式,接着打cool call(YMCA有一些教如何cool call的program),只打了两天,效果不好,我想这个方法本身不是最好的,但实在没办法了,也可以试一试,重要的是keep trying。也就是在打call call的那段时间,通过http://www.google.com/advanced_group_search?hl=en上查找tor.job news group(sort by date)我的cover letter改为找volunteer机会为主,当然也说自己如何符合他们的职位等等,但重点是告诉他们我主要是找volunteer机会,取得到canadian experience。结果有两家公司找我,一加是中国人公司,说一个星期两天(好像很想我去3天),连续3个月(我说2个月他们还不愿意),说干完以后如果公司有新项目,有条件的话可以留下,这3个月有$100/month作为交通费用。因为接下来还有一个机会,而且我觉得他们的诚意不是很够,加上中国人的公司在这个方面一般来讲的确没有西人公司好,所以我就回绝了。到了另外一家公司,发觉是downtown的一家西人公司,准备让我协助他们做web service的项目,两个星期,9:00am~5:00pm,我就坚持下来了。结束的时候manager告诉我可以pick my stuff,但可以给我开reference的时候,我其实是非常难受的,因为一直还是想着就直接留下来的。但也没办法,留了manager和team leader的名片就离开了。发了Thank You Letter(刚得到volunteer机会发了一次,结束后再发了一次)后安慰自己两个星期换个reference也不错,要接着move on。就在我开始上另外一个找工program的第一天,好消息来了,说他的一个programmer要离开,有一个immediately openning,通知我第二天上班,那一天我一直觉得unreal,too good to be true,告诉他那是gift from heaven。接下来是要顺利通过他们的3个月考核。   

总的来说,对于要找IT专业工作的朋友,我有以下建议(特别是来了不久或准备在短期类来的):   

1.强烈建议从volunteer/co-op开始(除非有信心能直接找到工作),其中以西人中小型企业为主要对象,又以自己联系为主(因为即使你去一些co-op,最终还是以你自己找为主,即使是他们帮你找,还存在那家公司是否已经养成使用volunteer习惯的风险),目标是通过volunteer/co-op建立与雇主的联系,让manager看到你的能力,能让他们一有openning,就想到你是一个很好的选择。如果不能直接得到offer,留下他们的名片,隔一段时间就要联系他们,让他们知道你还在找工作,跟他们聊一聊,保持联系,networking很重要的,我有一种感觉,他们一般还是很愿意帮助人的(当然不能过于频繁的骚扰或超出他们的能力范围),但你要ask for it,他们也不会很主动的送一份工作给我们,得到帮助或一些有用的信息后,要多谢一些他们,写一写thank you letter。   

2.如果短时间内不能自己找到工作或volunteer/co-op,而英语水平过关的话,参加以下co-op/work placement,政府资助的关于找工作的program中,我觉得下面的最有价值,时间太短的内容不多而且没有canadian experience,下面的program就提供了所有的你能免费获得的帮助:   http://www.dpcdsb.org/coopcentre/register.coop.html(可能是中国人最多去的,也可能是是几个中最好的,但在Mississauga,我自己没去过,但本来是想去这个的)http://www.dpcdsb.org/alcmeslcoop/coopmain.html(Mississauga另外一个,好像没有那么多人去,不知道效果)NOW: http://www.tdsb.on.ca/business/cspd/now.htm(777 Bloor Street West, Room 122, Toronto,也有不少人去,不是到效果)Yorkdale: http://www.yorkdale.net/main/yorkdale_coop_programs.htm(38 Orfus Road North York, Ontario,但听说留下的不多)STIC: http://skillsforchange.org/stic/index.html(可能是唯一一个有专门为IT人士分组的,但听说accounting分组效果比较好,IT分组效果一般)   

3.Keep Trying,这几个月是觉得辛苦,在国内从来没有受过这个苦,但只要有恒心和毅力,我们还是可以争取到的。开始怀疑自己的时候,告诉自己坚持就是胜利。我们在国内都不会如此,但现在的确比不上2000年了,我们刚过来找工作难是正常的,语言的差距是确确实实存在的,但也要记住还是有很多人坚持下来了,再加上一些运气(也可能是很大一部分),我们最终会得到的,但如果我们已经放弃了,那一点机会都不会有。今年听说IT比2003年要好不少,难度还有,但大家要加油啊!   

4.参考IT简历: http://www.scguild.com

5.Google new group: http://www.google.com/advanced_group_search?hl=ensort by date, Newsgroup中填tor.jobs

6.每天更新Monster.ca和Workopolis.com上简历的状态。   

如果有什么可以帮得上忙得话,可以给我留言,416-763-9913,因为我也得到过不少其他人的帮助,也的确体会到了其过程的压力,体会到在这个地球另外一边得到一些无私帮助时的喜悦。感谢所有多年来帮助过我的朋友,认识的和不认识的,也希望我的经历能够帮助一些朋友。

---------------------------------------------------------------------------------
---------------------------------------------------------------------------------

Behavioural questions万变不离其宗


no matter what question the HR mgr asks, these are the aspects they want to know about you. So for each aspect listed below, prepare for some good examples. Tell the story in the formate of " this is what happens"--->" this is how I handled it"---> conclusion : "from this experience, i learned that... /I developed my skills in @@@ further."

1. your management style and you team work style

2. your time management skills

3. your conflict resolution skills

4. you skills to convince or influence people (make sure you give a well balanced response)

5. your strengs and weakness

7. you career orientation

8. you communication and presentation skills (how do you convey a difficult idea? how to you coach people? how do you make your point across clearly and effectively?) ---------------------------------------------------------------------------------
---------------------------------------------------------------------------------

Behavior Interview


来源: 梅影 于 07-09-29

1.Tell me about yourself.

What the hiring manager really wants is a quick, two- to three-minute snapshot of who you are and why you’re the best candidate for this position.
So as you answer this question, talk about what you’ve done to prepare yourself to be the very best candidate for the position. Use an example or two to back it up. Then ask if they would like more details. If they do, keep giving them example after example of your background and experience. Always point back to an example when you have the opportunity.
“Tell me about yourself” does not mean tell me everything. Just tell me what makes you the best.

sample answer:

I have been working in the field of civil engineering for the past 6 years. My most recent experience has been with an engineering consulting firm where I’ve worked for the last 2 years. I enjoy my job because it’s challenging and I like interacting with a variety of people. In my most recent assignment I was on a project that lasted nine months. I made a significant contribution to the project because of my expertise in sanitary engineering. One of my strengths is my attention to detail. I am known for being extremely thorough and meeting or exceeding deadlines and goals. My boss knows that I work well under minimal supervision, that I am very conscientious and that the job will be done right the first time. I’m looking for a new opportunity where I can contribute to the growth of the company by helping educate customers on the benefits of using our consulting services.

My background to date has been centered on preparing myself to become the very best _____ I can become. Let me tell you specifically how I've prepared myself...

Tell about your major, what you plan on doing when you get out of college, what other jobs you have had.
Answer in about two minutes. Avoid details, don’t ramble. Touch on these four areas:
How many years, doing what function
Education – credentials
Major responsibility and accomplishments
Personal summary of work style (plus career goals if applicable)

2.Did you bring your resume?
Yes. Be prepared with two or three extra copies. Do not offer them unless you’re asked for one.

3.What is your long-range objective?
The key is to focus on your achievable objectives and what you are doing to reach those objectives.

For example: “Within five years, I would like to become the very best accountant your company has on staff. I want to work toward becoming the expert that others rely upon. And in doing so, I feel I’ll be fully prepared to take on any greater responsibilities which might be presented in the long term. For example, here is what I’m presently doing to prepare myself . . .”

Then go on to show by your examples what you are doing to reach your goals and objectives.

Although it's certainly difficult to predict things far into the future, I know what direction I want to develop toward. Within five years, I would like to become the very best _____ your company has. I would like to become the expert that others rely upon. And in doing so, I feel I will be fully prepared to take on any greater responsibilities that might be presented in the long term.

4.Are you a team player?
Describe what would be an ideal working environment?

Team work is the key.
Almost everyone says yes to this question. But it is not just a yes/no question. You need to provide behavioral examples to back up your answer.
A sample answer: “Yes, I’m very much a team player. In fact, I’ve had opportunities in my work, school and athletics to develop my skills as a team player. For example, on a recent project . . .”

Emphasize teamwork behavioral examples and focus on your openness to diversity of backgrounds. Talk about the strength of the team above the individual. And note that this question may be used as a lead in to questions around how you handle conflict within a team, so be prepared
You are, of course, a team player. Be sure to have examples ready. Specifics that show you often perform for the good of the team rather than for yourself are good evidence of your team attitude. Do not brag, just say it in a matter-of-fact tone. This is a key point.

5.What is your greatest weakness?

Most career books tell you to select strength and present it as a weakness. Such as: “I work too much. I just work and work and work.” Wrong. First of all, using strength and presenting it as a weakness is deceiving. Second, it misses the point of the question.

You should select a weakness that you have been actively working to overcome. For example: “I have had trouble in the past with planning and prioritization. However, I’m now taking steps to correct this. I just started using a pocket planner . . .” then show them your planner and how you are using it.

Talk about a true weakness and show what you are doing to overcome it.
I would say my greatest weakness has been my lack of proper planning in the past. I would overcommit myself with too many variant tasks, then not be able to fully accomplish each as I would like. However, since I've come to recognize that weakness, I've taken steps to correct it. For example, I now carry a planning calendar in my pocket so that I can plan all of my appointments and "to do" items. Here, let me show you how I have this week planned out...

6.What is your greatest strength?

Numerous answers are good, just stay positive. A few good examples: Your ability to prioritize, Your problem-solving skills, Your ability to work under pressure, Your ability to focus on projects, Your professional expertise, Your leadership skills, Your positive attitude.

You know that your key strategy is to first uncover your interviewer's greatest wants and needs before you answer questions. And from Question 1, you know how to do this.

Prior to any interview, you should have a list mentally prepared of your greatest strengths. You should also have, a specific example or two, which illustrates each strength, an example chosen from your most recent and most impressive achievements.

You should, have this list of your greatest strengths and corresponding examples from your achievements so well committed to memory that you can recite them cold after being shaken awake at 2:30AM.

Then, once you uncover your interviewer's greatest wants and needs, you can choose those achievements from your list that best match up.

As a general guideline, the 10 most desirable traits that all employers love to see in their employees are:
1. A proven track record as an achiever...especially if your achievements match up with the employer's greatest wants and needs.
2. Intelligence...management "savvy".
3. Honesty...integrity...a decent human being.
4. Good fit with corporate culture...someone to feel comfortable with...a team player who meshes well with interviewer's team.
5. Likeability...positive attitude...sense of humor.
6. Good communication skills.
7. Dedication...willingness to walk the extra mile to achieve excellence.
8. Definiteness of purpose...clear goals.
9. Enthusiasm...high level of motivation.
10. Confident...healthy...a leader.

7.If you had to live your life over again, what one thing would you change?

Focus on a key turning point in your life or missed opportunity. Yet also tie it forward to what you are doing to still seek to make that change.

For example: “Although I’m overall very happy with where I’m at in my life, the one aspect I likely would have changed would be focusing earlier on my chosen career. I had a great internship this past year and look forward to more experience in the field. I simply wish I would have focused here earlier. For example, I learned on my recent internship…” …then provide examples.

Stay focused on positive direction in your life and back it up with examples.

8.How did you prepare for this interview?

When I found this position posted on the internet (monster.com) I was immediately interested. I checked out the company website and mission statement, looked at the bios of company founders and executives, and was impressed. Once I had the interview appointment, I talked with friends and acquaintances in the industry. And, I’m sure I’ll find out a lot more in today’s meetings.”

9.What kinds of people do you have difficulties working with?

In my last three jobs I have worked with men and women from very diverse backgrounds and cultures. The only time I had difficulty was with people who were dishonest about work issues. I worked with one woman who was taking credit for work that her team accomplished. I had an opportunity to talk with her one day and explained how she was affecting the morale. She became very upset that others saw her that way, and said she was unaware of her behavior or the reactions of others. Her behavior changed after our talk. What I learned from that experience is that sometimes what we perceive about others is not always the case if we check it out.

10.How do you handle conflict? (How would you evaluate your ability to deal with conflict?)

On the job, there are many possible sources of conflict. Conflicts with: fellow employees management rules, procedures clients, customers demands of work vs. personal life, family The best way to approach a good answer is to look at if from the employers point of view—they want to be your first priority and they want you to solve problems (not bring them any). “I know everything cannot run smoothly at work all the time. When there is a conflict I usually try to determine the source of the problem and see if it can be solved. This might involve other members of the work team discussing the problem and offering possible solutions. I would then try to pick the solution which appears to have the best outcome and put it into action.” A natural follow-up to this would be: Tell me when you solved a conflict at work. So, have a brief example… a short story… to illustrate your approach. Even if not asked, you can offer your story! If it proves your point and accentuates a skill needed for the position, go with it.

I believe I am quite good at handling conflict. Working in retail and in the residence halls required that I make many unpopular decisions at times, whether it was terminating an associate or taking judicial action on a resident. Often the person in conflict with me would be upset and sometimes physically outraged. I would always make sure that I fully explained the situation, the policies behind my decision, and why those policies exist. Usually by the end of the conversation, the person could see the other side of the situation.

11. How do you handle rejection?

Rejection is part of business. People don’t always buy what you sell. The tick here is to separate rejection of your product from rejection of yourself: “I see rejection as an opportunity. I learn from it. When a customer takes a pass, I ask him what we could do to the product, price or service to make it possible for him to say yes. Don’t get me wrong: You’ve got to makes sales. But rejection is valuable, too. It’s a good teacher.”

12.Tell me about a time when you tried and failed?

Has this ever happened to you? No one expects perfection actually, employers are more interested in your ability to cope, to learn from mistakes, and to deal with others who are less than perfect. If you have an example, certainly pick one that happened a while back, was not earth shattering in the results, and one which you learned and applied this knowledge recently. This is a version of ‘damning with faint praise’ by picking an incident that was minor in scope but, since you are so wise and are always willing to learn, has taught you a valuable lesson.

13.What are some of the things you find difficult to do?
The interviewer is looking to determine how well you know yourself, how you react to difficult situations/tasks and credibility. Look back over your work experience for examples of challenges… speaking in public at a meeting, disagreeing with a manager over an important issue, being asked to use a software program you have not had an opportunity to learn… These ’stories’ should illustrate a lesson learned, a problem overcome or a weakness being dealt with. “I always seem to need a day or two to prepare myself to give a presentation to department heads. When I know I have to give a report on my projects, I plan out all the details in advance and rehearse. One time, there was a problem with a supplier and I was asked to update senior management… immediately. The supply chain was crucial to the completion of an important project we had been working on for 5 months and decisions had to be made based on the information I had to prepare and present on a moment’s notice. I gathered the information and presented it simply and in detail. It was much easier than I thought without the hours of concern and practice. The facts spoke for themselves. Since I understood the situation, I was able to make it clear to management and get a rapid decision. I still prefer advance notice but I know I can deliver when asked to.”

14.What are your short and long term goals?

No one can make goals for you. It comes down to where you are in your professional life and what you want to do. Most people have 5-6 careers in their working lifetime—some with 2 careers going at the same time (like us). The best advice is to be certain to relate your answers to the organization that interviews you. Do not make a point of having goals that cannot be realized there (”I want to work in Paris.” Organization is strictly domestic.) If you do your research into the organization, and into what you truly want to do in the future, you will be able to come up with reasonable responses. No one is going to come back to you in five years and chastise you for not meeting these goals! You will not be held to them… it is only an interview and they are interested in how you see yourself (and they want to see you in the job.)

My primary objectives are to learn as much as possible about your company's product offering, organizational structure, and professional sales techniques so that I may become the most productive member of your sales team.

What are your short-term goals?

Many executives in a position to hire you are strong believers in goal-setting. (It's one of the reasons they've achieved so much.) They like to hire in kind.
If you're vague about your career and personal goals, it could be a big turnoff to many people you will encounter in your job search.
Be ready to discuss your goals for each major area of your life: career, personal development and learning, family, physical (health), community service, and (if your interviewer is clearly a religious person) you could very briefly and generally allude to your spiritual goals (showing you are a well-balanced individual with your values in the right order).
Be prepared to describe each goal in terms of specific milestones you wish to accomplish along the way, time periods you're allotting.

My short-term objectives are to graduate from the Professional Development Program before the standard two years and begin developing a clientele. As an intern, I prepared ahead of time by studying for the Series 7 and Series 64 exams that constitute a majority of a beginning financial consultant's time. I'd like to make make the company that hires me wonder what it ever did without me.


15.Where do you see yourself in five years?

This is the interviewer trying to see how you are in making long range plans and if you have goals that mesh with the organizations. One way to answer this question is to look back on your accomplishments to date: “I started out in my profession as a junior clerk while I completed my college studies during the evenings. Once I had my degree, I applied for a transfer to a more advanced position, citing my on-the-job training. This has been my pattern for my career with my past 2 employers. I learn quickly on the job and am willing to take classes and workshops to augment my experience. I have been able to assume greater responsibilities and add more value to the organization. I do not think in terms of titles… I think more in terms of “How can I solve this problem? Since this has been my career style to date, I do not imagine it to change. In five years, I feel I will have continued to learn, to grow into a position of more responsibility and will have made a significant contribution to the organization.”

Although it is hard to predict the future, I sincerely believe that I will become a very good financial consultant. I believe that my abilities will allow me to excel to the point that I can seek other opportunities as a portfolio manager (the next step) and possibly even higher. My ultimate goal continues to be -- and will always be -- to be the best at whatever level I am working at within Merrill Lynch's corporate structure.

16.Where do you want to become ten years from now?

Ten years from now I see myself as a successful consultant for a world-class firm like yours. I want to have developed a wonderful bond with my employer I will have proven myself a highly competent systems analyst and will represent my company in helping others find solutions to their information-systems needs in a professional and timely manner.

17.Would you rather work with information or with people?

I like the validity of information and also like the energy that comes with working with people. The best thing about working in a group is combining the great minds from different perspectives and coming up with something extremely great, compared with when you're working alone. At the same time, information can generate vitality in the project you're working on. No matter how many heads you've got together, without information, you can't go very far. The perfect situation would be a combination of working with information and people, and I'm confident of my abilities in both areas.

18.Do you have the qualifications and personal characteristics necessary for success in your chosen career?

I believe I have a combination of qualities to be successful in this career. First, I have a strong interest, backed by a solid, well-rounded, state-of-the-art education, especially in a career that is technically oriented. This basic ingredient, backed by love of learning, problem-solving skills, well-rounded interests, determination to succeed and excel, strong communication skills, and the ability to work hard, are the most important qualities that will help me succeed in this career. To succeed, you also need a natural curiosity about how systems work -- the kind of curiosity I demonstrated when I upgraded my two computers recently. Technology is constantly changing, so you must a fast learner just to keep up or you will be overwhelmed. All of these traits combine to create a solid team member in the ever-changing field of information systems. I am convinced that I possess these characteristics and am ready to be a successful team member for your firm.

19.What are your weak points?

Don’t say you have one, but give one that is really a “positive in disguise.” I am sometimes impatient and do to much work myself when we are working against tight deadlines.” Or “I compliment and praise my staff, but feel I can improve.”

20.What personal weakness has caused you the greatest difficulty in school or on the job?

My greatest weakness had been delegation. I would take it upon myself to do many small projects throughout my shift as a manager that could have been done by others in an attempt to improve my workers' efficiency. Once I realized that I was doing more work than the other assistant managers, and they were achieving better results, I reevaluated what I was doing. I quickly realized that if I assigned each person just one small project at the beginning of their shift, clearly state expectations for the project, and then follow up that everything would get done, and I could manage much more efficiently and actually accomplish much more.

21.How has your education prepared you for your career?

This is a broad question and you need to focus on the behavioral examples in your educational background which specifically align to the required competencies for the career.

An example: “My education has focused on not only the learning the fundamentals, but also on the practical application of the information learned within those classes. For example, I played a lead role in a class project where we gathered and analyzed best practice data from this industry. Let me tell you more about the results . . .”

Focus on behavioral examples supporting the key competencies for the career. Then ask if they would like to hear more examples.

As you will note on my resume, I've taken not only the required core classes in the _____ field, I've also gone above and beyond. I've taken every class the college has to offer in the field and also completed an independent study project specifically in this area. But it's not just taking the classes to gain academic knowledge I've taken each class, both inside and outside of my major, with this profession in mind. So when we're studying _____ in _____, I've viewed it from the perspective of _____. In addition, I've always tried to keep a practical view of how the information would apply to my job. Not just theory, but how it would actually apply. My capstone course project in my final semester involved developing a real-world model of _____, which is very similar to what might be used within your company...


22.Have you ever had a conflict with a boss or professor? How was it resolved?

Note that if you say no, most interviewers will keep drilling deeper to find a conflict. The key is how you behaviorally reacted to conflict and what you did to resolve it.

For example: “Yes, I have had conflicts in the past. Never major ones, but there have been disagreements that needed to be resolved. I've found that when conflict occurs, it helps to fully understand the other person’s perspective, so I take time to listen to their point of view, and then I seek to work out a collaborative solution. For example . . .”

Focus your answer on the behavioral process for resolving the conflict and working collaboratively.

23.If I were to ask your professors to describe you, what would they say?

This is a threat of reference check question. Do not wait for the interview to know the answer. Ask any prior bosses or professors in advance. And if they’re willing to provide a positive reference, ask them for a letter of recommendation.

Then you can answer the question like this:
“I believe she would say I'm a very energetic person, that I’m results oriented and one of the best people she has ever worked with. Actually, I know she would say that, because those are her very words. May I show you her letter of recommendation?”

So be prepared in advance with your letters of recommendation.

24.Tell me about a time when you had to plan and coordinate a project from start to finish.

I headed up a project which involved customer service personnel and technicians. I organized a meeting to get everyone together to brainstorm and get his or her input. From this meeting I drew up a plan, taking the best of the ideas. I organized teams, balancing the mixture of technical and non-technical people. We had a deadline to meet, so I did periodic checks with the teams. After three weeks, we were exceeding expectations, and were able to begin implementation of the plan. It was a great team effort, and a big success. I was commended by management for my leadership, but I was most proud of the team spirit and cooperation which it took to pull it off.

25.Describe a situation where others you were working with on a project disagreed with your ideas. What did you do?

I was on a project team in a business class in my freshman year in college, The group brainstormed ideas for the video we were assigned to produce, and everyone but me was leaning toward an idea that would be easy. I suggested instead an idea that would be more difficult but would be something different that no other group would be doing. I used my communications skills to persuade the rest of the group to use my idea. During the project, we really learned what teamwork was all about, became a close team, and ended up putting a lot of hard work into the project. All the team members ended up feeling very proud of the video, and they thanked me for the idea -- for which we earned an A.

26.Why did you choose to attend your college?

My college has always had a reputation as having an excellent accounting department, so I knew that if I enrolled there, I would achieve first-class preparation for my chosen career field. It is also a highly accredited school known for satisfying employers with the preparation of its graduates -- that's why companies like yours recruit at my school -- the school produces top graduates. The school offers an excellent liberal-arts background, which research shows equips graduates with numerous qualities, such as versatility and strong critical-thinking skills. Finally, having visited the campus before enrolling, I knew that the business school emphasized group projects. During my four years in the school, I participated in more than 35 group projects, which taught me invaluable teamwork, communication, and interpersonal skills.

27.What changes would you make at your college?

My major department had a wonderful internship program, and I was able to complete three valuable internships with my department's guidance. Some other departments in the business school don't have internship programs that are as strong as my department's. I'd like to see all the departments have strong internship programs so all my school's business grads would have the same opportunities that I had.

28.How will the academic program and coursework you've taken benefit your career?

As you will note on my resume, I've taken not only the required core classes for the finance field, I've also gone above and beyond by double majoring in accounting. I doubled majored since I knew that the financial consulting field requires much knowledge of portfolio analysis and understanding of the tax laws. I believe that my success in both areas of study have specifically prepared me for this area. But it's not just taking the classes in these two areas that allow me to offer Merrill Lynch clients more. I minored in Spanish to understand the growing Hispanic clientele in the Central Florida area, which as you are well aware, is a growing source of revenue for the industry. If you like, I can elaborate on other aspects of my education further.


29.What were your favorite classes? Why?

My favorite classes have been the ones pertaining to my major, which is marketing. These classes have laid the groundwork for my career in marketing. They have also taught me skills that I can bring to my employer, ranging from communication skills to interacting with others.

30. Do you enjoy doing independent research?
Are you the type of student for whom conducting independent research has been a positive experience?

Yes, I love it. I thoroughly enjoyed my senior research in college while many others in my class were miserable. I was never tired of learning more about my topic and found it exhilarating to be researching something that had not been studied before.


31.Who were your favorite professors? Why? Describe the type of professor that has created the most beneficial learning experience for you.

My favorite professors were the ones who gave me hands-on learning experiences that I can apply to my career. Any person can make you memorize the quadratic equation, but someone who can show you how to use it, and why, were the professors I liked. I liked teachers who realized that sometimes there is more then one answer and everyone thinks differently.

32.Why is your GPA not higher? Do you think that your grades are a indication of your academic achievement?

I have focused much of my energy on work and obtaining real-world experience. I commend my classmates who have earned high GPAs, but I also feel it's important to be well-rounded. In addition to work experience, I participated in sports and extracurricular activities in school. These activities taught me leadership, communication, and teamwork skills. Sometimes my heavy load has not allowed me to keep up with some of my studies, but I have learned an enormous amount that I can apply in my future industry. As you will discover if you talk to my supervisors, my ability to work effectively is much more reflective of my future potential than is my GPA.


33.Do you have any plans for further education? What plans do you have for continued study? An advanced degree?

I plan to continue my education for the rest of my life. In any technology-related field, keeping up to date through continuing education is of the utmost importance. Continuing education can include on-the-job training, courses sponsored by the employer, and courses taken in new technologies as they emerge. I plan to be not only a career employee but a career student so that I can be the best information systems analyst I can be. I will ensure, however, that any education I pursue not only doesn't interfere with my job or the company's policies, but will enhance my value as an employee.

34.Give an example of how you applied knowledge from previous coursework to a project in another class.

Last semester I was taking a microeconomics and a statistics course. One of the microeconomics projects dealt with showing the relationship between the probability that customers would stop buying a product if the price was raised a certain amount. Through what I learned in statistics I could find the median where the price was the highest and still kept most of the customers happy.

35. Describe a situation in which you found that your results were not up to your professor's or supervisor's expectations. What happened? What action did you take?

Recently I was asked to put together a proposal for a migration of network systems. Misunderstanding my boss, I thought it was just an informal paper. When I presented it to him days later, he was upset with the quality since it had to be presented to our VP. I explained my misunderstanding, apologized, reworked the paper, and had it back to him with enough time for him to review it before he presented it successfully at the meeting

36.What do you know about our organization?

Research the target company before the interview. Basic research is the only way to prepare for this question. Do your homework, and you’ll score big on this question. Talk about products, services, history and people, especially any friends that work there. “But I would love to know more, particularly from your point of view. Do we have time to cover that now?

This question is one reason to do some research on the organization before the interview. Find out where they have been and where they are going. What are the current issues and who are the major players?

37.What experience do you have?

Try to cite experience relevant to the company’s concerns. Also, try answering these questions with a question: “Are you looking for overall experience or experience in some specific area of special interest to you?” Let the interviewer’s response guide your answer.

What experience do you have in this field? Speak about specifics that relate to the position you are applying for. If you do not have specific experience, get as close as you can.

I think I have my current job because of my experiences abroad. Those experiences gave me greater self-confidence and a greater understanding of myself, which led to my willingness to uproot myself and try new work in a new location.”

38.According to your definition of success, how successful have you been so far?

Be prepared to define success, and then respond (consistent record of responsibility)
You should always answer yes and briefly explain why. A good explanation is that you have set goals, and you have met some and are on track to achieve the others.

39. How has your college experience prepared you for a business career?

Emphasize your best and favorite subjects. If grades were average, talk about leadership or jobs you took to finance your education. Talk about extra-curricular activities (clubs, sports, volunteer work)

I have prepared myself to transition into the the work force through real-world experience involving travel abroad, internship, and entrepreneurial opportunities. While interning with a private organization in Ecuador, I developed a 15-page marketing plan composed in Spanish that recommended more effective ways the company could promote its services. I also traveled abroad on two other occasions in which I researched the indigenous culture of the Mayan Indians in Todos Santos, Guatemala, and participate din a total language immersion program in Costa Rica. As you can see from my academic, extracurricular, and experiential background, I have unconditionally committed myself to success as a marketing professional.

40.What do you look for in a job?

Flip this one over. Despite the question, the employer isn’t really interested in what you are looking for. He’s interested in what he is looking for. Address his interests, rather than yours. Use words like “contribute,” “enhance,” “improve,” and “team environment.” Fit your answer to their needs Relate your preferences and satisfiers/dissatisfiers to the job opening. ---------------------------------------------------------------------------------
---------------------------------------------------------------------------------

Friday, October 01, 2004

AutoNumber And Identity Functionality in Oracle

Developers who are used to AutoNumber columns in MS Access or Identity columns in SQL Server often complain when they have to manually populate primary key columns using sequences. This type of functionality is easily implemented in Oracle using triggers.First we create a table with a suitable primary key column and a sequence to support it:
CREATE TABLE departments (
ID NUMBER(10) NOT NULL,
DESCRIPTION VARCHAR2(50) NOT NULL);
ALTER TABLE departments ADD (
CONSTRAINT dept_pk PRIMARY KEY (ID));
CREATE SEQUENCE dept_seq;Next we create a trigger to populate the ID column if it's not specified in the insert:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON departments
FOR EACH ROW
WHEN (:new.id IS NULL)
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/Finally we can test it using the automatic and manual population methods:
SQL> INSERT INTO departments (description)
2 VALUES ('Development');
1 row created.
SQL> SELECT * FROM departments;
ID DESCRIPTION
---------- --------------------------------------------------
1 Development
1 row selected.
SQL> INSERT INTO departments (id, description)
2 VALUES (dept_seq.NEXTVAL, 'Accounting');
1 row created.
SQL> SELECT * FROM departments;
ID DESCRIPTION
---------- --------------------------------------------------
1 Development
2 Accounting
2 rows selected.
SQL>The trigger can be modified to give slightly different results. If the insert trigger needs to perform more functionality than this one task you may wish to do something like:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON departments
FOR EACH ROW
BEGIN
SELECT NVL(:new.id, dept_seq.NEXTVAL)
INTO :new.id
FROM dual;

-- Do more processing here.
END;
/To overwrite any values passed in you should do the following:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON departments
FOR EACH ROW
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
/To error if a value is passed in you should do the following:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON departments
FOR EACH ROW
BEGIN
IF :new.is IS NOT NULL THEN
RAISE_APPLICATION_ERROR(-20000, 'ID cannot be specified');
ELSE
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END IF;
END;
/Hope this helps.
http://www.oracle-base.com/articles/8i/AutoNumber.php

Tuesday, September 07, 2004

10 Tools for Dot Net Developer

http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/TenMHToolEDevShouDN.mspx欢迎来到 MSDN > 企业开发
每个开发人员现在应该下载的十种必备工具
发布日期: 7/20/2004 更新日期: 7/20/2004
本文自发布以来已经增加了新信息。
请参阅下面的编辑更新。
本文讨论:

用于编写单元测试的 NUnit

用于创建代码文档资料的 NDoc

用于生成解决方案的 NAnt

用于生成代码的 CodeSmith

用于监视代码的 FxCop

用于编译少量代码的 Snippet Compiler

两种不同的转换器工具:ASP.NET 版本转换器和 Visual Studio .NET 项目转换器

用于生成正则表达式的 Regulator

用于分析程序集的 .NET Reflector
本文使用了下列技术:
.NET、C# 或 Visual Basic .NET、Visual Studio .NET
除非您使用能够获得的最佳工具,否则您无法期望生成一流的应用程序。除了像 Visual Studio®.NET 这样的著名工具以外,还可以从 .NET 社区获得许多小型的、不太为人所知的工具。在本文中,我将向您介绍一些目前可以获得的、面向 .NET 开发的最佳免费工具。我将引导您完成一个有关如何使用其中每种工具的快速教程 — 一些工具在许多时候可以使您节约一分钟,而另一些工具则可能彻底改变您编写代码的方式。因为我要在本篇文章中介绍如此之多的不同工具,所以我无法详尽讨论其中每种工具,但您应该了解到有关每种工具的足够信息,以便判断哪些工具对您的项目有用。
本页内容

Snippet Compiler

Regulator

CodeSmith

生成自定义模板

NUnit

编写 NUnit 测试

FxCop

Lutz Roeder 的 .NET Reflector

NDoc

NAnt

实际运行的 NAnt

转换工具

小结
Snippet Compiler
Snippet Compiler 是一个基于 Windows® 的小型应用程序,您可以通过它来编写、编译和运行代码。如果您具有较小的代码段,并且您不希望为其创建完整的 Visual Studio .NET 项目(以及伴随该项目的所有文件),则该工具将很有用。
例如,假设我希望向您说明如何从 Microsoft?.NET 框架中启动另一个应用程序。在 Snippet Compiler 中,我将通过新建一个能够创建小型控制台应用程序的文件开始。可以在该控制台应用程序的 Main 方法内部创建代码片段,而这正是我要在这里做的事情。下面的代码片段演示了如何从 .NET 框架中创建记事本实例: System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName= "notepad.exe";
proc.Start();
proc.WaitForExit();
当然该代码片段本身无法编译,而这正是 Snippet Compiler 的用武之地。图 1 显示了 Snippet Compiler 中的这一代码示例。
图 1 Snippet Compiler
要测试该代码片段,只须按 play(运行)按钮(绿色三角形),它就会在调试模式下运行。该代码片段将生成一个弹出式控制台应用程序,并且将显示记事本。当您关闭记事本时,该控制台应用程序也将关闭。
就我个人而言,我是在尝试为某位向我求助的人士创建一个小型示例时,才发现 Snippet Compiler 是如此宝贵的 — 如果不使用该工具,则我通常必须新建一个项目,确保每个部分都能编译通过,然后将代码片段发送给求助者,并删除该项目。Snippet Compiler 使得这一过程变得更加容易、更加愉快。
Snippet Compiler 由 Jeff Key 编写,并且可以从 http://www.sliver.com/dotnet/SnippetCompiler 下载。
返回页首
Regulator
Regulator 是最后一个添加到我的头等工具清单中的。它是一种很有特色的工具,能够使生成和测试正则表达式变得很容易。人们对正则表达式重新产生了兴趣,因为它们在 .NET 框架中受到很好的支持。正则表达式用来基于字符、频率和字符顺序定义字符串中的模式。它们最常见的用途是作为验证用户输入有效性的手段或者作为在较大字符串中查找字符串的方法 — 例如,在 Web 页上查找 URL 或电子邮件地址。
Regulator 使您可以输入一个正则表达式以及一些针对其运行该表达式的输入内容。这样,在应用程序中实现该正则表达式之前,您可以了解它将产生什么效果以及它将返回哪些种类的匹配项。图 2 显示了带有简单正则表达式的 Regulator。
文档中包含该正则表达式 — 在该示例中,它是 [0-9]*,应该匹配一行中任意数量的数字。右下侧的框中含有针对该正则表达式的输入,而左下侧的框显示了该正则表达式在输入内容中找到的匹配项。在这样的单独应用程序中编写和测试正则表达式,要比尝试在您的应用程序中处理它们容易得多。
Regulator 中的最佳功能之一是能够在 regexlib.com 搜索联机正则表达式库。例如,如果您在搜索框中输入字符串“phone”,您将找到 20 种以上能够匹配各种电话号码的不同的正则表达式,包括用于英国、澳大利亚的表达式以及其他许多电话号码。Regulator 由 Roy Osherove 编写,并且可以在 http://royo.is-a-geek.com/regulator 下载。
返回页首
CodeSmith
CodeSmith 是一种基于模板的代码生成工具,它使用类似于 ASP.NET 的语法来生成任意类型的代码或文本。与其他许多代码生成工具不同,CodeSmith 不要求您订阅特定的应用程序设计或体系结构。使用 CodeSmith,可以生成包括简单的强类型集合和完整应用程序在内的任何东西。
当您生成应用程序时,您经常需要重复完成某些特定的任务,例如编写数据访问代码或者生成自定义集合。CodeSmith 在这些时候特别有用,因为您可以编写模板自动完成这些任务,从而不仅提高您的工作效率,而且能够自动完成那些最为乏味的任务。CodeSmith 附带了许多模板,包括对应于所有 .NET 集合类型的模板以及用于生成存储过程的模板,但该工具的真正威力在于能够创建自定义模板。为了使您能够入门,我将快速介绍一下如何生成自定义模板。
返回页首
生成自定义模板
CodeSmith 模板只是一些可以在任意文本编辑器中创建的文本文件。它们的唯一要求是用 .cst 文件扩展名来保存它们。我将要生成的示例模板将接受一个字符串,然后基于该字符串生成一个类。创建模板的第一步是添加模板头,它可声明模板的语言、目标语言以及简要模板说明:
模板的下一部分是属性声明,在这里可声明将在模板每次运行时指定的属性。就该模板而言,我要使用的唯一属性只是一个字符串,因此属性声明如下所示:
该属性声明将使 ClassName 属性出现在 CodeSmith 属性窗口中,以便可以在模板运行时指定它。下一步是实际生成模板主体,它非常类似于用 ASP.NET 进行编码。您可以在图 3 中查看该模板的主体。[编辑更新 — 6/16/2004:图 3 中的代码已被更新,以便对多线程操作保持安全。]
正如您所见,该模板接受字符串输入并使用该类名生成单独的类。在模板主体中,使用与 ASP.NET 中相同的起始和结束标记。在该模板中,我只是插入属性值,但您还可以在这些标记内部使用任意类型的 .NET 代码。在该模板完成之后,您就可以通过双击它或者从 CodeSmith 应用程序中打开它将其加载到 CodeSmith 中。图 4 显示了已经加载到 CodeSmith 中的该模板。
您可以看到左侧的属性正是我在该模板中声明的属性。如果我输入“SingletonClass”作为类名,并单击 Generate 按钮,则将生成图 3 的底部显示的类。
CodeSmith 使用起来相当容易,如果能够正确应用,则可以产生一些令人难以置信的结果。面向代码生成的应用程序中最常见的部分之一是数据访问层。CodeSmith 包括一个名为 SchemaExplorer 的特殊的程序集,可用来从表、存储过程或几乎任何其他 SQL Server? 对象生成模板。
CodeSmith 由 Eric J. Smith 编写,并且可以在 http://www.ericjsmith.net/codesmith 下载。
返回页首
NUnit
NUnit 是为 .NET 框架生成的开放源代码单元测试框架。NUnit 使您可以用您喜欢的语言编写测试,从而测试应用程序的特定功能。当您首次编写代码时,单元测试是一种测试代码功能的很好方法,它还提供了一种对应用程序进行回归测试的方法。NUnit 应用程序提供了一个用于编写单元测试的框架,以及一个运行这些测试和查看结果的图形界面。
返回页首
编写 NUnit 测试
作为示例,我将测试 .NET 框架中 Hashtable 类的功能,以确定是否可以添加两个对象并且随后检索这些对象。我的第一步是添加对 NUnit.Framework 程序集的引用,该程序集将赋予我对 NUnit 框架的属性和方法的访问权。接下来,我将创建一个类并用 TestFixture 属性标记它。该属性使 NUnit 可以知道该类包含 NUnit 测试: using System;
using System.Collections;
using NUnit.Framework;
namespace NUnitExample
{
[TestFixture]
public class HashtableTest {
public HashtableTest() {

}
}
}
下一步,我将创建一个方法并用 [Test] 属性标记它,以便 NUnit 知道该方法是一个测试。然后,我将建立一个 Hashtable 并向其添加两个值,再使用 Assert.AreEqual 方法查看我是否可以检索到与我添加到 Hashtable 的值相同的值,如下面的代码所示: [Test]
public void HashtableAddTest()
{
Hashtable ht = new Hashtable();

ht.Add("Key1", "Value1");
ht.Add("Key2", "Value2");
Assert.AreEqual("Value1", ht["Key1"], "Wrong object returned!");
Assert.AreEqual("Value2", ht["Key2"], "Wrong object returned!");
}
这将确认我可以首先向 Hashtable 中添加值并随后检索相应的值 — 这是一个很简单的测试,但能够表现 NUnit 的功能。存在许多测试类型以及各种 Assert 方法,可使用它们来测试代码的每个部分。
要运行该测试,我需要生成项目,在 NUnit 应用程序中打开生成的程序集,然后单击 Run 按钮。图 5 显示了结果。当我看到那个大的绿色条纹时,我有一种兴奋和头晕的感觉,因为它让我知道测试已经通过了。这个简单的示例表明 NUnit 和单元测试是多么方便和强大。由于能够编写可以保存的单元测试,并且每当您更改代码时都可以重新运行该单元测试,您不仅可以更容易地检测到代码中的缺陷,而且最终能够交付更好的应用程序。
图 5 NUnit
NUnit 是一个开放源代码项目,并且可以从 http://www.nunit.org/ 下载。还有一个优秀的 NUnit Visual Studio .NET 外接程序,它使您可以直接从 Visual Studio 中运行单元测试。您可以在 http://sourceforge.net/projects/nunitaddin 找到它。有关 NUnit 及其在测试驱动开发中的地位的详细信息,请参阅文章“Test-Driven C#: Improve the Design and Flexibility of Your Project with Extreme Programming Techniques”(MSDN ®Magazine 2004 年 4 月刊)。
返回页首
FxCop
.NET 框架非常强大,这意味着存在创建优秀应用程序的极大可能,但是也同样存在创建劣质程序的可能。FxCop 是有助于创建更好的应用程序的工具之一,它所采用的方法是:使您能够分析程序集,并使用一些不同的规则来检查它是否符合这些规则。FxCop 随附了由 Microsoft 创建的固定数量的规则,但您也可以创建并包括您自己的规则。例如,如果您决定所有的类都应该具有一个不带任何参数的默认构造函数,则可以编写一条规则,以确保程序集的每个类上都具有一个构造函数。这样,无论是谁编写该代码,您都将获得一定程度的一致性。如果您需要有关创建自定义规则的详细信息,请参阅 John Robbins 的有关该主题的 Bugslayer 专栏文章(MSDN ® Magazine 2004 年 6 月刊)。
那么,让我们观察一下实际运行的 FxCop,并且看一下它在我一直在处理的 NUnitExample 程序集中找到哪些错误。当您打开 FxCop 时,您首先需要创建一个 FxCop 项目,然后向其添加您要测试的程序集。在将该程序集添加到项目以后,就可以按 Analyze,FxCop 将分析该程序集。图 6 中显示了在该程序集中找到的错误和警告。
FxCop 在我的程序集中找到了几个问题。您可以双击某个错误以查看详细信息,包括规则说明以及在哪里可以找到更多信息。(您可以做的一件有趣的事情是在框架程序集上运行 FxCop 并查看发生了什么事情。)
FxCop 可以帮助您创建更好的、更一致的代码,但它无法补偿低劣的应用程序设计或非常简单拙劣的编程。FxCop 也不能替代对等代码检查,但是因为它可以在进行代码检查之前捕获大量错误,所以您可以花费更多时间来解决严重的问题,而不必担心命名约定。FxCop 由 Microsoft 开发,并且可以从 http://www.gotdotnet.com/team/fxcop 下载。
返回页首
Lutz Roeder 的 .NET Reflector
下一个必不可少的工具称为 .NET Reflector,它是一个类浏览器和反编译器,可以分析程序集并向您展示它的所有秘密。.NET 框架向全世界引入了可用来分析任何基于 .NET 的代码(无论它是单个类还是完整的程序集)的反射概念。反射还可以用来检索有关特定程序集中包含的各种类、方法和属性的信息。使用 .NET Reflector,您可以浏览程序集的类和方法,可以分析由这些类和方法生成的 Microsoft 中间语言 (MSIL),并且可以反编译这些类和方法并查看 C# 或 Visual Basic ®.NET 中的等价类和方法。
为了演示 .NET Reflector 的工作方式,我将加载和分析前面已经显示的 NUnitExample 程序集。图 7 显示了 .NET Reflector 中加载的该程序集。
图 7 NUnitExample 程序集
在 .NET Reflector 内部,有各种可用来进一步分析该程序集的工具。要查看构成某个方法的 MSIL,请单击该方法并从菜单中选择 Disassembler。
除了能够查看 MSIL 以外,您还可以通过选择 Tools 菜单下的 Decompiler 来查看该方法的 C# 形式。通过在 Languages 菜单下更改您的选择,您还可以查看该方法被反编译到 Visual Basic .NET 或 Delphi 以后的形式。以下为 .NET Reflector 生成的代码: public void HashtableAddTest()
{
Hashtable hashtable1;
hashtable1 = new Hashtable();
hashtable1.Add("Key1", "Value1");
hashtable1.Add("Key2", "Value2");
Assert.AreEqual("Value1", hashtable1["Key1"],
"Wrong object returned!");
Assert.AreEqual("Value2", hashtable1["Key2"],
"Wrong object returned!");
}
前面的代码看起来非常像我为该方法实际编写的代码。以下为该程序集中的实际代码: public void HashtableAddTest()
{
Hashtable ht = new Hashtable();

ht.Add("Key1", "Value1");
ht.Add("Key2", "Value2");
Assert.AreEqual("Value1", ht["Key1"],
"Wrong object returned!");
Assert.AreEqual("Value2", ht["Key2"],
"Wrong object returned!");
}
尽管上述代码中存在一些小的差异,但它们在功能上是完全相同的。
虽然该示例是一种显示实际代码与反编译代码之间对比的好方法,但在我看来,它并不代表 .NET Reflector 所具有的最佳用途 — 分析 .NET 框架程序集和方法。.NET 框架提供了许多执行类似操作的不同方法。例如,如果您需要从 XML 中读取一组数据,则存在多种使用 XmlDocument、XPathNavigator 或 XmlReader 完成该工作的不同方法。通过使用 .NET Reflector,您可以查看 Microsoft 在编写数据集的 ReadXml 方法时使用了什么,或者查看他们在从配置文件读取数据时做了哪些工作。.NET Reflector 还是一个了解以下最佳实施策略的优秀方法:创建诸如 HttpHandlers 或配置处理程序之类的对象,因为您可以了解到 Microsoft 工作组实际上是如何在框架中生成这些对象的。
.NET Reflector 由 Lutz Roeder 编写,并且可以从 http://www.aisto.com/roeder/dotnet 下载。
返回页首
NDoc
编写代码文档资料几乎总是一项令人畏惧的任务。我所说的不是早期设计文档,甚至也不是更为详细的设计文档;我说的是记录类上的各个方法和属性。NDoc 工具能够使用反射来分析程序集,并使用从 C# XML 注释生成的 XML 自动为代码生成文档资料。XML 注释仅适用于 C#,但有一个名为 VBCommenter 的 Visual Studio .NET Power Toy,它能够为 Visual Basic .NET 完成类似的工作。此外,下一版本的 Visual Studio 将为更多语言支持 XML 注释。
使用 NDoc 时,您仍然在编写代码的技术文档,但您是在编写代码的过程中完成了文档编写工作(在 XML 注释中),而这更容易忍受。使用 NDoc 时,第一步是为您的程序集打开 XML 注释生成功能。右键单击该项目并选择 Properties Configuration Properties Build,然后在 XML Documentation File 选项中输入用于保存 XML 文件的路径。当该项目生成时,将创建一个 XML 文件,其中包含所有 XML 注释。下面是 NUnit 示例中的一个用 XML 编写了文档的方法: ///
/// This test adds a number of values to the Hashtable collection
/// and then retrieves those values and checks if they match.
///

[Test]
public void HashtableAddTest()
{
//Method Body Here
}
有关该方法的 XML 文档资料将被提取并保存在 XML 文件中,如下所示:
This test adds a number of values to the Hashtable collection
and then retrieves those values and checks if they match.


NDoc 使用反射来考察您的程序集,然后读取该文档中的 XML,并且将它们进行匹配。NDoc 使用该数据来创建任意数量的不同文档格式,包括 HTML 帮助文件 (CHM)。在生成 XML 文件以后,下一步是将程序集和 XML 文件加载到 NDoc 中,以便可以对它们进行处理。通过打开 NDoc 并单击 Add 按钮,可以容易地完成该工作。
在将程序集和 XML 文件加载到 NDoc 中并且使用可用的属性范围自定义输出以后,单击 Generate 按钮将启动生成文档资料的过程。使用默认的属性,NDoc 可以生成一些非常吸引人并且实用的 .html 和 .chm 文件,从而以快速有效的方式自动完成原来非常乏味的任务。
NDoc 是一个开放源代码项目,并且可以从 http://ndoc.sourceforge.net/ 下载。
返回页首
NAnt
NAnt 是一个基于 .NET 的生成工具,与当前版本的 Visual Studio .NET 不同,它使得为您的项目创建生成过程变得非常容易。当您拥有大量从事单个项目的开发人员时,您不能依赖于从单个用户的座位进行生成。您也不希望必须定期手动生成该项目。您更愿意创建每天晚上运行的自动生成过程。NAnt 使您可以生成解决方案、复制文件、运行 NUnit 测试、发送电子邮件,等等。遗憾的是,NAnt 缺少漂亮的图形界面,但它的确具有可以指定应该在生成过程中完成哪些任务的控制台应用程序和 XML 文件。注意,MSBuild(属于 Visual Studio 2005 的新的生成平台)为每种健壮的生成方案进行了准备,并且由基于 XML 的项目文件以类似的方式驱动。
返回页首
实际运行的 NAnt
在该示例中,我将为前面创建的 NUnitExample 解决方案创建一个 NAnt 版本文件。首先,我需要创建一个具有 .build 扩展名的 XML 文件,将其放在我的项目的根目录中,然后向该文件的顶部添加一个 XML 声明。我需要添加到该文件的第一个标记是 project 标记:

The NUnit Example Project

项目标记还用于设置项目名称、默认目标以及基目录。Description 标记用于设置该项目的简短说明。
接下来,我将添加 property 标记,该标记可用于将设置存储到单个位置(随后可以从文件中的任意位置访问该位置)。在该例中,我将创建一个名为 debug 的属性,我可以随后将其设置为 true 或 false,以反映我是否要在调试配置下编译该项目。(最后,这一特定属性并未真正影响如何生成该项目;它只是您设置的一个变量,当您真正确定了如何生成该项目时将读取该变量。)
接下来,我需要创建一个 target 标记。一个项目可以包含多个可在 NAnt 运行时指定的 target。如果未指定 target,则使用默认 target(我在 project 元素中设置的 target)。在该示例中,默认 target 是 build。让我们观察一下 target 元素,它将包含大多数生成信息:

在 target 元素内,我将把 target 的名称设置为 build,并且创建有关该 target 将做哪些工作的说明。我还将创建一个 csc 元素,该元素用于指定应该传递给 csc C# 编译器的数据。让我们看一下该 csc 元素:







首先,我必须设置该 csc 元素的 target。在该例中,我将创建一个 .dll 文件,因此我将 target 设置为 library。接下来,我必须设置 csc 元素的 output,它是将要创建 .dll 文件的位置。最后,我需要设置 debug 属性,它确定了是否在调试中编译该项目。因为我在前面创建了一个用于存储该值的属性,所以我可以使用下面的字符串来访问该属性的值:${debug}。Csc 元素还包含一些子元素。我需要创建两个元素:references 元素将告诉 NAnt 需要为该项目引用哪些程序集,sources 元素告诉 NAnt 要在生成过程中包含哪些文件。在该示例中,我引用了 NUnit.Framework.dll 程序集并包含了 HashtableTest.cs 文件。图 8 中显示了完整的生成文件。(您通常还要创建一个干净的 target,用于删除生成的文件,但为了简洁起见,我已经将其省略。)
要生成该文件,我需要转到我的项目的根目录(生成文件位于此处),然后从该位置执行 nant.exe。如果生成成功,您可以在该应用程序的 bin 目录中找到 .dll 和 .pdb 文件。尽管使用 NAnt 肯定不像在 Visual Studio 中单击 Build 那样简单,但它仍然是一种非常强大的工具,可用于开发按自动计划运行的生成过程。NAnt 还包括一些有用的功能,例如能够运行单元测试或者复制附加文件(这些功能没有受到当前 Visual Studio 生成过程的支持)。
NAnt 是一个开放源代码项目,并且可以从 http://nant.sourceforge.net/ 下载。
返回页首
转换工具
我已经将两个独立的工具合在一起放在标题“转换工具”下面。这两个工具都非常简单,但又可能极为有用。第一个工具是 ASP.NET 版本转换器,它可用于转换 ASP.NET(虚拟目录在它下面运行)的版本。第二个工具是 Visual Studio Converter,它可用于将项目文件从 Visual Studio .NET 2002 转换到 Visual Studio .NET 2003。
当 IIS 处理请求时,它会查看正在请求的文件的扩展名,然后基于该 Web 站点或虚拟目录的扩展名映射,将请求委派给 ISAPI 扩展或者自己处理该请求。这正是 ASP.NET 的工作方式;将为所有 ASP.NET 扩展名注册扩展名映射,并将这些扩展名映射导向 aspnet_isapi.dll。这种工作方式是完美无缺的,除非您安装了 ASP.NET 1.1 — 它会将扩展名映射升级到新版本的 aspnet_isapi.dll。当在 ASP.NET 1.0 上生成的应用程序试图用 1.1 版运行时,这会导致错误。要解决该问题,可以将所有扩展名映射重新转换到 1.0 版的 aspnet_isapi.dll,但是由于有 18 种扩展名映射,所以手动完成这一工作将很枯燥。这正是 ASP.NET 版本转换器可以发挥作用的时候。使用这一小型实用工具,可以转换任何单个 ASP.NET 应用程序所使用的 .NET 框架的版本。
图 9 ASP.NET 版本转换器
图 9 显示了实际运行的 ASP.NET 版本转换器。它的使用方法非常简单,只须选择相应的应用程序,然后选择您希望该应用程序使用的 .NET 框架版本。该工具随后将使用 aspnet_regiis.exe 命令行工具将该应用程序转换到所选版本的框架。随着将来版本的 ASP.NET 和 .NET 框架的发布,该工具将变得更为有用。
ASP.NET 版本转换器由 Denis Bauer 编写,并且可以从 http://www.denisbauer.com/NETTools/ASPNETVersionSwitcher.aspx 下载。
Visual Studio .NET 项目转换器(参见图 10)非常类似于 ASP.NET 版本转换器,区别在于它用于转换 Visual Studio 项目文件的版本。尽管在 .NET 框架的 1.0 版和 1.1 版之间只有很小的差异,但一旦将项目文件从 Visual Studio .NET 2002 转换到 Visual Studio .NET 2003,将无法再把它转换回去。虽然这在大多数时候可能不会成为问题(因为在 .NET 框架 1.0 版和 1.1 版之间几乎没有什么破坏性的更改),但在某些时刻您可能需要将项目转换回去。该转换器可以将任何解决方案或项目文件从 Visual Studio 7.1 (Visual Studio .NET 2003) 转换到 Visual Studio 7.0 (Visual Studio .NET 2002),并在必要时进行反向转换。
图 10 Visual Studio .NET 项目转换器
Visual Studio .NET 项目转换器由 Dacris Software 编写。该工具可以从 http://www.codeproject.com/macro/vsconvert.asp 下载。
返回页首
小结
本文采用走马观花的方式介绍了上述工具,但我已经试图起码向您提供足够的信息以激起您的好奇心。我相信本文已经让您在某种程度上领悟了几个免费工具,您可以立即开始使用这些工具来编写更好的项目。同时,我还要敦促您确保自己拥有所有其他可以获得的合适工具,无论是最新版本的 Visual Studio、功能强大的计算机还是免费的实用工具。拥有合适的工具将使一切变得大不相同。
James Avery 是一位使用 .NET 和其他 Microsoft 技术的顾问。他已经撰写了许多书籍和文章,他的最新著作是《ASP.NET Setup and Configuration Pocket Reference》(Microsoft Press, 2003)。您可以通过 javery@infozerk.com 向他发送电子邮件,并且在 http://www.dotavery.com/blog 阅读他的网络日记。
本文摘自 MSDN Magazine2004 年 7 月刊。
该杂志可在各地的报摊购买,也可以订阅
转到原英文页面
返回页首
适合打印机打印的版本 通过电子邮件发送此页面 添加到收藏夹 备注

Thursday, August 12, 2004

.Net 文章

David Wang's Blog - ISAPI

用户自己开发Custom Control
http://dev.csdn.net/develop/article/13/article/16/16199.shtm

NHibernate的关联映射(one-to-one,one-to-many,many-to-many)以及cascade分析

.NET开源项目介绍及资源推荐:序

IOC容器篇 CastleSpring.NETObjectBuilderStructureMap

数据持久层 NHibernateNBearCastle ActiveRecord iBATIS.NETDAAB, Dlinq
日志记录 Log4net, Logging Application Bloc, NLog
单元测试 NUnitTestDriven.Net NUnitForms NUnitAsp

老赵点滴


Spring.NET & NHibernate of C#.NET 技术论坛

TerryLee's Tech Space .NET设计模式

.NET技术网上资源

MetaBuilders - 一些Free的很有用的ASP.NET控件, 如RowSelectorColumn , GlobalRadioButton , UpDown 等.
http://metabuilders.com/products/

中国软件网(中国最大的技术社区)
http://www.csdn.net/
计算机世界开发者俱乐部
http://www.dev-club.com/
中国Dot Net俱乐部
http://www.aspx.cn/
微软官方MSDN权威站点:
http://msdn.microsoft.com/
微软官方ASP.NET站点:
http://www.asp.net/
微软官方Windows Form站点:
http://www.windowsforms.net/
微软官方Dot NET站点:
http://www.gotdotnet.com/
英文站点Code project:
http://www.codeproject.com/

Friday, July 16, 2004

GCC精彩之旅

GCC精彩之旅

GCC精彩之旅(一) 
作者:肖文鹏 发文时间:2004.03.22
 
在为Linux开发应用程序时,绝大多数情况下使用的都是C语言,因此几乎每一位Linux程序员面临的首要问题都是如何灵活运用C编译器。目前Linux下最常用的C语言编译器是GCC(GNU Compiler Collection),它是GNU项目中符合ANSI C标准的编译系统,能够编译用C、C++和Object C等语言编写的程序。GCC不仅功能非常强大,结构也异常灵活。最值得称道的一点就是它可以通过不同的前端模块来支持各种语言,如Java、Fortran、Pascal、Modula-3和Ada等。

开放、自由和灵活是Linux的魅力所在,而这一点在GCC上的体现就是程序员通过它能够更好地控制整个编译过程。在使用GCC编译程序时,编译过程可以被细分为四个阶段:

◆ 预处理(Pre-Processing)

◆ 编译(Compiling)

◆ 汇编(Assembling)

◆ 链接(Linking)

Linux程序员可以根据自己的需要让GCC在编译的任何阶段结束,以便检查或使用编译器在该阶段的输出信息,或者对最后生成的二进制文件进行控制,以便通过加入不同数量和种类的调试代码来为今后的调试做好准备。和其它常用的编译器一样,GCC也提供了灵活而强大的代码优化功能,利用它可以生成执行效率更高的代码。

GCC提供了30多条警告信息和三个警告级别,使用它们有助于增强程序的稳定性和可移植性。此外,GCC还对标准的C和C++语言进行了大量的扩展,提高程序的执行效率,有助于编译器进行代码优化,能够减轻编程的工作量。

GCC起步

在学习使用GCC之前,下面的这个例子能够帮助用户迅速理解GCC的工作原理,并将其立即运用到实际的项目开发中去。首先用熟悉的编辑器输入清单1所示的代码:

清单1:hello.c

#include
int main(void)
{
 printf ("Hello world, Linux programming!\n");
 return 0;
}
 


然后执行下面的命令编译和运行这段程序:

# gcc hello.c -o hello
# ./hello
Hello world, Linux programming!
 


从程序员的角度看,只需简单地执行一条GCC命令就可以了,但从编译器的角度来看,却需要完成一系列非常繁杂的工作。首先,GCC需要调用预处理程序cpp,由它负责展开在源文件中定义的宏,并向其中插入“#include”语句所包含的内容;接着,GCC会调用ccl和as将处理后的源代码编译成目标代码;最后,GCC会调用链接程序ld,把生成的目标代码链接成一个可执行程序。

为了更好地理解GCC的工作过程,可以把上述编译过程分成几个步骤单独进行,并观察每步的运行结果。第一步是进行预编译,使用-E参数可以让GCC在预处理结束后停止编译过程:

#  gcc -E hello.c -o hello.i
 


此时若查看hello.cpp文件中的内容,会发现stdio.h的内容确实都插到文件里去了,而其它应当被预处理的宏定义也都做了相应的处理。下一步是将hello.i编译为目标代码,这可以通过使用-c参数来完成:

#  gcc -c hello.i -o hello.o
 


GCC默认将.i文件看成是预处理后的C语言源代码,因此上述命令将自动跳过预处理步骤而开始执行编译过程,也可以使用-x参数让GCC从指定的步骤开始编译。最后一步是将生成的目标文件链接成可执行文件:

#  gcc hello.o -o hello
 


在采用模块化的设计思想进行软件开发时,通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用GCC能够很好地管理这些编译单元。假设有一个由foo1.c和foo2.c两个源文件组成的程序,为了对它们进行编译,并最终生成可执行程序foo,可以使用下面这条命令:

#  gcc foo1.c foo2.c -o foo
 


如果同时处理的文件不止一个,GCC仍然会按照预处理、编译和链接的过程依次进行。如果深究起来,上面这条命令大致相当于依次执行如下三条命令:

# gcc -c foo1.c -o foo1.o
# gcc -c foo2.c -o foo2.o
# gcc foo1.o foo2.o -o foo
 


在编译一个包含许多源文件的工程时,若只用一条GCC命令来完成编译是非常浪费时间的。假设项目中有100个源文件需要编译,并且每个源文件中都包含10000行代码,如果像上面那样仅用一条GCC命令来完成编译工作,那么GCC需要将每个源文件都重新编译一遍,然后再全部连接起来。很显然,这样浪费的时间相当多,尤其是当用户只是修改了其中某一个文件的时候,完全没有必要将每个文件都重新编译一遍,因为很多已经生成的目标文件是不会改变的。要解决这个问题,关键是要灵活运用GCC,同时还要借助像Make这样的工具。

警告提示功能

GCC包含完整的出错检查和警告提示功能,它们可以帮助Linux程序员写出更加专业和优美的代码。先来读读清单2所示的程序,这段代码写得很糟糕,仔细检查一下不难挑出很多毛病:

◆main函数的返回值被声明为void,但实际上应该是int;

◆使用了GNU语法扩展,即使用long long来声明64位整数,不符合ANSI/ISO C语言标准;

◆main函数在终止前没有调用return语句。

清单2:illcode.c

#include
void main(void)
{
  long long int var = 1;
  printf("It is not standard C code!\n");
}
 


下面来看看GCC是如何帮助程序员来发现这些错误的。当GCC在编译不符合ANSI/ISO C语言标准的源代码时,如果加上了-pedantic选项,那么使用了扩展语法的地方将产生相应的警告信息:

# gcc -pedantic illcode.c -o illcode
illcode.c: In function `main':
illcode.c:9: ISO C89 does not support `long long'
illcode.c:8: return type of `main' is not `int'
 


需要注意的是,-pedantic编译选项并不能保证被编译程序与ANSI/ISO C标准的完全兼容,它仅仅只能用来帮助Linux程序员离这个目标越来越近。或者换句话说,-pedantic选项能够帮助程序员发现一些不符合ANSI/ISO C标准的代码,但不是全部,事实上只有ANSI/ISO C语言标准中要求进行编译器诊断的那些情况,才有可能被GCC发现并提出警告。

除了-pedantic之外,GCC还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W开头,其中最有价值的当数-Wall了,使用它能够使GCC产生尽可能多的警告信息:

# gcc -Wall illcode.c -o illcode
illcode.c:8: warning: return type of `main' is not `int'
illcode.c: In function `main':
illcode.c:9: warning: unused variable `var'
 


GCC给出的警告信息虽然从严格意义上说不能算作是错误,但却很可能成为错误的栖身之所。一个优秀的Linux程序员应该尽量避免产生警告信息,使自己的代码始终保持简洁、优美和健壮的特性。

在处理警告方面,另一个常用的编译选项是-Werror,它要求GCC将所有的警告当成错误进行处理,这在使用自动编译工具(如Make等)时非常有用。如果编译时带上-Werror选项,那么GCC会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改。只有当相应的警告信息消除时,才可能将编译过程继续朝前推进。执行情况如下:

# gcc -Wall -Werror illcode.c -o illcode
cc1: warnings being treated as errors
illcode.c:8: warning: return type of `main' is not `int'
illcode.c: In function `main':
illcode.c:9: warning: unused variable `var'
 


对Linux程序员来讲,GCC给出的警告信息是很有价值的,它们不仅可以帮助程序员写出更加健壮的程序,而且还是跟踪和调试程序的有力工具。建议在用GCC编译源代码时始终带上-Wall选项,并把它逐渐培养成为一种习惯,这对找出常见的隐式编程错误很有帮助。

库依赖

在Linux下开发软件时,完全不使用第三方函数库的情况是比较少见的,通常来讲都需要借助一个或多个函数库的支持才能够完成相应的功能。从程序员的角度看,函数库实际上就是一些头文件(.h)和库文件(.so或者.a)的集合。虽然Linux下的大多数函数都默认将头文件放到/usr/include/目录下,而库文件则放到/usr/lib/目录下,但并不是所有的情况都是这样。正因如此,GCC在编译时必须有自己的办法来查找所需要的头文件和库文件。

GCC采用搜索目录的办法来查找所需要的文件,-I选项可以向GCC的头文件搜索路径中添加新的目录。例如,如果在/home/xiaowp/include/目录下有编译时所需要的头文件,为了让GCC能够顺利地找到它们,就可以使用-I选项:

# gcc foo.c -I /home/xiaowp/include -o foo
 


同样,如果使用了不在标准位置的库文件,那么可以通过-L选项向GCC的库文件搜索路径中添加新的目录。例如,如果在/home/xiaowp/lib/目录下有链接时所需要的库文件libfoo.so,为了让GCC能够顺利地找到它,可以使用下面的命令:

# gcc foo.c -L /home/xiaowp/lib -lfoo -o foo
 


值得好好解释一下的是-l选项,它指示GCC去连接库文件libfoo.so。Linux下的库文件在命名时有一个约定,那就是应该以lib三个字母开头,由于所有的库文件都遵循了同样的规范,因此在用-l选项指定链接的库文件名时可以省去lib三个字母,也就是说GCC在对-lfoo进行处理时,会自动去链接名为libfoo.so的文件。

Linux下的库文件分为两大类分别是动态链接库(通常以.so结尾)和静态链接库(通常以.a结尾),两者的差别仅在程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。默认情况下,GCC在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话可以在编译时加上-static选项,强制使用静态链接库。例如,如果在/home/xiaowp/lib/目录下有链接时所需要的库文件libfoo.so和libfoo.a,为了让GCC在链接时只用到静态链接库,可以使用下面的命令:

# gcc foo.c -L /home/xiaowp/lib -static -lfoo -o foo
 
*******************************************************************************************
GCC精彩之旅(二) 
作者:肖文鹏 发文时间:2004.03.22
 

代码优化

代码优化指的是编译器通过分析源代码,找出其中尚未达到最优的部分,然后对其重新进行组合,目的是改善程序的执行性能。GCC提供的代码优化功能非常强大,它通过编译选项-On来控制优化代码的生成,其中n是一个代表优化级别的整数。对于不同版本的GCC来讲,n的取值范围及其对应的优化效果可能并不完全相同,比较典型的范围是从0变化到2或3。

编译时使用选项-O可以告诉GCC同时减小代码的长度和执行时间,其效果等价于-O1。在这一级别上能够进行的优化类型虽然取决于目标处理器,但一般都会包括线程跳转(Thread Jump)和延迟退栈(Deferred Stack Pops)两种优化。选项-O2告诉GCC除了完成所有-O1级别的优化之外,同时还要进行一些额外的调整工作,如处理器指令调度等。选项-O3则除了完成所有-O2级别的优化之外,还包括循环展开和其它一些与处理器特性相关的优化工作。通常来说,数字越大优化的等级越高,同时也就意味着程序的运行速度越快。许多Linux程序员都喜欢使用-O2选项,因为它在优化长度、编译时间和代码大小之间,取得了一个比较理想的平衡点。

下面通过具体实例来感受一下GCC的代码优化功能,所用程序如清单3所示。

清单3:optimize.c

#include
int main(void)
{
  double counter;
  double result;
  double temp;
  for (counter = 0;
   counter < 2000.0 * 2000.0 * 2000.0  / 20.0 + 2020;
   counter += (5 - 1) / 4) {
    temp = counter / 1979;
    result  = counter;   
  }
  printf("Result is %lf\n", result);
  return 0;
}
 


首先不加任何优化选项进行编译:

# gcc -Wall optimize.c -o optimize
 


借助Linux提供的time命令,可以大致统计出该程序在运行时所需要的时间:

# time ./optimize
Result is 400002019.000000
real    0m14.942s
user    0m14.940s
sys     0m0.000s
 


接下去使用优化选项来对代码进行优化处理:

# gcc -Wall -O optimize.c -o optimize
 


在同样的条件下再次测试一下运行时间:

# time ./optimize
Result is 400002019.000000
real    0m3.256s
user    0m3.240s
sys     0m0.000s
 


对比两次执行的输出结果不难看出,程序的性能的确得到了很大幅度的改善,由原来的14秒缩短到了3秒。这个例子是专门针对GCC的优化功能而设计的,因此优化前后程序的执行速度发生了很大的改变。尽管GCC的代码优化功能非常强大,但作为一名优秀的Linux程序员,首先还是要力求能够手工编写出高质量的代码。如果编写的代码简短,并且逻辑性强,编译器就不会做更多的工作,甚至根本用不着优化。

优化虽然能够给程序带来更好的执行性能,但在如下一些场合中应该避免优化代码:

◆ 程序开发的时候 优化等级越高,消耗在编译上的时间就越长,因此在开发的时候最好不要使用优化选项,只有到软件发行或开发结束的时候,才考虑对最终生成的代码进行优化。

◆ 资源受限的时候 一些优化选项会增加可执行代码的体积,如果程序在运行时能够申请到的内存资源非常紧张(如一些实时嵌入式设备),那就不要对代码进行优化,因为由这带来的负面影响可能会产生非常严重的后果。

◆ 跟踪调试的时候 在对代码进行优化的时候,某些代码可能会被删除或改写,或者为了取得更佳的性能而进行重组,从而使跟踪和调试变得异常困难。

调试

一个功能强大的调试器不仅为程序员提供了跟踪程序执行的手段,而且还可以帮助程序员找到解决问题的方法。对于Linux程序员来讲,GDB(GNU Debugger)通过与GCC的配合使用,为基于Linux的软件开发提供了一个完善的调试环境。

默认情况下,GCC在编译时不会将调试符号插入到生成的二进制代码中,因为这样会增加可执行文件的大小。如果需要在编译时生成调试符号信息,可以使用GCC的-g或者-ggdb选项。GCC在产生调试符号时,同样采用了分级的思路,开发人员可以通过在-g选项后附加数字1、2或3来指定在代码中加入调试信息的多少。默认的级别是2(-g2),此时产生的调试信息包括扩展的符号表、行号、局部或外部变量信息。级别3(-g3)包含级别2中的所有调试信息,以及源代码中定义的宏。级别1(-g1)不包含局部变量和与行号有关的调试信息,因此只能够用于回溯跟踪和堆栈转储之用。回溯跟踪指的是监视程序在运行过程中的函数调用历史,堆栈转储则是一种以原始的十六进制格式保存程序执行环境的方法,两者都是经常用到的调试手段。

GCC产生的调试符号具有普遍的适应性,可以被许多调试器加以利用,但如果使用的是GDB,那么还可以通过-ggdb选项在生成的二进制代码中包含GDB专用的调试信息。这种做法的优点是可以方便GDB的调试工作,但缺点是可能导致其它调试器(如DBX)无法进行正常的调试。选项-ggdb能够接受的调试级别和-g是完全一样的,它们对输出的调试符号有着相同的影响。

需要注意的是,使用任何一个调试选项都会使最终生成的二进制文件的大小急剧增加,同时增加程序在执行时的开销,因此调试选项通常仅在软件的开发和调试阶段使用。调试选项对生成代码大小的影响从下面的对比过程中可以看出来:

# gcc optimize.c -o optimize
# ls optimize -l
-rwxrwxr-x  1 xiaowp   xiaowp  11649 Nov 20 08:53 optimize  (未加调试选项)
# gcc -g optimize.c -o optimize
# ls optimize -l
-rwxrwxr-x  1 xiaowp   xiaowp  15889 Nov 20 08:54 optimize  (加入调试选项)
 


虽然调试选项会增加文件的大小,但事实上Linux中的许多软件在测试版本甚至最终发行版本中仍然使用了调试选项来进行编译,这样做的目的是鼓励用户在发现问题时自己动手解决,是Linux的一个显著特色。

下面还是通过一个具体的实例说明如何利用调试符号来分析错误,所用程序见清单4所示。

清单4:crash.c

#include
int main(void)
{
  int input =0;
  printf("Input an integer:");
  scanf("%d", input);
  printf("The integer you input is %d\n", input);
  return 0;
}
 


编译并运行上述代码,会产生一个严重的段错误(Segmentation fault)如下:

# gcc -g crash.c -o crash
# ./crash
Input an integer:10
Segmentation fault
 


为了更快速地发现错误所在,可以使用GDB进行跟踪调试,方法如下:

# gdb crash
GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)
……
(gdb)
 


当GDB提示符出现的时候,表明GDB已经做好准备进行调试了,现在可以通过run命令让程序开始在GDB的监控下运行:

(gdb) run
Starting program: /home/xiaowp/thesis/gcc/code/crash
Input an integer:10

Program received signal SIGSEGV, Segmentation fault.
0x4008576b in _IO_vfscanf_internal () from /lib/libc.so.6
 


仔细分析一下GDB给出的输出结果不难看出,程序是由于段错误而导致异常中止的,说明内存操作出了问题,具体发生问题的地方是在调用_IO_vfscanf_internal ( )的时候。为了得到更加有价值的信息,可以使用GDB提供的回溯跟踪命令backtrace,执行结果如下:

(gdb) backtrace
#0  0x4008576b in _IO_vfscanf_internal () from /lib/libc.so.6
#1  0xbffff0c0 in ?? ()
#2  0x4008e0ba in scanf () from /lib/libc.so.6
#3  0x08048393 in main () at crash.c:11
#4  0x40042917 in __libc_start_main () from /lib/libc.so.6
 


跳过输出结果中的前面三行,从输出结果的第四行中不难看出,GDB已经将错误定位到crash.c中的第11行了。现在仔细检查一下:

(gdb) frame 3
#3  0x08048393 in main () at crash.c:11
11       scanf("%d", input);
 


使用GDB提供的frame命令可以定位到发生错误的代码段,该命令后面跟着的数值可以在backtrace命令输出结果中的行首找到。现在已经发现错误所在了,应该将

scanf("%d", input);
改为
scanf("%d", &input);
 


完成后就可以退出GDB了,命令如下:

(gdb) quit
 


GDB的功能远远不止如此,它还可以单步跟踪程序、检查内存变量和设置断点等。

调试时可能会需要用到编译器产生的中间结果,这时可以使用-save-temps选项,让GCC将预处理代码、汇编代码和目标代码都作为文件保存起来。如果想检查生成的代码是否能够通过手工调整的办法来提高执行性能,在编译过程中生成的中间文件将会很有帮助,具体情况如下:

# gcc -save-temps foo.c -o foo
# ls foo*
foo  foo.c  foo.i  foo.s
 


GCC支持的其它调试选项还包括-p和-pg,它们会将剖析(Profiling)信息加入到最终生成的二进制代码中。剖析信息对于找出程序的性能瓶颈很有帮助,是协助Linux程序员开发出高性能程序的有力工具。在编译时加入-p选项会在生成的代码中加入通用剖析工具(Prof)能够识别的统计信息,而-pg选项则生成只有GNU剖析工具(Gprof)才能识别的统计信息。

最后提醒一点,虽然GCC允许在优化的同时加入调试符号信息,但优化后的代码对于调试本身而言将是一个很大的挑战。代码在经过优化之后,在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。建议在调试的时候最好不使用任何优化选项,只有当程序在最终发行的时候才考虑对其进行优化。
 
************************************************************************************************
GCC精彩之旅(三) 
作者:肖文鹏 发文时间:2004.04.14
 

上次的培训园地中介绍了GCC的编译过程、警告提示功能、库依赖、代码优化和程序调试六个方面的内容。这期是最后的一部分内容。

加速

在将源代码变成可执行文件的过程中,需要经过许多中间步骤,包含预处理、编译、汇编和连接。这些过程实际上是由不同的程序负责完成的。大多数情况下GCC可以为Linux程序员完成所有的后台工作,自动调用相应程序进行处理。

这样做有一个很明显的缺点,就是GCC在处理每一个源文件时,最终都需要生成好几个临时文件才能完成相应的工作,从而无形中导致处理速度变慢。例如,GCC在处理一个源文件时,可能需要一个临时文件来保存预处理的输出、一个临时文件来保存编译器的输出、一个临时文件来保存汇编器的输出,而读写这些临时文件显然需要耗费一定的时间。当软件项目变得非常庞大的时候,花费在这上面的代价可能会变得很沉重。

解决的办法是,使用Linux提供的一种更加高效的通信方式—管道。它可以用来同时连接两个程序,其中一个程序的输出将被直接作为另一个程序的输入,这样就可以避免使用临时文件,但编译时却需要消耗更多的内存。

在编译过程中使用管道是由GCC的-pipe选项决定的。下面的这条命令就是借助GCC的管道功能来提高编译速度的:

# gcc -pipe foo.c -o foo
 


在编译小型工程时使用管道,编译时间上的差异可能还不是很明显,但在源代码非常多的大型工程中,差异将变得非常明显。

文件扩展名

在使用GCC的过程中,用户对一些常用的扩展名一定要熟悉,并知道其含义。为了方便大家学习使用GCC,在此将这些扩展名罗列如下:

.c C原始程序;

.C C++原始程序;

.cc C++原始程序;

.cxx C++原始程序;

.m Objective-C原始程序;

.i 已经过预处理的C原始程序;

.ii 已经过预处理之C++原始程序;

.s 组合语言原始程序;

.S 组合语言原始程序;

.h 预处理文件(标头文件);

.o 目标文件;

.a 存档文件。

GCC常用选项

GCC作为Linux下C/C++重要的编译环境,功能强大,编译选项繁多。为了方便大家日后编译方便,在此将常用的选项及说明罗列出来如下:

-c 通知GCC取消链接步骤,即编译源码并在最后生成目标文件;

-Dmacro 定义指定的宏,使它能够通过源码中的#ifdef进行检验;

-E 不经过编译预处理程序的输出而输送至标准输出;

-g3 获得有关调试程序的详细信息,它不能与-o选项联合使用;

-Idirectory 在包含文件搜索路径的起点处添加指定目录;

-llibrary 提示链接程序在创建最终可执行文件时包含指定的库;

-O、-O2、-O3 将优化状态打开,该选项不能与-g选项联合使用;

-S 要求编译程序生成来自源代码的汇编程序输出;

-v 启动所有警报;

-Wall 在发生警报时取消编译操作,即将警报看作是错误;

-Werror 在发生警报时取消编译操作,即把报警当作是错误;

-w 禁止所有的报警。

小结

GCC是在Linux下开发程序时必须掌握的工具之一。本文对GCC做了一个简要的介绍,主要讲述了如何使用GCC编译程序、产生警告信息、调试程序和加快GCC的编译速度。对所有希望早日跨入Linux开发者行列的人来说,GCC就是成为一名优秀的Linux程序员的起跑线。
 

posted @ 16:44 无右 评论 (0)  编辑 收藏


GCC使用手册

GCC使用手册

作者:Clock
 
1.前言

    GCC编译器的手册(GCC MANUAL)的英文版已经非常全面,并且结构也非常完善了,只是一直都没有中文的版本,我这次阅读了GCC编译器的主要内容,对手册的内容进行了结构性的了解,认为有必要对这次阅读的内容进行整理,为以后的工作做准备。

    由于我对这个英文手册的阅读也仅仅是结构性的。因此有很多地方并没有看,所以这篇文档的内容我也只能写出部分,对于以后需要详细了解的地方,会再往这篇文档中增添内容,需要增添的内容主要是编译器的各种开关。

2. GCC功能介绍

    GCC编译器完成从C、C++、objective-C等源文件向运行在特定CPU硬件上的目标代码的转换(这是任何一个编译器需要完成的任务)。

    GCC能够处理的源文件分为C、C++、Objective-C、汇编语言等。对于这些源文件,用他们的后缀名进行标示。GCC能够处理的后缀有:

a. *.c  *.C      (C语言)

b. *.cxx   *.cc  (C++语言)

c. *.m           (面向对象的C)

d. *.i           (预处理后的C语言源文件)

e. *.ii          (预处理后的C++语言源文件)

f. *.s *.S       (汇编语言)

h. *.h         (头文件)

目标文件可以是:

a. *.o     编译连接后的目标文件

b. *.a     库文件

编译器把编译生成目标代码的任务分为以下4步:

a.预处理,把预处理命令扫描处理完毕;

b.编译,把预处理后的结果编译成汇编或者目标模块;

c.汇编,把编译出来的结果汇编成具体CPU上的目标代码模块;

d.连接,把多个目标代码模块连接生成一个大的目标模块;

3.  GCC开关

    GCC的运行开关共分为11类,这是类开关从11个方面控制着GCC程序的运行,以达到特定的编译目的。

3.1.  全局开关(OVERALL OPTIONS)

    全局开关用来控制在“GCC功能介绍”中的GCC的4个步骤的运行,在缺省的情况下,这4个步骤都是要执行的,但是当给定一些全局开关后,这些步骤就会在某一步停止执行,这产生中间结果,例如可能你只是需要中间生成的预处理的结果或者是汇编文件(比如拟的目的是为了看某个CPU上的汇编语言怎么写)。

3.1.1.  –x  language

    对于源文件是用什么语言编写的,可以通过文件名的后缀来标示,也可以用这开关。指定输入文件是什么语言编写的,language 可以是如下的内容

a.  c

b. objective-c

c. c-header

d. c++

e.cpp-output

f.assembler

g.assembler-with-cpp

3.1.2.–x none

把上一节介绍的-x开关都给关掉了。

3.1.3.  –c

编译成把源文件目标代码,不做连接的动作。

3.1.4. –S

把源文件编译成汇编代码,不做汇编和连接的动作。

3.1.5. –E

只把源文件进行预处理之后的结果输出来。不做编译,汇编,连接的动作。

3.1.6.  –o file

指明输出文件名是file。

3.1.7. –v

把整个编译过程的输出信息都给打印出来。

3.1.8.–pipe

由于gcc的工作分为好几步才完成,所以需要在过程中生成临时文件,使用-pipe就是用管道替换临时文件。

3.2.  语言相关开关(Language Options)

用来处理和语言相关的控制开关。

3.2.1.–ansi

    这个开关让GCC编译器把所有的gnu的编译器特性都给关掉,让你的程序可以和ansi标准兼容。

    除了以上的开关外,语言相关开关还有很多,如果在以后的工作学习中遇到了再加不迟!3.3.预处理开关(Preprocessor Options)

用来控制预处理所设置的开关。

3.3.1. –include file

    在编译之前,把file包含进去,相当于在所有编译的源文件最前面加入了一个#include 语句,这样做更“省油”。

3.3.2. –imacros file

    同-include file 一样。不过这个文件在具体编译的时候只有里面定义的宏才起作用,所以值用来在file文件里面定义宏。

3.3.3. –nostdinc

    在搜寻include 的文件路径中去掉标准的c语言头文件搜索路径,例如stdio.h文件就是放在标准头文件搜索路径下。

3.3.4.  –nostdinc++

    同上,只是去掉的是标准C++语言的头文件搜索路径。

3.3.5. –C

    同-E参数配合使用。让预处理后的结果,把注释保留,让人能够比较好读它。

3.3.6. –Dmacro

    把macro定义为字符串’1’。

3.3.7. –Dmacro = defn

    把macro定义为defn。

3.3.8.  –Umacro

    把对macro的定义取消。

    除了以上的开关外,预处理相关开关还有很多,如果在以后的工作学习中遇到了再加不迟!

3.4.   汇编开关(Assembler Option)

    用来控制汇编行为的开关。

3.4.1.  –Wa , option

    把option作为开关送给汇编程序。如果option里面有逗号,则作为好几行进行处理。

3.5.连接开关(Linker Options)

    用来控制连接过程的开关选项。

3.5.1. object-file-name

3.5.2. –llibrary

    连接库文件开关。例如-lugl,则是把程序同libugl.a文件进行连接。

3.5.3. –lobjc

    这个开关用在面向对象的C语言文件的库文件处理中。

3.5.4.  –nostartfiles

    在连接的时候不把系统相关的启动代码连接进来。

3.5.5.   –nostdlib

    在连接的时候不把系统相关的启动文件和系统相关的库连接进来。

3.5.6. –static

    在一些系统上支持动态连接,这个开关则不允许动态连接。

3.5.7. –shared

    生成可共享的被其他程序连接的目标模块。

    连接相关的开关还有一些,以后需要的时候再补。

3.6.目录相关开关(Directory Options)

    用于定义与目录操作相关的开关。

3.6.1. –Idir

    宏include需要搜寻的目录。

3.6.2.–I-

    与-I开关类似。

3.6.3.–Ldir

    搜寻库文件(*.a)的路径。

    和目录相关的开关还有很多,以后需要再加。

3.7. 警告开关(Warning Options)

    与警告处理相关的开关。

3.7.1.–fsyntax-only

    只检查代码中的语法错误,但并没有输出。

3.7.2. –w

    禁止一切警告信息打印出来。

3.7.3. –Wno-import

    禁止对宏#import提出警告。

3.7.4. –pedantic

3.7.5.  –pedantic-errors

3.7.6.  –W

   还有很多与警告处理相关的开关,以后再补。

3.8. 调试开关(Debugging Options)

3.8.1.–g

    把调试开关打开,让编译的目标文件有调试信息。

    还有很多与调试处理相关的开关,以后再补。

3.9. 优化开关(Optimization Options)

    -O1 –O2 –O3 –O0,这些开关分别控制优化的强度,-O3最强。

3.10. 目标机开关(Target Options)

3.10.1. –b machine

    在有的时候,Gcc编译器编译出来的目标代码并不是在运行这个编译动作的机器上运行而是另外一台机器,这种编译叫做交叉编译,用来运行最终目标代码的得机器叫做目标机,machine就是用来指明目标机的类型的。

3.10.2.  –V version

    用来告诉编译器使用它的多少版本的功能,version参数用来表示版本。

3.11.   CPU相关开关(Machine Dependent Options)

    比较多,也是在交叉编译的时候用得着。以后再说。

3.12. 生成代码开关(Code Generation Options)
 
********************************************************************************************

GCC 使用指南
使用语法:

  gcc [ option filename ]...
  g++ [ option filename ]...

  其中 option 为 gcc 使用时的选项(后面会再详述),
  而 filename 为欲以 gcc 处理的文件

说明:

  这 C 与 C++ 的 compiler 已将产生新程序的相关程序整合起来。产
生一个新的程序需要经过四个阶段:预处理、编译、汇编、连结,而这两
个编译器都能将输入的文件做不同阶段的处理。虽然原始程序的扩展名可
用来分辨编写原始程序码所用的语言,但不同的compiler,其预设的处理
程序却各不相同:

  gcc  预设经由预处理过(扩展名为.i)的文件为 C 语言,并於程式
      连结阶段以 C 的连结方式处理。

  g++  预设经由预处理过(扩展名为.i)的文件为 C++ 语言,并於程
序连结阶段以 C++ 的连结方式处理。

  原始程序码的扩展名指出所用编写程序所用的语言,以及相对应的处
理方法:

  .c  C 原始程序          ;   预处理、编译、汇编
  .C  C++ 原始程序        ;   预处理、编译、汇编
  .cc   C++ 原始程序        ;   预处理、编译、汇编
  .cxx  C++ 原始程序        ;   预处理、编译、汇编
  .m  Objective-C 原始程序    ;   预处理、编译、汇编
  .i  已经过预处理之 C 原始程序  ;   编译、汇编
  .ii   已经过预处理之 C++ 原始程序 ;   编译、汇编
  .s  组合语言原始程序      ;   汇编
  .S  组合语言原始程序      ;   预处理、汇编
  .h  预处理文件(标头文件)    ;   (不常出现在指令行)

  其他扩展名的文件是由连结程序来处理,通常有:

  .o  Object file
  .a  Archive file

  除非编译过程出现错误,否则 "连结" 一定是产生一个新程序的最
  後阶段。然而你也可以以 -c、-s 或 -E 等选项,将整个过程自四
  个阶段中的其中一个停止。在连结阶段,所有与原始码相对应的
  .o 文件、程序库、和其他无法自文件名辨明属性的文件(包括不以 .o
  为扩展名的 object file 以及扩展名为 .a 的 archive file)都会
  交由连结程序来处理(在指令行将那些文件当作连结程序的参数传给
  连结程序)。

选项:

  不同的选项必须分开来下:例如 `-dr' 这个选项就与 `-d -r' 大
  不相同。

  绝大部份的 `-f' 及 `-W' 选项都有正反两种形式:-fname 及
  -fno-name (或 -Wname 及 -Wno-name)。以下只列出非预设的那个
  形式。

  以下是所有选项的摘要。以形式来分类。选项的意义将另辟小节说
  明。

  一般性(概略、常用的)选项
        -c -S -E -o file -pipe -v -x language

  程序语言选项
        -ansi -fall-virtual -fcond-mismatch
        -fdollars-in-identifiers -fenum-int-equiv
        -fexternal-templates -fno-asm -fno-builtin
        -fno-strict-prototype -fsigned-bitfields
        -fsigned-char -fthis-is-variable
        -funsigned-bitfields -funsigned-char
        -fwritable-strings -traditional -traditional-cpp
        -trigraphs

  编译时的警告选项
        -fsyntax-only -pedantic -pedantic-errors -w -W
        -Wall -Waggregate-return -Wcast-align -Wcast-qual
        -Wchar-subscript -Wcomment -Wconversion
        -Wenum-clash -Werror -Wformat -Wid-clash-len
        -Wimplicit -Winline -Wmissing-prototypes
        -Wmissing-declarations -Wnested-externs -Wno-import
        -Wparentheses -Wpointer-arith -Wredundant-decls
        -Wreturn-type -Wshadow -Wstrict-prototypes -Wswitch
        -Wtemplate-debugging -Wtraditional -Wtrigraphs
        -Wuninitialized -Wunused -Wwrite-strings

  除错选项
        -a -dletters -fpretend-float -g -glevel -gcoff
        -gxcoff -gxcoff+ -gdwarf -gdwarf+ -gstabs -gstabs+
        -ggdb -p -pg -save-temps -print-file-name=library
        -print-libgcc-file-name -print-prog-name=program

  最佳化选项
        -fcaller-saves -fcse-follow-jumps -fcse-skip-blocks
        -fdelayed-branch -felide-constructors
        -fexpensive-optimizations -ffast-math -ffloat-store
        -fforce-addr -fforce-mem -finline-functions
        -fkeep-inline-functions -fmemoize-lookups
        -fno-default-inline -fno-defer-pop
        -fno-function-cse -fno-inline -fno-peephole
        -fomit-frame-pointer -frerun-cse-after-loop
        -fschedule-insns -fschedule-insns2
        -fstrength-reduce -fthread-jumps -funroll-all-loops
        -funroll-loops -O -O2

  预处理选项
        -Aassertion -C -dD -dM -dN -Dmacro[=defn] -E -H
        -idirafter dir -include file -imacros file -iprefix
        file -iwithprefix dir -M -MD -MM -MMD -nostdinc -P
        -Umacro -undef

  汇编程序选项
        -Wa,option

  连结程序选项
        -llibrary -nostartfiles -nostdlib -static -shared
        -symbolic -Xlinker option -Wl,option -u symbol

  目录选项
        -Bprefix -Idir -I- -Ldir

  Target Options
        -b  machine -V version

  与机器(平台)相关的选项
        M680x0 Options
        -m68000 -m68020 -m68020-40 -m68030 -m68040 -m68881
        -mbitfield -mc68000 -mc68020 -mfpa -mnobitfield
        -mrtd -mshort -msoft-float

        VAX Options
        -mg -mgnu -munix

        SPARC Options
        -mepilogue -mfpu -mhard-float -mno-fpu
        -mno-epilogue -msoft-float -msparclite -mv8
        -msupersparc -mcypress

        Convex Options
        -margcount -mc1 -mc2 -mnoargcount

        AMD29K Options
        -m29000 -m29050 -mbw -mdw -mkernel-registers
        -mlarge -mnbw -mnodw -msmall -mstack-check
        -muser-registers

        M88K Options
        -m88000 -m88100 -m88110 -mbig-pic
        -mcheck-zero-division -mhandle-large-shift
        -midentify-revision -mno-check-zero-division
        -mno-ocs-debug-info -mno-ocs-frame-position
        -mno-optimize-arg-area -mno-serialize-volatile
        -mno-underscores -mocs-debug-info
        -mocs-frame-position -moptimize-arg-area
        -mserialize-volatile -mshort-data-num -msvr3 -msvr4
        -mtrap-large-shift -muse-div-instruction
        -mversion-03.00 -mwarn-passed-structs

        RS6000 Options
        -mfp-in-toc -mno-fop-in-toc

        RT Options
        -mcall-lib-mul -mfp-arg-in-fpregs -mfp-arg-in-gregs
        -mfull-fp-blocks -mhc-struct-return -min-line-mul
        -mminimum-fp-blocks -mnohc-struct-return

        MIPS Options
        -mcpu=cpu type -mips2 -mips3 -mint64 -mlong64
        -mlonglong128 -mmips-as -mgas -mrnames -mno-rnames
        -mgpopt -mno-gpopt -mstats -mno-stats -mmemcpy
        -mno-memcpy -mno-mips-tfile -mmips-tfile
        -msoft-float -mhard-float -mabicalls -mno-abicalls
        -mhalf-pic -mno-half-pic -G num -nocpp

        i386 Options
        -m486 -mno-486 -msoft-float -mno-fp-ret-in-387

        HPPA Options
        -mpa-risc-1-0 -mpa-risc-1-1 -mkernel -mshared-libs
        -mno-shared-libs -mlong-calls -mdisable-fpregs
        -mdisable-indexing -mtrailing-colon

        i960 Options
        -mcpu-type -mnumerics -msoft-float
        -mleaf-procedures -mno-leaf-procedures -mtail-call
        -mno-tail-call -mcomplex-addr -mno-complex-addr
        -mcode-align -mno-code-align -mic-compat
        -mic2.0-compat -mic3.0-compat -masm-compat
        -mintel-asm -mstrict-align -mno-strict-align
        -mold-align -mno-old-align

        DEC Alpha Options
        -mfp-regs -mno-fp-regs -mno-soft-float -msoft-float

        System V Options
        -G -Qy -Qn -YP,paths -Ym,dir

  Code Generation Options
        -fcall-saved-reg -fcall-used-reg -ffixed-reg
        -finhibit-size-directive -fnonnull-objects
        -fno-common -fno-ident -fno-gnu-linker
        -fpcc-struct-return -fpic -fPIC
        -freg-struct-returno -fshared-data -fshort-enums
        -fshort-double -fvolatile -fvolatile-global
        -fverbose-asm

PRAGMAS
  Two  `#pragma'  directives  are  supported for GNU C++, to
  permit using the same header file for two purposes:  as  a
  definition  of  interfaces to a given object class, and as
  the full definition of the contents of that object  class.

  #pragma interface
        (C++  only.)   Use  this  directive in header files
        that define object classes, to save space  in  most
        of  the  object files that use those classes.  Nor-
        mally, local copies of certain information  (backup
        copies of inline member functions, debugging infor-
        mation, and the internal tables that implement vir-
        tual  functions)  must  be kept in each object file
        that includes class definitions.  You can use  this
        pragma  to  avoid  such duplication.  When a header
        file containing `#pragma interface' is included  in
        a  compilation, this auxiliary information will not
        be generated (unless the main input source file it-
        self  uses `#pragma implementation').  Instead, the
        object files will contain references to be resolved
        at link time.

  #pragma implementation

  #pragma implementation "objects.h"
        (C++  only.)  Use this pragma in a main input file,
        when you want  full  output  from  included  header
        files  to be generated (and made globally visible).
        The included  header  file,  in  turn,  should  use
        `#pragma  interface'.  Backup copies of inline mem-
        ber functions, debugging information, and  the  in-
        ternal  tables  used to implement virtual functions
        are all generated in implementation files.

        If you use `#pragma implementation' with  no  argu-
        ment,  it  applies to an include file with the same
        basename as  your  source  file;  for  example,  in
        `allclass.cc',  `#pragma  implementation' by itself
        is   equivalent  to  `#pragma  implementation
        "allclass.h"'.  Use the string argument if you want
        a single implementation file to include  code  from
        multiple header files.

        There  is no way to split up the contents of a sin-
        gle header file into multiple implementation files.

文件说明
  file.c       C source file
  file.h       C header (preprocessor) file
  file.i       经预处理过的 C source file
  file.C       C++ source file
  file.cc      C++ source file
  file.cxx    C++ source file
  file.m       Objective-C source file
  file.s       assembly language file
  file.o       object file
  a.out        link edited output
  TMPDIR/cc*     temporary files
  LIBDIR/cpp     preprocessor
  LIBDIR/cc1     compiler for C
  LIBDIR/cc1plus   compiler for C++
  LIBDIR/collect   linker front end needed on some machines
  LIBDIR/libgcc.a  GCC subroutine library
  /lib/crt[01n].o  start-up routine
  LIBDIR/ccrt0  additional start-up routine for C++
  /lib/libc.a    standard C library, 参阅 man page intro(3)
  /usr/include  standard directory for #include files
  LIBDIR/include   standard gcc directory for #include files
  LIBDIR/g++-include additional g++ directory for #include

  LIBDIR is usually /usr/local/lib/machine/version.
  TMPDIR comes from the environment variable TMPDIR (default
  /usr/tmp if available, else /tmp).

posted @ 16:40 无右 评论 (0)  编辑 收藏

Emacs 快速指南

您正在阅读 Emacs 快速指南( Emacs tutorial )。请见页尾有关复制条件。
Copyright (c) 1985, 1996, 1998, 2001, 2002 Free Software Foundation.

Emacs 命令通常包含有 CONTROL 键(有时候以 CTRL 或 CTL 来标示)或是
META 键(有时候以 EDIT 或 ALT 来标示)。为了避免每一次都要写出其全名,
我们将会使用下述的缩写:

C- 表示当键入字符 时 按住 CONTROL 键。
因此,C-f 就是:按住 CONTROL 键再键入 f 。
M- 表示当键入字符 时 按住 META 或 EDIT 或 ALT 键。
如果没有 META 、 EDIT 或 ALT 键时,则可以用
“按一下 ESC 键然后放开,再键入 的步骤”
来作为替代。我们以 来表示 ESC 键。

重要备忘录:要退出 Emacs 会话( session ),键入 C-x C-c (两个字
符)。位在左侧边界的“>>”字符是让您可以试著使用的命令的提示。举例来说:
<>
[Middle of page left blank for didactic purposes. Text continues below]
>> 现在键入 C-v ( View next screen )以移到下个屏幕。
(试试看,键入字符 v 时,按住 CONTROL 键)
从现在开始,您应该在每次阅读完目前的屏幕时做一次这个动作。

要注意的是,当您从一个屏幕移到另一个时,中间会有两行重复;这样做是为了
提供一些连续性,让您可以接续地阅读文字。

您需要知道的第一件事是如何在文字中移动。您已经知道了可以 C-v 来向前移
动一个屏幕。要向后移动一个屏幕,则键入 M-v (按住 META 键,然后键入 v
,或是如果您没有 META 、 EDIT 或 ALT 键时键入 v )。

>> 试著键入 M-v 然后 C-v ,连续个几次。

【现在您可以 C-v 命令移到后面“翻译”一节,以取得关于本文的翻译相关事
项;然后以 M-v 命令回到这里。】


* 摘要( SUMMARY )
-------------------

以下的命令在浏览屏幕时相当有用:【我们现在以“屏幕”来表示“显示文件内
容的区域”,因为目前是处在 Emacs 中的单窗格( window )显示状态,如果
是在多窗格的状态下,这里所介绍的命令则作用在“工作中的窗格”。有关于窗
格的介绍,请见窗格( windows )一节。】

C-v 向前移动一个屏幕/窗格
M-v 向后移动一个屏幕/窗格
C-l 清除屏幕/窗格,再重新显示所有文字,
光标所在位置会显示于屏幕/窗格的中央。
(是 CONTROL-L 而不是 CONTROL-1 )

>> 找出光标的位置,并注意其附近的文字为何。然后键入 C-l 。
再次找出光标的位置,确认一下相同的文字现在也位在其附近。

如果您的终端机有 PageUp 与 PageDn 键的话,您也可以使用它们来以屏幕为单
位地移动,但是使用 C-v 和 M-v 会比较有效率。


* 基本的光标控制( BASIC CURSOR CONTROL )
------------------------------------------

屏幕到屏幕的移动是很有用,但是您如何移动到位于屏幕内文字中的特定位置呢?

有几种方式可以进行。您可以使用方向键,但是将您的手放在标准的〔键盘〕位
置,并且使用命令 C-p 、 C-b 、 C-f 和 C-n 将比较有效率。这些字符和四个
方向键〔的功能〕是同等的,如下所示:

前一行 C-p
:
:
向后移 C-b .... 目前光标位置 .... 向前移 C-f
:
:
后一行 C-n

>> 以 C-n 或 C-p 将光标移到图形的中央。
键入 C-l 会看到整个图形显示在屏幕的中央。

您会发现用字母所代表的意义来记忆它们很容易:P 表示 previous 、 N 表示
next 、 B 表示 backward 、而 F 则表示 forward 。您将“总是”用到这些游
标移动命令。

>> 按几次 C-n 把光标往下移动到这行。

>> 按几次 C-f 往前移到这行,然后再以 C-p 往后移动。
看看当光标在本行中央时,C-p 的动作是怎样。

每一个文字行都以一个 Newline 字符作为结束,它用来与下一行相互分开。
在您文件中的最后一行应该要有一个 Newline 来作为结束(但是 Emacs 并不一
定需要它来编辑文件)。

>> 试著在一行开始的地方键入 C-b 。结果应该会移动到前一行的最后面。
这是因为它往后移动时越过了 Newline 字符。

C-f 也可以和 C-b 一样地越过 Newline 字符。【Newline 字符是“不可见
( invisible )字符”,在编辑器中一般看不到它,这里只是告诉您:在行首
再往前走,那么光标会跑到前一行(如果有前一行的话);在行尾再往后走,那
么光标会跑到后一行(如果有后一行的话)。“越过 Newline 字符”会让光标
跑到另外一行。】

>> 多按几次 C-b,自己感觉一下光标在哪。
然后按几次 C-f 回到这行的尾巴。
再按一次 C-f 就可以移到下一行了。

当您移动光标穿越屏幕的上方或下方时,在边界外的文字会移位进入屏幕内。这
称为“卷动”。它让 Emacs 可以将光标移动到文字中的任意特定位置,同时
(光标)不会跑出屏幕外。

>> 试著以 C-n 将光标越过屏幕下方,然后看看发生了什么事。

如果一个字符一个字符地移动太慢的话,您可以一个字一个字地移动。M-f
(META-f) 往前移动一个字,M-b 则往后移动一个字。【对中文来说,则是移动
到下一个或下一个标点符号的所在。】

>> 键入一些 M-f 和 M-b。

当您在一个字的中间时,M-f 会移动到这个字的尾巴。当您在字与字间的空白时,
M-f 会移动到下一个字的尾巴。M-b 的效果相似,只是方向不同。

>> 按几次 M-f 和 M-b,中间夹杂一些 C-f 和 C-b,
这样子您就可以观察 M-f 和 M-b 在各种“位在字间或字符间”
的不同位置,所表现出来的行为。

请注意 C-f 、 C-b 和 M-f 、 M-b 两对之间的相似性。“经常”的状况是:
META 字符是用来作为与“以语言定义出的单位(字、句子、段落)”有关的操
作,而 CONTROL 字符则是作用在“与您所编辑无关的『基本』单位(字符或行
等)”上。

这个相似性在“行与句子”之间也同样适用:C-a 和 C-e 会将光标移动到“一
行”的 开始和结尾处,而M-a 和 M-e 则将光标移动到“一句”的 开始和结尾
处。

>> 试著按两次 C-a,再按两次 C-e。
试著按两次 M-a,再按两次 M-e。

看一下为什么重复的 C-a 命令会没有作用,而重复的 M-a 命令则继续移动到下
一个句子。虽然这并不能说是完全类比,但是其中每个命令的行为看起来都十分
自然。

光标在文字中的位置也可以称作“点位( point )”。简单来说就是:光标表
现出屏幕中“点位”所在的文字位置。

这里是一些简单“光标移动( cursor-moving )操作”的整理,其中也包括了
“字和句”的移动命令:

C-f 往前移动一个字符
C-b 往回移动一个字符

M-f 往前移动一个字【中文是移动到下一个标点符号】
M-b 往回移动一个字【中文是移动到上一个标点符号】

C-n 移动到下一行
C-p 移动到上一行

C-a 移动到行首
C-e 移动到行尾

M-a 移回句首
M-e 移到句尾

>> 练习几次这些命令。这些都是最常使用到的命令。

还有两个重要的光标动作( cursor-motion )命令,M-<( META Less-than ),
移动到文字的最开始,以及M->( META Greater-than ),移动到文字的最后。

在大部份的终端机,“<”是在 comma 上方,所以您必须要使用 shift 键来键
入。在这些终端机上,您必须使用 shift 键来键入 M-<;没有使用 shift 键,
您就变成键入 M-comma 了。

>> 现在试一下 M-< ,移到本快速指南的最开始。
然后再重复地使用 C-v 回到这里。

>> 现在试一下 M-> ,移到本快速指南的最后。
然后再重复地使用 M-v 回到这里。

如果您的终端机有方向键的话,您也可以用方向键移动光标。我们有三个理由建
议您学习 C-b 、 C-f 、 C-n 、 和 C-p :(1) 任何的终端机都能使用。(2)
一旦您使用 Emacs 相当熟练了,您会发现键入这些 CONTROL 字符,比起使用方
向键坑卩了(因为您不需要将手移开打字区)。(3) 一旦您使用这些 CONTROL
字符命令成为习惯,您也可以很容易地学会其他高级的光标动作命令。

大部份的 Emacs 命令接受数字参数;对大部份的命令而言,它的作用是指定重
复次数。您要指定一个命令的重复次数的作法是:先键入 C-u,然后在您键入指
令前,键入代表重复次数的数位。如果您有一个 META(或 EDIT 或 ALT )键,
那么您还有另外一个替代作法来输入数字参数:按住 META 键时打入这数字。我
们建议您学习 C-u 的方法,因为它在任何终端机都可以使用。此一数字参数也
称作为“字首参数”,因为您在这参数所作用到的命令前键入它。

举例来说, C-u 8 C-f 向前移动 8 个字符。

>> 试著以一个数字参数来使用 C-n 或 C-p,
只一个命令就将光标移动到这行的附近。

大部份的命令使用数字参数来作为其重复次数,但是其中有些命令则是作为其他
用途。有几个命令(目前您尚未学到)将它作为旗标 -- 以一个字首参数的型态
出现,而不管其值为何,它们让这命令做些不一样的事。

C-v 和 M-v 则是另一类的例外。当给定一个参数时,它们卷动“所指定的数量
的行(以行为单位)”,而不是以“屏幕”为单位卷动。举例来说,C-u 8 C-v
将显示屏幕卷动 8 行。

>> 现在试著键入 C-u 8 C-v。

这命令应该已经将屏幕向上移了 8 行。若您想将它再次地向下卷动,您可以在
执行 M-v 时给定一个参数。

如果您正在使用 X 窗口系统,在 Emacs 窗口左手侧应该有一个称为“卷动轴”
的长方型区域。您可以用鼠标在卷动轴按一下来卷动文字。

>> 试著在“卷动轴内反白区域上”压一下中间钮。这应该会将文字卷动到
“由您所按一下滑鼠的地方”所决定的位置。

>> 当按住中间时,试著将滑鼠上下移动。
您会看到文字随著您移动滑鼠而上下移动。


* 当 EMACS 发呆时( WHEN EMACS IS HUNG )
-----------------------------------------

如果 Emacs 停止回应您的命令,您可以键入 C-g 来安全地停止它。您也可以使
用 C-g 来停止执行过久的命令。

您也可以使用 C-g 来取消数字参数或您不想要完成的命令。

>> 键入 C-u 100 以设定一个 100 的数字参数,然后键入 C-g。
现在键入 C-f。它应该只会移动一个字符,因为您已经以 C-g
取消了参数。

如果您已经不小心地键入一个 ,您可以 C-g 来取消它。


* 无效化的命令( DISABLED COMMANDS )
-------------------------------------

有一些 Emacs 命令被“无效化”了,因此初学者不会意外地使用到它们。

如果您键入了某一个无效化的命令,Emacs 会显示一个消息,说明这个命令是什
么,并且询问您是否想要继续,然后执行这命令。

如果您真的想要试一下这个命令,那么在当 Emacs 询问您时,请键入空白。一
般来说,如果您不想要执行这个无效化的命令,请以『n』来回答它。

>> 键入 C-x C-l (这是个无效化的命令)
然后键入 n 来回答问题。


* 窗格( WINDOWS )
-------------------

Emacs 可以有数个窗格,每一个显示它自己的文字。我们在稍后会解释如何使用
多重窗格。现在我们想要解释如何除去多余的窗格,然后回到基本的单窗格编辑。
它很简单:

C-x 1 One window (即,除去其他所有的窗格)。

那是个 CONTROL-x 后面跟著数字 1 。C-x 1 将含有光标的窗格扩大到整个屏幕。
它将所有其他的窗格除去。

>> 移动光标到本行并且键入 C-u 0 C-l。
>> 键入 CONTROL-h k CONTROL-f。
看看这个窗格在当一个新的窗格出现
(以显示有关 CONTROL-f 命令的文文件时),它是如何缩小的。

>> 键入 C-x 1 以使文文件列表窗格消失。

这个命令并不像您先前所学过的命令那般,它包括了两个字符。它是以字符
CONTROL-x 作为开始。有一整个系列的命令是以 CONTROL-x 作为开始;它们之
中有许多是与“窗格、文件、暂存区以及相关事物”有关的。这些命令有 2 、
3 或 4 个字符长。


* 插入与删除( INSERTING AND DELETING )
----------------------------------------

如果您想要插入文字,把它键入就是了。您可以看到的字符,像是 A 、 7 、 *
等,被 Emacs 视为文字并且可以直接插入。键入
( carriage-return 键)以插入一个 Newline 字符。

您可以键入 以删除您最后键入的字符。 是一个的键盘键
-- 就是您通常在 Emacs 外,使用来“删除您最后键入字符”的同一个。一般来
说是个在 上方数行的大键,通常标示为『Delete』、『Del』或
『Backspace』。

如果在那里有个标示为『Backspace』的大键,那么那一个就是您使用来作为
的键了。某个地方可能也会有另一个标示为『Delete』的键,但那个
并不是

更一般地说, 将位于目前光标位置前一个字符加以删除。

>> 现在做 -- 键入一些字符,然后键入几次 来删除它们。
不要担心这个文件会被更动;您不会影响到原来的快速指南。
(您现在看到的)这一个是您的个人拷贝。

当一行文字变得比“在窗格中的一行”长时,这一行文字会“接续”到第二行窗
格行。这时一个反斜线“”(或如果您使用窗口化的显示,则是一个小小弯弯
的箭头)会位在其右边界以指出此行接续著。

>> 插入文字,一直到您达到右边界,然后再继续插入。
您会看到一个接续行出现。

>> 使用 删除一些文字,直到此行再次成为一个窗格行。
接续行消失了。

您可以像删除其他字符一样地删除 Newline 字符。将位在两行中的 Newline 字
元删除会让它们合并成为一行。如果合并的结果使这一行太长,以致无法符合窗
格的宽度,它会以一个接续行来显示。

>> 移动光标到本行的开头并键入
这会将本行与其前一行结合为一行。

>> 键入 以重新插入您刚才删除的 Newline 字符。

记得大部份的 Emacs 命令都可以给予一个重复计数( repeat count );这也
包括了文字字符。重复一个文字字符会将它插入数次。

>> 现在就试一下 -- 键入 C-u 8 * 以插入 ********。

您现在已经学到了“键入个什么东西进 Emacs 以及修正错误”的大部份基本方
法。您也可以“以字或行为单位”地删除。这里有份关于“删除操作”的摘要:

删除光标所在的 前一个字符
C-d 删除光标所在的 后一个字符

M- 删除光标所在的 前一个字
M-d 删除光标所在的 后一个字

C-k 删除从光标所在到“行尾”间的字符
M-k 删除从光标所在到“句尾”间的字符

注意“ 和 C-d”还有“M- 和 M-d”是平行地自 C-f 和
M-f 扩充出来的(嗯, 并不是控制字符,但是没什么好担心的)。
C-k 和 M-k 在某种程度上与 C-e 和 M-e 一样,如果把“一行”和“一句”作
为类比的话。

您也可以只以一种方法来删除缓冲区内的任何部份,先移动到您想要删除的部份
的一端,然后键入 C-@ 或 C-SPC (任一个即可)。( SPC 指的是 Space Bar
)再移到那部份的另一端,接著键入 C-w 。这样就会把介于这两个位置间的所
有文字删除。

>> 移动光标到上一段开头的“您”字。
>> 键入 C-SPC 。 Emacs 应该会在屏幕的下方显示一个“Mark set”消息。
>> 移动光标到第二行中的“端”字。
>> 键入 C-w 。这样会把从“您”开始到刚好“端”之前的文字删除。

要注意的是“杀掉( killing )”和“删除( deleting )”的不同在于被杀
掉的可以拉回,而被删除的则不能。【有点难以理解,您可以这么想:(1)“被
杀掉的”尚存尸骨,而“被删除的”则尸骨无存了!可见得对电脑资料来说,
“删除”比“杀掉”严重多了。(2)实际上,就算被删除了,我们还是有技术可
以把它救回来,尤其是文字资料,前提是删除后不能进行实体内存的格式化动
作。但这对于一般使用者而言是不可能的,因此就不考虑这情形了。】重新插入
被杀掉的文字称为“拉回( yanking )”。一般而言,可以移除掉很多文字的
命令会把那些文字储存起来(它们设定成您可以将文字拉回),而那些只是删除
一个字符或者只是除去空白行或空白的命令,则不会储存这些被删除的文字(因
此您不能将那文字拉回)。

>> 移动光标到一非空白行的开始。
然后键入 C-k 杀掉在那一行上的文字。
>> 第二次键入 C-k。您将会看到它杀掉跟在那一行后面的 Newline 字符。

请注意单独的 C-k 会把一行的内容杀掉,而第二个 C-k 则会杀掉那一行本身,
并且使得所有其他的行向上移动。C-k 以很特别的方式来处理数字参数,它会杀
掉很多行以及它们的内容,这不仅仅是重复而已,C-u 2 C-k 会把两行以及它们
的 Newline 字符杀掉;如果只是键入 C-k 两次并不会这样。

将被杀掉的文字恢复的动作称为“拉回( yanking )”。(把它想像成您把别
人从您身上夺去的东西猛力地拉回来)您可以在您删除文字的地方拉回,也可以
在文字的其他地方拉回。您可以拉回数次同样的文字,以制作它的数份拷贝。

拉回的命令为 C-y。它会在目前光标的位置重新插入最后杀掉的文字。

>> 试试看;键入 C-y 将文字拉回。

如果您连续地做了数次 C-k,所有被杀掉的文字都会被储存在一起,因此做一次
C-y 就会把所有这些行都拉回来。

>> 现在做一下,键入 C-k 数次。

现在要恢复那些杀掉的文字:

>> 键入 C-y。然后把光标往下移动个几行,再一次键入 C-y。
您现在知道如何复制某些文字了。

如果您有一些文字想要拉回来,但是后来您又杀了某些东西,那么该怎么做呢?
C-y 会把最近杀掉的拉回来,但是先前的文字并没有消失,您可以用 M-y 来回
到它。当您已经使用 C-y 把最近杀掉的拉回来之后,再键入 M-y 来把这些拉回
来的文字替换为先前所杀掉的。一次又一次地键入 M-y 会把先前再先前所杀掉
的文字带回来。当您到了您想找的文字时,您不需要做任何事来保存它,只要继
续您的编辑,把这些已拉回的文字留在那里就好。

如果您 M-y 做了很多次,您可能会回到起始点,也就是最近杀掉的。

>> 杀掉一行,到处绕绕,再杀掉另一行。
然后用 C-y 将第二次杀掉的那行带回来。
然后再用 M-y,它将会被第一次杀掉的那行取代。
再做几次 M-y 看看您会得到什么。
不间断地做,直到第二个杀掉行回来,再做个几次。
如果您想的话,您可以试著给 M-y 正的或是负的参数。


* 取消动作( UNDO )
--------------------

如果您对文字做了一些改变,后来觉得它是个错误,您可以 Undo 命令取消这一
个改变,C-x u。

通常 C-x u 会把一个命令所造成的改变取消掉;如果您在一行中重复了许多次
C-x u,每一个重复都会取消额外的命令。

但是有两个例外:
(1) 没有改变文字的命令不算(这包括了光标移动的命令还有卷轴命令);
(2) 自行键入的字符以一群一群 -- 每群最多 20 个 -- 来进行处理。
(这是为了减少您在取消“村入文字动作”所必须键入 C-x u 的次数)

>> 以 C-k 将这一行杀掉,然后键入 C-x u 后它会再次出现。

C-_ 是另一个取消命令;它的作用就和 C-x u 一样,但是在一行中它比较容易
键入许多次。C-_ 的缺点是在某些键盘中不太清楚如何键入它,这也是为什么我
们同时提供 C-x u 的原因。在某些终端机,您可以按住 CONTROL 再键入 / ,
来键入 C-_。

一个数字参数对 C-_ or C-x u 来说,是作为重复的次数。


* 文件( FILE )
----------------

为了使您编辑的文字永久保存,您必须把它放到一个文件中。不然,当您退出
Emacs 后,它就会随之消失。为了把您的文字放在文件中,您必须在您键入这些
文字前“找( find )”文件。(这也称之为“拜访( visiting )”文件)

找一个文件表示您可以在 Emacs 中看到文件的内容。从许多方面来看,它就像
是您直接编辑那个文件一样。然而,直到您“储存”这个文件之前,您使用
Emacs 编辑所做出的改变并不会保存下来。这就是为什么当您不想要时,您可以
避免留下修改到一半的文件在系统中。即使当您储存了,Emacs 也会把原本的文件
案以一个不同的名称保留下来,若您稍后觉得您的改变是一个错误的话,就可以
使用它。

在靠近屏幕的下方,您可以看到由破折号开始与结束的一行 -- 通常是以“--:--
TUTORIAL.cn”或其他类似的东西作为开始。这是屏幕的一部分,通常用来表示
您正在拜访的文件。现在,您正在拜访的文件叫做“TUTORIAL.cn”,它是您个
人的拷贝。当您以 Emacs 找出一个文件时,那个文件的名字就会出现在那个地
方。

关于寻找文件的命令中,有一个很特别的是,您必须说出这个您想要的文件名称。
我们说这个命令“从终端机中读进了一个参数”。(在这个例子中,这参数就是
文件的名称)当您键入这个命令后,

C-x C-f 找一个文件

Emacs 会要您键入文件名。您所键入的文件名会出现在屏幕的底行。在被用来作为这
种形式的输入时,底行被称为小缓冲区( minibuffer )。您可以使用正常的
Emacs 编辑命令来编辑这个文件名。

当您正在键入文件名时(或是任何的小缓冲区输入时),您可以用 C-g 这个命令
来取消它。

>> 键入 C-x C-f,然后键入 C-g。这会取消小缓冲区,
并且也会取消使用这个小缓冲区的 C-x C-f 命令。
因此您没有找任何文件。

当您已经键入了这个文件名,请键入 来结束它。然后 C-x C-f 命令就
会开始运作,并且找到您所选择的文件。小缓冲区在当 C-x C-f 命令结束时就
会消失。

过了一会儿,文件的内容就会出现在屏幕,然后您就可以编辑它的内容。当您想
要您的改变永久保存时,键入这个命令:

C-x C-s 储存这个文件

这会把在 Emacs 中的文字复制到文件中。当您第一次做这个动作时,Emacs 会
将原始的文件重新命名成一个新的名字,这样它才不会消失。新的名字通常会加
入“~”到原始文件的名字后面。

当储存结束时,Emacs 会把写入文件的名字列出来。您应该经常地进行储存,这
样子如果系统挂起时,您就不会损失太多工作。

>> 键入 C-x C-s 以储存本快速指南的您的拷贝。
这会把“Wrote ...TUTORIAL.cn”这个消息显示在屏幕的下方。

注意:在某些系统中,键入 C-x C-s 将会把屏幕冻结,您将看不到从 Emacs 来
的任何输出。这表示操作系统一个称为“流程控制”的“功能”将 C-s 命令拦
截住,并且不让它传到 Emacs。要取消屏幕的冻结,请键入 C-q。然后到 Emacs
使用手册中看看对于“渐进式搜寻的同时进入( Spontaneous Entry to
Incremental Search )”这个主题,以取得处理这个“功能”的建议。

您可以找出一个已经存在的文件,然后观看它或编辑它。您也可以找一个还没有
存在过的文件。这是以 Emacs 建立一个文件的方法:找这个文件,就从零开始,
然后开始插入文字到这个文件中。当您要求“储存”这个文件,Emacs 会真的建
立一个文件,并把您所插入的文字摆到文件中。从那时候开始,您就可以当自己
是在编辑一个已经存在的文件了。


* 缓冲区( BUFFER )
--------------------

如果您以 C-x C-f“找”第二个文件,第一个文件仍然存在 Emacs 内。要切换
回它,您可以 C-x C-f 再找它一次。依此方式,您可以在 Emacs 内打开不少文件
案。

>> 以键入 C-x C-f foo 的方式建立一个名为“foo”的文件。
然后插入一些文字,编辑它,然后再以 C-x C-s 储存“foo”。
最后,键入 C-x C-f TUTORIAL.cn 回到本快速指南。

Emacs 储存每个文件的文字在一个称为“缓冲区( buffer )”的对象中。找一
个文件会在 Emacs 内部建立一个缓冲区。想要看目前存在您的 Emacs 的工作中
缓冲区列表,键入

C-x C-b 列出缓冲区

>> 现在就试一下 C-x C-b

看看每一个缓冲区是如何命名的,它也可能同时拥有一个“储存其内容的文件”
的名称。您在一个 Emacs 窗格所见到的“任何”文字都是某个缓冲区的一部份。

>> 键入 C-x 1 以退出缓冲列表

当您有数个缓冲区时,在任何时候其中只有一个是“目前作用的”。而那个就是
您在编辑的缓冲区。如果您想要编辑另一个缓冲区,那么您必须“切换”到它。
如果您想要切换到连接到某个文件的缓冲区,您可以用 C-x C-f 再次拜访那个
文件。但是有个比较简单的方式:使用 C-x b ;在这个命令中,您必须键入缓
冲区的名称。

>> 键入 C-x b foo 以回到含有文件“foo”的文字的缓冲区。
然后建入 C-x b TUTORIAL 以回到本快速指南。

就大部份的情况来说,缓冲区的名称与文件的名称是相同的(除去了文件名中的目
录部份)。然而并不总是如此。您以 C-x C-b 所制作出的缓冲区列表总是会显
示给您每一个缓冲区的名称。

您在一个 Emacs 窗格中所见到的“任何”文字总是某个缓冲区的一部份。有一
些缓冲区并没有连接到文件。举例来说,命名为“*Buffer List*”的缓冲区并
没有任何文件。它是包含有您以 C-x C-b 命令所制作出来的缓冲区列表的缓冲
区。命名为“*Messages*”的缓冲区也没有连接到任何文件;它在您的 Emacs
操作阶段中包含出现在底行的消息。

>> 键入 C-x b *Messages* 来看看消息的缓冲区。
然后键入 C-x b TUTORIAL 回到本快速指南。

如果您对文件中的文字做了修改,然后找另一文件,这个动作并不会储存第一个
文件。它的修改仍旧存在 Emacs 中,也就是在那个文件的缓冲区中。对于第二
个文件的建立或编辑并不会影响到第一个文件的缓冲区。这样子非常有用,但这
个情形也表明了您需要“一个方便的方法”来储存第一个文件的缓冲区。只是为
储存第一个文件就必须以 C-x C-f 切换缓冲区,才能以 C-x C-s 将它储存,总
是个让人讨厌的过程。因此我们有

C-x s 储存一些缓冲区

C-x s 会询问您关于您已做出修改但还没储存的每一个缓冲区。它会问您,对于
每一个这样的缓冲区,是否要储存?

>> 插入一行文字,然后键入 C-x s。
它应该会问您是否要储存名为 TUTORIAL.cn 的缓冲区。
键入『y』以回答要储存。


* 扩充命令集( EXTENDING THE COMMAND SET )
-------------------------------------------

由于 Emacs 拥有太多命令,即便使用上所有的 CONTROL 和 META 字符,也没办
法完全摆上。Emacs 以 X(扩充『eXtend』)命令来解决这个问题。扩充命令有
两种型式:

C-x 字符扩充。后面跟著一个字符。
M-x 有名称的命令扩充。后面跟著一个长的名称。

还有一些命令通常来说是很有用的,但是比您已经学到的命令较少使用。您已经
看过其中两个:文件命令中的 C-x C-f 去寻找,以及 C-x C-s 去储存。其他的
例子则有结束 Emacs 阶段的命令 -- 这个命令是 C-x C-c。(不要担心您会失
去已经做出的改变,C-x C-c 在它杀掉 Emacs 之前会提供储存每一个变动的文件
案的机会。)

C-z 是 *暂时* 退出 Emacs 的命令 -- 因此您稍后可以回到同样的 Emacs 阶段。

在某些允许它的作用的系统中, C-z 会“暂停住( suspends )”Emacs,也就
是说,它会回到 shell 但不会把 Emacs 毁掉。在最常用的 shell 中,您可以
用『fg』或『%emacs』两种命令恢复 Emacs。

在没有提供暂停功能的系统中,C-z 会在 Emacs 底下建立一个 subshell 以让
您有机会执行其他的程序,并且在稍后回到 Emacs,它并没有真的退出 Emacs。
在这个例子中,shell 命令『exit』是从subshell 回到 Emacs 的通常方式。

使用 C-x C-c 的时机是当您打算要登出时。它也非常适合用来退出被其他邮件
处理程序,以及许多不同的应用程序所启动的 Emacs。然而在一般的状况下,如
果您不打算登出,最好是把 Emacs 暂停而不是退出它。

有许多 C-x 的命令。这里是一份您已经学过的列表:

C-x C-f 找文件。
C-x C-s 储存文件。
C-x C-b 列出缓冲区。
C-x C-c 退出 Emacs。
C-x 1 除了一个外,删去其他所有的窗格。
C-x u 取消动作。

以扩充来命名的命令通常是不太常使用的命令,或是只在特定的模式下才会使用
的命令。一个例子是取代字串命令,它会全域地将一个字串以另一个来取代。当
您键入 M-x 时,Emacs 会在屏幕的底端询问您,然后您也应该键入这个命令的
名称。在这个例子中是『replace-string』只要键入『repl s』,然后
Emacs 将会补齐这个名称。以 来结束这个命令名称。

取代字串命令需要两个参数 -- 被取代的字串以及用来取代它的字串。您必须以
Newline 字符来结束每一个参数。

>> 将光标移到本行的下两行空白,然后键入
M-x repl schangedaltered

【为了说明的目的,于下保留一行原文。
Notice how this line has changed: you've replaced... 】

请注意这一行是怎么改变的:在光标的起始位置之后,您已经将 c-h-a-n-g-e-d
这个字 -- 不管它在哪里出现 -- 以“altered”这个字来取代了。


* 自动存文件( AUTO SAVE )
-------------------------

当您在一个文件中做了修改,但是还没有将它们储存起来,那么如果您的电脑当
机,它们将有可能遗失。为了避免这种情形发生在您的身上,Emacs 会定期地将
您正在编辑的文件写入“自动储存”文件中。自动储存文件在文件名的前后会各有
一个 # 符号;举例来说,如果您的文件名为“hello.c”,那么它的自动储存文件
案的文件名就是“#hello.c#”。当您以平常的方式储存文件时,Emacs 就会把它
的自动储存文件删除。

如果挂起,您可以经由正常地寻找文件,(指的是您在编辑的文件而不是自动储
存文件)然后键入 M-x recover file 来恢复您的自动储存文件。当它要求
确认时,键入 yes 以继续并恢复自动储存的资料。


* 回应区( ECHO AREA )
-----------------------

如果 Emacs 见到您很慢地键入多字符命令,它会将它们显示在位于窗格下方,
称为“回应区”的区域给您参阅。回应区位在窗格的最后一行。


* 状态行( MODE LINE )
-----------------------

位在回应区的正上面是称为“状态行”的一行。状态行显示出一些信息,如:

--:** TUTORIAL.cn (Fundamental)--L670--58%----------------

本行提供一些关于“Emacs 的状态”以及“您正在编辑的文字”的有用信息。

您已经知道文件名的意义是什么了 -- 就是您找的文件。-NN%-- 指出目前您在文
字文件中的位置;它的意思是说:有 NN 百分比的文字位在窗格的上面。如果文件
的顶端就位在窗格中,那么它就会显示 --Top-- 而不是 --00%--。如果文件的
底部就位在窗格中,那么它是显示 --Bot--。如果您正在看的文字文件很小,在窗
格中就足以看到全部的内容,那么状态行就会显示 --All--。

L 和数字以另一种方式来表示出位置:它们给出了目前所在的行数( Line )。

在靠近前面的星号表示您已经对这些文字做了改变。在您刚拜访或储存一个文件
之后,状态行的那个部分会没有星号,只有破折号。

状态行中位于小括弧里面的部分,是用来告诉您正在使用什么编辑模式。默认的
模式是 Fundamental,也就是您现在使用的。它是“主模式”的一个例子。

Emacs 有许多不同的主模式。它们之中有一些是用来编辑不同的语言以及/或不
同种类的文字,像是 Lisp 模式、 Text 模式等等。在任何的时间只有一个主模
式可以作用,并且它的名称总可以在状态行中被找到,就在现在的
“Fundamental”中的位置。

每一个主模式都使得一些命令的行为表现得不太一样。举例来说,在一个程序中
有一些命令用来制作出备注,而由于每一种程序语言对于一个备注应该长得像什
么,都有著不同的想法,因此每一个主模式都必须以不同的方式来插入备注。每
一个主模式是一个延伸命令的名称,使得您可以用来切换至那个模式。举例来说,
M-x fundamental-mode 就是切换到 Fundamental 模式的一个命令。

如果您想要编辑人类语言的文字文件 -- 像是现在的这一个,您应该使用 Text
模式。

>> 键入 M-x text mode

不要担心,没有任何一个您已经学过的 Emacs 命令,会被改变成任何非常不同
的形式。但是您可以发现到 M-f 和 M-b 现在把贫丝谂(')视为字的一部分。先
前,在 Fundamental 模式中,M-f 和 M-b 将贫丝谂视为字的分隔符号。

主模式通常会像上述那个例子一样,做出一些精巧的改变:大部分的命令在每一
个主模式中“做同样的事”,但是它们以一点点不同的方式来工作。【再举个例
子,接续上面所开的头,以程序语言的备注来说。同样一个插入备注的动作,因
为您使用的程序语言/主模式的不同而不同。若您使用 C 语言,Emacs 插入
『/* 介于中间的为备注区块 */』;若您使用的是 Fortran 语言,Emacs 插入
『c 以字符 c 为首的为备注行』;若您使用的是 Basic 语言,Emacs 则插入『'
贫丝谂以后的为备注文字』。编辑器的弹性如此,实在没有必要为了不同的语言、
目的或外观,设计特殊化的编辑器。“求大同,存小异”在这里也是成立的。】

要浏览您现在所处的主模式的文文件,键入 C-h m。

>> 使用 C-u C-v 一或数次,将本行带到靠近屏幕的上方。
>> 键入 C-h m,看看 Text 模式与 Fundamental 模式是哪里不同。
>> 键入 C-x 1 将文文件从屏幕移除掉。

主模式之所以称为“主要( major )”的原因是因为它们也有次模式( minor
mode )。次要的模式并不是主模式的其他选择,而只是次要的更改。每一个次
模式可以被它本身启用或停止,和所有其他的次模式无关,并且叶丝谕您的主模式
无关。所以您可以不使用次模式,或一个,或任何数量的次模式的组合。

有一个叫做 Auto Fill 模式的次模式非常有用,特别是在编辑人类语言的文字
时。当这个模式启用时, Emacs 在当您插入文字并且使一行太宽时,会将那一
行,在字与字之间自动地分隔开。

您可以 M-x auto fill mode 来将 Auto Fill 模式启用。当这个模式
启用时,您可以使用 M-x auto fill mode 来将它取消。当这个模式不
用时,则这个命令会将它启动,而当这个模式启用时,这个命令会将它关闭。我
们说这个命令用来“切换( toggle )”模式。

>> 现在键入 M-x auto fill mode。然后一再地插入字串
“ asdf ”,直到您看到它分成两行。您必须在它们之间摆上空白,
因为 Auto Fill 只在空白处断行。

边界通常被设定为 70 个字符,但是您可以用 C-x f 命令来改变它。您应该以
一个数字参数的方式来给定您所希望的边界设定。

>> 键入 C-x f 并附上引数 20:『C-u 2 0 C-x f』。
然后键入一些文字,看看 Emacs 以 20 个字符,
在行与行之间进行 fill 动作。然后再用一次 C-x f 将边界设回 70。

如果您在一个段落的中间做出改变,Auto Fill 模式并不会为您重新进行 fill
的动作( re-fill )。要 re-fill 这个段落,键入 M-q (META-q),而光标必
须处在其中。

>> 移动光标到前一段中,然后键入 M-q。


* 搜寻( SEARCHING )
---------------------

Emacs 可以搜寻字串(字串可以是一群连续的字符或字)【就中文来说,字符和
字基本上意义相同;此处所指的『字』,是英文中没有被空白隔开的字符集
合。】,往前或往后搜寻都可以。搜寻一个字串是一种光标移动命令,它会将游
标移动到字串出现的下一个地方。

Emacs 搜寻命令与大部分编辑器的搜寻命令不同的地方在于,它是“渐进的
( incremental )”。这表示搜寻发生在您键入想要搜寻的文字串后。

要开始搜寻的命令是:C-s 往前搜寻,C-r 往后搜寻。但先等一下!现在先不要
试。

当您键入 C-s 时,会发现到有一个字串“I-search”出现在回应区中作为提示。
它告诉您 Emacs 现在正处于称为“渐进式搜寻”的状态中,等待您键入您想要
搜寻的字串。 会结束一个搜寻。

>> 现在键入 C-s 开始一个搜寻。慢一点,一次键入一个字符,
键入『cursor』这个字,每键入一个字符时,稍微停一下,
注意看看光标发生了什么事。现在您已曾经搜寻过“cursor”这个字了。
>> 再次键入 C-s 来搜寻“cursor”的下一个出现位置。
>> 现在键入 四次,看看光标是如何移动的。
>> 键入 结束搜寻。

您有没有看到发生了什么?在一个渐进式搜寻中,Emacs 试著要走到您键入的字
串的下一个出现位置。要移动到光标所在的下一个出现位置,只要再键入 C-s
一次。如果并没有这样的出现位置存在,Emacs 会哔一声,并告诉您目前的搜寻
“失败”。另外 C-g 也可以用来结束搜寻。

注意:在某些系统中,键入 C-s 将会把屏幕冻结,您将看不到从 Emacs 来的任
何输出。这表示操作系统一个称为“流程控制”的“功能”将 C-s 命令拦截住,
并且不让它传到 Emacs。要取消屏幕的冻结,请键入 C-q。然后到 Emacs 使用
手册中看看对于“渐进式搜寻的同时进入( Spontaneous Entry to
Incremental Search )”这个主题,以取得处理这个“功能”的建议。

如果您在一个渐进式搜寻的中间,并且键入 ,您可以发现在搜寻字串
中的最后一个字符被消除了,并且搜寻会回到这个搜寻的最后一个地方。举例来
说,假设您已经键入了『c』,用来寻找“c”的第一次出现。现在如果您键入
『u』,光标会移动到“cu”的第一次出现位置。现在键入 ,这会将
“u”从搜寻字串中消除,并且光标会移回到“c”的第一次出现位置。

如果您在一个搜寻的中间,并且键入一个 CONTROL 或 META 字符的话,(但有
一些例外 -- 对搜寻而言特别的字符,像是 C-s 和 C-r ),搜寻会被结束。

C-s 会开始一个搜寻,它会寻找搜寻字串在目前光标位置“之后”,的任何出现
位置。如果您想要在先前文字中搜寻,键入 C-r 作为替代。除了搜寻的方向相
反之外,我们所宋募?有关 C-s 的所有事情,同样地可以应用到 C-r 上。


* 多重窗格( MULTIPLE WINDOWS )
--------------------------------

Emacs 许多好功能的其中之一是,您可以在屏幕中同时展示超过一个窗格。

>> 移动光标到这一行并且键入 C-u 0 C-l。

>> 现在键入 C-x 2,它会将屏幕平分成两个窗格。
这两个窗格都显示著这个快速指南。光标则停留在上方的窗格。

>> 键入 C-M-v 以卷动下方的窗格。
(如果您并没有一个真的 META 键,则键入 ESC C-v 亦可。)

>> 键入 C-x o(『o』指的是其他『other』的意思),
将光标移动到下方的窗格。

>> 在下方的窗格中,使用 C-v 和 M-v 来卷动它。
继续维持在上方的窗格中阅读这些指引。

>> 再一次键入 C-x o 将光标移回到上方的窗格。
光标会回到它在上方窗格中,原本所在的位置。

您可以持续使用 C-x o 在窗格之间切换。每一个窗格有它自己的光标位置,但
是只有一个窗格会真的显示出光标。所有通常的编辑命令只会应用到那个光标所
在的窗格。我们称这个为“被选择的窗格”。

命令 C-M-v 在当您于一个窗格中编辑文字,并使用其他的窗格作为参考之用时,
是非常有用的。您可以将光标一直保持在您正在编辑的窗格中,并以 C-M-v 指
令在其他的窗格循序地前进。【验证工作特别适合以这种方式来进行,如 GNU
中译小组:找一个原始英文文件;再找它翻译好的中文文件,编辑这个“被选择
的窗格”,以 C-M-v 命令跟上验证中的段落……。】

C-M-v 是 CONTROL-META 字符的一个例子。如果您有一个真的 META 键,您可以
同时按住 CONTROL 和 META 再键入 v 来键入 C-M-v。CONTROL 或 META “谁先
被按住”并没有影响,因为这两个键都是用来修饰您所键入的字符。

如果您并没有一个真的 META 键,您可以使用 ESC 来作为替代,这样子顺序就
有关系了:您必须键入 ESC ,跟著键入 CONTROL-v,CONTROL-ESC v 并不会作
用。这是因为 ESC 是一个具有本身作用的字符,而不是一个修饰键。

>> (在上方窗格)键入 C-x 1 以除去下方窗格。

(如果您已经在底端的窗格键入 C-x 1,那么将会把上面的窗格隐藏住。将这个
命令想像成“只保留一个窗格 -- 我正在编辑的这个。”)

您不需要在两个不同的窗格中显示相同的缓冲区。如果您使用 C-x C-f 在一个
窗格中找文件,另一个窗格并不因而改变。您可以在独立的任一个窗格中找〔它
自己的〕一个文件。

这里有另外一个方式可以用来,使用两个窗格显示两个不同的东西:

>> 键入 C-x 4 C-f,后面跟著您的其中一个文件的名称。
作为结束。看看指定的文件出现在下方的窗格。
光标也跑到那里。

>> 键入 C-x o 以回到上方的窗格,然后以 C-x 1 删除掉下方窗格。


* 递归编辑阶层( RECURSIVE EDITING LEVELS )
--------------------------------------------

有时候您会进入所谓的“递归编辑阶层”。它是由位在状态行的方括弧所指明,
并且包含住以小括弧来指明的模式名称。举例来说,您可能会看到
[(Fundamental)],而不是 (Fundamental)。

要退出递归编辑阶层,请键入 ESC ESC ESC。这是个全功能的“退出”命令。您
也可以使用它来除去多余的窗格,并且退出小缓冲区。

>> 键入 M-x 以进入小缓冲区;然后键入 ESC ESC ESC 退出。

您无法使用 C-g 来退出递归编辑阶层。这是因为 C-g 是用来取消命令以及“位
于”递归编辑阶层中的“引数( arguments )”之故。


* 取得更多的帮助( GETTING MORE HELP )
---------------------------------------

在本快速指南中,我们试著仅提供刚刚好的信息让您可以开始使用 Emacs。在
Emacs 中有太多可取得的信息,想要在这里全部解释是不可能的。然而,您也许
会想要学习更多 Emacs 相关的信息,因为它有许多其他有用的功能。Emacs 提
供了“阅读有关 Emacs 命令”的命令。这些“help”命令都以 CONTROL-h 这个
字符作为开头,称作为“Help 字符”。

要使用 Help 功能,键入 C-h 字符,然后再键入一个说明您所需要的帮助的字
元。如果您真的不知道要问什么,那么请键入『C-h ?』,此时 Emacs 将会告诉
您它能够提供的帮助。如果您已经键入 C-h,但发现您并不需要任何帮助,键入
C-g 来取消掉它就是了。

(有些网站将 C-h 这个字符的意义改变了。他们真的不应该把它设为对所有使
用者全部都适用的方法,所以您现在就有了个理由来抱怨系统管理者了。在此同
时,如果 C-h 并没有在窗格的底部显示任何有关帮助的消息,试著键入 F1 键,
或是 M-x help 。)

最基本的 HELP 功能是 C-h c。键入 C-h,字符 c,以及一个或一串字符;然后
Emacs 会显示一个非常简短的有关这个命令的解释。

>> 键入 C-h c C-p。

消息应该会像是这样:

C-p runs the command previous-line

这告诉了您“函数的名称”。函数名称主要是用来自订以及扩充 Emacs。但是由
于函数名称是由“用来指出这命令在做些什么”而被选定,它们因此也可以作为
非常简短的文文件 -- 足够提醒您已经学过的命令。

多字符命令像是 C-x C-s 和 (如果您没有 META 或 EDIT 或 ALT 键)v
也可以在 C-h c 后面出现。

要取得更多有关一个命令的信息,用 C-h k 来取代使用 C-h c 。

>> 键入 C-h k C-p。

这会在一个 Emacs 窗格显示这个函数的说明文文件以及它的名称。当您阅读完后,
键入 C-x 1 以跳离这些帮助文字。您并不需要马上跟著做。您可以做些编辑,
当参考到帮助文字时再键入 C-x 1。

这里有一些其他有用的 C-h 选项:

C-h f 解释一个函数。您要键入此函数的名称。

>> 试著键入 C-h f previous-line
这会印出 Emacs 所有的有关“实作出 C-p 这个命令的函数”的信息

C-h v 这个类似的命令会显示出“您可以用来自订 Emacs 行为的变量”的文文件。
当 Emacs 要求时,您需要键入这变量的名称。

C-h a 命令相关查找( Command Apropos )。
键入一个关键字然后 Emacs 会列出所有
“在其名称中含有此关键字”的全部命令。
这些命令全部都可以经由 META-x 来启动。
对于一些命令而言,命令相关查找也会列出
“可以执行相同命令”的一个或两个字符的串列。

>> 键入 C-h a file

这会在另一个窗格显示一个“在其名称中含有『file』的全部 M-x 命令”的列
表。您将会看到像是 C-x C-f 的“字符-命令”列在其相对应命令名称(如:
find-file )的旁边。

>> 键入 C-M-v 上下移动 help 窗格。试个几次。

>> 键入 C-x 1 来删除 help 窗格。

C-h i 阅读线上使用手册( a.k.a. Info )。
这个命令将您带到了称为“*info*”的特殊缓冲区,在那,
您可以阅读安装在您的系统里的软件包的线上使用手册。
键入 m emacs 以阅读 Emacs 使用手册。
如果您在此之前未曾使用过 Info 系统,请键入『?』。
Emacs 将会带您进入 Info 模式功能的导览指南。
一旦完成了本快速指南的研读,您应该查阅 Emacs Info
使用手册,以作为主要的参考文文件。


* 更多功能特色( MORE FEATURES )
---------------------------------

您可以经由阅读 Emacs 使用手册〈不论是一本书或是在 Info 中的线上版本
(使用 Help 菜单或是键入 F10 h r )〉来学到更多有关它的知识。有两个您
可能会特别喜欢的功能特色是可以节省打字量的 completion 还有简化文件处理
的 dired 。

Completion 是一种避免不必要的打字的方式。举例来说,如果您想要切换
*Messages* 缓冲区,您可以键入 C-x b *M ,只要可以从您已经键入的文
字中确定, Emacs 就会将剩下的缓冲区名称补齐。 Completion 是在 Emacs 使
用手册的 Info 中,称为“Completion”的节点中所解释的。

Dired 使您可以在一个目录中列出文件(次目录则是可选的)、在列表中到处移
动、拜访、重新命名、删除以及对文件作操作。 Dired 是在 Emacs 使用手册的
Info 中,称为“Dired”的节点中所解释的。

使用手册也解释了许多其它 Emacs 的功能特色。


* 结论( CONCLUSION )
----------------------

记住,要完全退出 Emacs 请使用 C-x C-c 。要暂时退出到 shell,稍后再回到
Emacs,请使用 C-z 。

本快速指南对于所有的新手应该都是易于理解的,所以如果您发现了什么地方不
清楚,不要只是坐著怪自己 -- (向本文作者和翻译)发点牢骚吧!


* 翻译( TRANSLATION )
-----------------------

本快速指南的翻译人员列表如下,如果您在阅读本文之前,“完全”对 Emacs
没有概念,请告诉我们您的意见以作为本文后续的改进依据。翻译也提供了一份
《GNU Emacs 中文处理说明》在
http://www.gnu.org/software/chinese/guide/emacs-chinese.cn.html 〈部份
内容已经整理到本快速指南〉,也请您自行参阅。

编辑器是电脑使用者最常接触到的应用程序,因此不应该让初学者感到过于困难,
就一般的评论来说, Emacs 是不难学会使用的编辑器,但您的意见可以使它更
为贴近一般的使用者,并使电脑作为工具的角色得以充分发挥。如果您愿意提供
改进的意见,请寄 email 到<chinese-translators@gnu.org> 。请不要害羞,
我们欢迎任何有关的讨论;如果您不想寄到邮件清单,请直接 email 给本文翻
译 <chliu@gnu.org> 。请在 Title 行中包含此字串“Emacs TUTORIAL: issue here>”。

如果您是 Emacs 老手,GNU Chinese Translators Team (GNU/CTT)
<http://www.gnu.org/software/chinese/> 欢迎您的加入,我们现在正需要愿
意投入翻译 Emacs 使用手册的人员。

本快速指南并没有采用习惯上编辑器所使用的翻译术语,一方面因为它的实际意
义与一般的编辑器不同,原文本就不同;另一方面也因为 Emacs 所采用的视觉
设计概念,早在窗口化系统之前就已经存在,本质也不相同。总之,翻译以为这
样可以帮助对于 Emacs 整个设计哲学的理解。如果收到的回复中,大部份要求
提出修改,我们还是从善如流。

(0) 为了避免“光标移动命令”论述上的混淆,本文采用的术语为:
往“前”移( move Forward );往“后”移( move Backware )
〔或是往“回”移〕;
往“上”移( Previous line );往“下”移( Next line )。
(1) 在本文中,“行”指的是 row,这是采用一般的习惯用法。
为了避免误导中文读者,特别在此说明。在正式的用法中:
“column”翻译为“行”,以“纵”为行(直行),也译为“栏”;
“row”翻译为“列”,以“横”为列(横列)。
读者思索一下“合纵连横”应该可以理解。
大约是因为中文原本是直书的,我们说“一行字”是没问题;
但现在大部份的情形中文是横书的,由于习惯使然也称为一行字了。
(2) 有关于“文字”及其集合的相关译文,翻译所采用的有:
编辑的“文字”:“然后键入一些文字”;
用来作为说明功能的“文文件”:“这个函数的说明文文件”;
特指其所说明的内容的“文本”:“实际效力以英文本为准”。
即使只是“一行字”,只要它是用来作为说明之用,
翻译还是将它视为“文文件”。
(3) “cut”的动作在 Emacs 中分为“杀掉”和“删除”,之间的差异如下:
一般编辑器中的“cut”:只有最近被 cut 的文字摆到 clipboard 中;
“杀掉( killing )”:被杀掉的文字,全部被加入到 kill ring 中;
“删除( deleting )”:被删除的文字,就是被删除了。
因此在一般编辑器中,您只能 paste“最近”被 cut 的文字;
而在 Emacs 中,您可以“拉回”任何先前被杀掉的文字,同时,
它的作法很容易。至于被删除的,因为用来作为“删除”功能的命令,
所能移去的文字数量都很少,因此也没什么好拉回的;
如果真的想恢复这些文字,undo 您的动作就是了。
(4) “window”同时翻译为“窗口”和“窗格”,
前者表示现在一般概念中的窗口系统,如“X 窗口”;
后者表示 Emacs 中的窗口,翻译在此通称为“窗格”。
Emacs 的“窗格”即使在命令列提示下也可以正常工作,
此一基本特性显然治募?我们以另一个专用术语来描述它。
(5) 关于文件的术语,“找”一个文件在 Emacs 中有两种作用:
找一个“储不存在”的文件,读者应认知为“开新文件”;
找一个“已经存在”的文件,则是“打开旧文件”。
Emacs 只以一个“找”的动作来解决,主要的原因是“实际上”
的软件工作如此。黑客们应该会发现这样比较自然,
因为它反应了电脑的工作方式,同时操作起来也较少废话。
(6) 在【】中的文字为翻译的备注。
(7) 关于使中文文文件结构化的议题,问题已经获得解决。
( 本翻译文本所采用的简繁用语差异列表如下:
zh cn
文件 文档
软体 软件
作业 操作
套件 包
视窗 窗口
递回 递归
骇客 黑客
资讯 信息

另外,我们也十分欢迎读者可以直接修改本快速指南,做出自己的版本,以自己
认为最为合适的方式来介绍 Emacs 。如果您做出了这样个人化的版本,并且认
为足供大家参考使用,请寄给 <chinese-coordinators@gnu.org> ,我们会将您
的版本公开在 GNU/CTT 的网页中提供给中文使用者下载。

翻译:刘 昭宏 <chliu@gnu.org>
验证:马 雪萍


* 复制( COPYING )
-------------------

本快速指南沿袭自具有悠久历史的 Emacs 快速指南,由 Stuart Cracraft 为了
原始的 Emacs 所撰写的版本开始。

这个版本的快速指南和 GNU Emacs 一样都是版权化的,并且允许在某些条件下
散布其拷贝:

Copyright (c) 1985, 1996, 1998, 2001, 2002 Free Software Foundation
Chinese Translation by Chao-Hong Liu (2002, 2003)

Permission is granted to anyone to make or distribute verbatim copies
of this document as received, in any medium, provided that the
copyright notice and permission notice are preserved,
and that the distributor grants the recipient permission
for further redistribution as permitted by this notice.

本文允许在不变更文文件内容的前提下刊登在任何形式的媒体中,
但需保留版权声明以及许可声明,
散布者也必须给予接受者如同此声明所允许的,进一步散布的许可。
【本段译文提供读者作为参考以帮助理解,实际效力以英文本为准。】

Permission is granted to distribute modified versions
of this document, or of portions of it,
under the above conditions, provided also that they
carry prominent notices stating who last altered them.

本文允许在与上述相同的条件下,散布修改后的版本,或是其中的一部份,
但它们也必须带有显著的,说明由谁最后更动了它的声明。
【Copyleft 版权除了提供使用者自由外,也维护原始作者,
以及后来的修改作者的名誉权( credit )。
本段译文提供读者作为参考以帮助理解,实际效力以英文本为准。】

复制 Emacs 本身的条件较为复杂,但是具有相同的精神。请阅读 COPYING 这个
文件,并且确实给予您的朋友 GNU Emacs 的拷贝。请经由“使用、撰写、以及
分享自由软件”来帮助消除软件障碍主义(拥有权)!

;;; DO NOT PUT THIS ON ZHS OR ZHT FILE...
;;; Local Variables:
;;; coding: chinese-iso-8bit
;;; End:'