• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 40, 文章 - 0, 評論 - 9, 引用 - 0
            數據加載中……

            C++文件讀寫函數介紹

            http://www.zxbc.cn/html/cjjhs/1413524521078.html

            今天給大家介紹一下C++中常用到的讀寫函數,新手可以收藏一下,方便以后查找。 
              1.fopen()
              fopen的原型是:FILE *fopen(const char *filename,const char *mode),fopen實現三個功能:為使用而打開一個流,把一個文件和此流相連接,給此流返回一個FILR指針。
              參數filename指向要打開的文件名,mode表示打開狀態的字符串,其取值如下:
              字符串 含義
              "r" 以只讀方式打開文件
              "w" 以只寫方式打開文件
              "a" 以追加方式打開文件
              "r+" 以讀/寫方式打開文件,如無文件出錯
              "w+" 以讀/寫方式打開文件,如無文件生成新文件
            一個文件可以以文本模式或二進制模式打開,這兩種的區別是:在文本模式中回車被當成一個字符’\n’,而二進制模式認為它是兩個字符 0x0D,0x0A;如果在文件中讀到0x1B,文本模式會認為這是文件結束符,也就是二進制模型不會對文件進行處理,而文本方式會按一定的方式對數據作 相應的轉換。
              系統默認的是以文本模式打開,可以修改全部變量_fmode的值來修改這個設置,例如_fmode=O_TEXT;就設置默認打開方式為文本模式;而_fmode=O_BINARY;則設置默認打開方式是二進制模式。
              我們也可以在模式字符串中指定打開的模式,如"rb"表示以二進制模式打開只讀文件,"w+t"或"wt+"表示以文本模式打開讀/寫文件。
              此函數返回一個FILE指針,所以申明一個FILE指針后不用初始化,而是用fopen()來返回一個指針并與一個特定的文件相連,如果成敗,返回NULL,中國自學編程網,www.zxbc.cn
              例:
               以下是引用片段:
            FILE *fp; 
              if(fp=fopen("123.456","wb")) 
              puts("打開文件成功"); 
              else 
              puts("打開文件成敗");
              2.fclose()
              fclose()的功能就是關閉用fopen()打開的文件,其原型是:int fclose(FILE *fp);如果成功,返回0,失敗返回EOF。
              在程序結束時一定要記得關閉打開的文件,不然可能會造成數據丟失的情況,我以前就經常犯這樣的錯誤。
              例:fclose(fp);
              3.fputc()
              向流寫一個字符,原型是int fputc(int c, FILE *stream); 成功返回這個字符,失敗返回EOF。
              例:fputc(’X’,fp);
              4.fgetc()
              從流中讀一個字符,原型是int fputc(FILE *stream); 成功返回這個字符,失敗返回EOF。
              例:char ch1=fgetc(fp);
              5. fseek()
            此函數一般用于二進制模式打開的文件中,功能是定位到流中指定的位置,原型是 int fseek(FILE *stream, long offset, int whence);如果成功返回0,參數offset是移動的字符 數,whence是移動的基準,取值是:
              符號常量 值 基準位置
              SEEK_SET 0 文件開頭
              SEEK_CUR 1 當前讀寫的位置
              SEEK_END 2 文件尾部
              例:fseek(fp,1234L,SEEK_CUR);//把讀寫位置從當前位置向后移動1234字節(L后綴表示長整數)
              fseek(fp,0L,2);//把讀寫位置移動到文件尾
              6.fputs()
              寫一個字符串到流中,原型int fputs(const char *s, FILE *stream);
                例:fputs("I Love You",fp);
              7.fgets()
              從流中讀一行或指定個字符,原型是char *fgets(char *s, int n, FILE *stream); 從流中讀取n-1個字符,除非讀完一行,參數s是來接收字符串,如果成功則返回s的指針,否則返回NULL。
              例:如果一個文件的當前位置的文本如下:
              Love ,I Have
              But ……..
              如果用
              fgets(str1,4,file1);
              則執行后str1="Lov",讀取了4-1=3個字符,而如果用
              fgets(str1,23,file1);
              則執行str="Love ,I Have",讀取了一行(不包括行尾的’\n’)。
              8.fprintf()
              按格式輸入到流,其原型是int fprintf(FILE *stream, const char *format[, argument, …]);其用法和printf()相同,不過不是寫到控制臺,而是寫到流罷了。
              例:fprintf(fp,"%2d%s",4,"Hahaha");
              9.fscanf()
              從流中按格式讀取,其原型是int fscanf(FILE *stream, const char *format[, address, …]);其用法和scanf()相同,不過不是從控制臺讀取,而是從流讀取罷了。
              例:fscanf(fp,"%d%d" ,&x,&y);
              10.feof()
              檢測是否已到文件尾,是返回真,否則返回0,其原型是int feof(FILE *stream);
              例:if(feof(fp))printf("已到文件尾");
              11.ferror()
              原型是int ferror(FILE *stream);返回流最近的錯誤代碼,可用clearerr()來清除它,clearerr()的原型是void clearerr(FILE *stream);
              例:printf("%d",ferror(fp));
              12.rewind()
              把當前的讀寫位置回到文件開始,原型是void rewind(FILE *stream);其實本函數相當于fseek(fp,0L,SEEK_SET);
              例:rewind(fp);
              12.remove()
              刪除文件,原型是int remove(const char *filename); 參數就是要刪除的文件名,成功返回0。
              例:remove("c:\\io.sys");
              13.fread()
            從流中讀指定個數的字符,原型是 size_t fread(void *ptr, size_t size, size_t n, FILE *stream);參數ptr是保存讀取的 數據,void*的指針可用任何類型的指針來替換,如char*、int *等等來替換;size是每塊的字節數;n是讀取的塊數,如果成功,返回實際讀 取的塊數(不是字節數),本函數一般用于二進制模式打開的文件中。
              例:
               以下是引用片段:
            char x[4230]; 
              FILE *file1=fopen("c:\\msdos.sys","r"); 
              fread(x,200,12 ,file1);//共讀取200*12=2400個字節
              14.fwrite()
            與fread對應,向流中寫指定的數據,原型是 size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);參數 ptr是要寫入的數據指針,void*的指針可用任何類型的指針來替換,如char*、int *等等來替換;size是每塊的字節數;n是要寫的塊數, 如果成功,返回實際寫入的塊數(不是字節數),本函數一般用于二進制模式打開的文件中。
                例:
               以下是引用片段:
              char x[]="I Love You"; 
              fwire(x, 6,12,fp);//寫入6*12=72字節 
              將把"I Love"寫到流fp中12次,共72字節
              15.tmpfile()
              其原型是FILE *tmpfile(void); 生成一個臨時文件,以"w+b"的模式打開,并返回這個臨時流的指針,如果失敗返回NULL。在程序結束時,這個文件會被自動刪除。
              例:FILE *fp=tmpfile();
              16.tmpnam();
              其原型為char *tmpnam(char *s); 生成一個唯一的文件名,其實tmpfile()就調用了此函數,參數s用來保存得到的文件名,并返回這個指針,如果失敗,返回NULL。
              例:tmpnam(str1);

            posted @ 2008-09-12 17:07 茶 閱讀(774) | 評論 (0)編輯 收藏

            C++解析XML(From:C++ front)

            http://blog.csdn.net/wangqis/archive/2006/05/17/743039.aspx
            http://blog.csdn.net/amidiot/archive/2005/09/11/477335.aspx

            用mingw32-make前修改一下makefile文件,改為如下

            # DEBUG can be set to YES to include debugging info, or NO otherwise(不是DEBUG)
            DEBUG          := NO

            # PROFILE can be set to YES to include profiling info, or NO otherwise
            PROFILE        := NO

            # TINYXML_USE_STL can be used to turn on STL support. NO, then STL
            # will not be used. YES will include the STL files.(使用STL,選擇的話,則可以使用std::string)
            TINYXML_USE_STL := YES


            張弛<zhangchi(at)china.com>

            注:本文的最新版本可以在下面的地址找到
                   http://amidiot.512j.com/article/tinyxml/tinyxml_note.htm

            一、      TinyXml的特點

            TinyXml是一個基于DOM模型的、非驗證的輕量級C++解釋器。

            1.      SAXDOM

            目前XML的解析主要有兩大模型:SAXDOM

            其中SAX是基于事件的,其基本工作流程是分析XML文檔,當發現了一個新的元素時,產生一個對應事件,并調用相應的用戶處理函數。這種方式占用內存少,速度快,但用戶程序相應得會比較復雜。

            DOM(文檔對象模型),則是在分析時,一次性的將整個XML文檔進行分析,并在內存中形成對應的樹結構,同時,向用戶提供一系列的接口來訪問和編輯該樹結構。這種方式占用內存大,速度往往慢于SAX,但可以給用戶提供一個面向對象的訪問接口,對用戶更為友好。

            另據說,一些同時提供了SAXDOM接口的庫,是在底層先實現SAX,再在SAX的基礎上實現DOM

            目前我知道的XML解析庫有下面幾個:

            名稱

            訪問接口

            是否支持驗證

            備注

            Expat

            SAX/Local

            不清楚

            Local指它還有一套自己訪問模型

            LibXML2

            SAX/DOM

             

             

             

            TinyXml

            DOM

             

             

             

            XML4C

            SAX/DOM

            Xerces-C是一家,不過用了ICU,國際化似乎更好

            Xerces-C

            SAX/DOM

             

             

             

            XML Booster

            Local

            不清楚

            這個庫不是特別了解,好像是類似yacc那樣,可以生成一個特定的解析器,估計效率應該很高(看名字也像)。

             

             

             

            2.      驗證和非驗證

            對于一個特定的XML文檔而言,其正確性分為兩個層次。首先是其格式應該符合XML的基本格式要求,比如第一行要有聲明,標簽的嵌套層次必須前后一致等等,符合這些要求的文件,就是一個合格的XML文件,稱作well-formatted。但除此之外,一個XML文檔因其內容的不同還必須在語義上符合相應的標準,這些標準由相應的DTD文件或者Schema文件來定義,符合了這些定義要求的XML文件,稱作valid

            因此,解析器也分為兩種,一種是驗證的,即會跟據XML文件中的聲明,用相應的DTD文件對XML文件進行校驗,檢查它是否滿足DTD文件的要求。另一種是忽略DTD文件,只要基本格式正確,就可以進行解析。

            就我所知,驗證的解析器通常都是比較重量級的。TinyXml不支持驗證,但是體積很小,用在解析格式較為簡單的XML文件,比如配置文件時,特別的合適。

             

            二、      TinyXml的構建和使用

            1.      獲取

            TinyXml首頁在http://www.grinninglizard.com/tinyxml/index.html,從這里可以找到最新版本的源代碼,目前的版本是2.3.4

            2.      構建

            TinyXml在構建時可以選擇是否支持STL,選擇的話,則可以使用std::string,所以通常應該打開這個選項。

            Windows上,TinyXml的源碼包里提供了VC6的工程文件,直接用它就可以生成兩個靜態庫(帶STL和不帶STL),非常容易。唯一需要注意的是,默認生成的庫是單線程的,如果用在多線程的項目中,需要改動一下配置,生成相應的多線程庫。

            Unix平臺上,TinyXml的源碼包里只提供了一個Makefile,對于典型的Linux系統,或裝了gccgmake的其他Unix,這個Makefile足夠用了,我在RH9RHEL4上測試,簡單的make就成功了。需要注意的有以下幾點:默認的編譯是不支持STL的,可以通過編輯MakefileTINYXML_USE_STL := NO那一行,把NO改成YES就可以支持STL了;還有默認只生成了一個測試程序,沒有生成任何庫,如果要生成靜態庫的話,可以用ar命令,將生成的幾個目標文件打包就行了,如果要生成動態庫,則需要加上-fpic參數重新編譯。

            3.      使用

            構建了相應的庫之后,在使用了它們的工程中,只要在連接時把他們連上就行了。需要注意的是,如果需要STL支持,在編譯用到了TinyXml的文件時,需要定義一個宏TIXML_USE_STL,對gcc,可以使用參數-DTIXML_USE_STL,對cl.exeVC),可以使用參數/DTIXML_USE_STL,如果嫌麻煩,可以直接定義在 tinyxml.h文件里。

             

             

             

            三、      TinyXml的編程模型

            1.      類之間的關系

            TinyXml實現的時DOM訪問模型,因此提供了一系列的類對應XML文件中的各個節點。主要類間的關系如下圖所示:

            類結構圖

            TiXmlBase:其他類的基類,是個抽象類

            TiXmlNode:表示一個節點,包含節點的一般方法,如訪問自節點、兄弟節點、編輯自身、編輯子節電

            TiXmlDocument:表示整個XML文檔,不對應其中某個特定的節點。

            TiXmlElement:表示元素節點,可以包含子節點和TiXmlAttribute

            TiXmlComment:表示注釋

            TiXmlDeclaration:表示聲明

            TiXmlText:表示文本節點

            TiXmlUnknown:表示未知節點,通常是出錯了

            TiXmlAttribute:表示一個元素的屬性

            下面是一個簡單的例子:

            <?xml version="1.0" encoding="utf-8" ?>
                    <!-This is only a sample-->

                <book>

                    <name>TinyXml How To</name>

                   <price unit=”RMB”>20</price>

                    <description>Some words…</description>

             </ book >

             
                    整個文檔,對應TiXmlDocument

            book,name,price, description,都對應TiXmlElement

            第一行對應一個TiXmlDeclaration

            第二行對應一個TiXmlComment

            “TinyXml How To”對應一個TiXmlText

            unit則是price的一個TiXmlAttribute

            這些類與XML文件中的相應元素都有很好的對應關系,因此相信參照TinyXml的文檔,可以很容易的掌握各個方法的使用。

             

            2.      需要注意的問題

            各類之間的轉換

            由于各個節點類都從TiXmlNode繼承,在使用時常常需要將TiXmlNode*類型的指針轉換為其派生類的指針,在進行這種轉換時,應該首先使用由TiXmlNode類提供的一系列轉換函數,如ToElement(void),而不是c++dynamic_cast

             檢查返回值

             由于TinyXml是一個非校驗的解析器,因此當解析一個文件時,很可能文件并不包含我們預期的某個節點,在這種情況下,TinyXml將返回空指針。因此,必須要對返回值進行檢查,否則將很容易出現內存訪問的錯誤。

             如何重頭建立一個XML文件

             先建立一個TiXmlDocument對象,然后,載入某個模板,或者直接插入一個節點作為根節點,接著就可以像打開一個已有的XML文件那樣對它進行操作了。

             

            四、      總結

            TinyXml最大的特點就是它很小,可以很方便的靜態連接到程序里。對于像配置文件、簡單的數據文件這類文件的解析,它很適合。但是由于它是非驗證的,因此需要在程序里做許多檢查工做,加重了程序編寫的負擔。因此對于復雜的XML文件,我覺得最好還是用驗證的解析器來處理。


            posted @ 2008-09-12 14:12 茶 閱讀(803) | 評論 (0)編輯 收藏

            C++各大有名庫的介紹(作者 armman)

            http://hi.baidu.com/chendeping/blog/item/ff0de518418aecb24bedbc6f.html

            C++各大有名庫的介紹——GUI

              在眾多C++的庫中,GUI部分的庫算是比較繁榮,也比較引人注目的。在實際開發中,GUI庫的選擇也是非常重要的一件事情,下面我們綜述一下可選擇的GUI庫,各自的特點以及相關工具的支持。

            1、MFC

              大名鼎鼎的微軟基礎類庫(Microsoft Foundation Class)。大凡學過VC++的人都應該知道這個庫。雖然從技術角度講,MFC是不大漂亮的,但是它構建于Windows API 之上,能夠使程序員的工作更容易,編程效率高,減少了大量在建立 Windows 程序時必須編寫的代碼,同時它還提供了所有一般 C++ 編程的優點,例如繼承和封裝。MFC 編寫的程序在各個版本的Windows操作系統上是可移植的,例如,在Windows 3.1下編寫的代碼可以很容易地移植到 Windows NT 或 Windows 95 上。但是在最近發展以及官方支持上日漸勢微。

            2、QT

            參考網站:http://www.trolltech.com

              Qt是Trolltech公司的一個多平臺的C++圖形用戶界面應用程序框架。它提供給應用程序開發者建立藝術級的圖形用戶界 面所需的所用功能。Qt是完全面向對象的很容易擴展,并且允許真正地組件編程。自從1996年早些時候,Qt進入商業領域,它已經成為全世界范圍內數千種 成功的應用程序的基礎。Qt也是流行的Linux桌面環境KDE 的基礎,同時它還支持Windows、Macintosh、Unix/X11等多種平臺。

            3、WxWindows

            參考網站:http://www.wxwindows.org

              跨平臺的GUI庫。因為其類層次極像MFC,所以有文章介紹從MFC到WxWindows的代碼移植以實現跨平臺的功能。通過 多年的開發也是一個日趨完善的GUI庫,支持同樣不弱于前面兩個庫。并且是完全開放源代碼的。新近的C++ Builder X的GUI設計器就是基于這個庫的。

            4、Fox

            參考網站:http://www.fox-toolkit.org/

              開放源代碼的GUI庫。作者從自己親身的開發經驗中得出了一個理想的GUI庫應該是什么樣子的感受出發,從而開始了對這個庫的開發。有興趣的可以嘗試一下。

            5、WTL

              基于ATL的一個庫。因為使用了大量ATL的輕量級手法,模板等技術,在代碼尺寸,以及速度優化方面做得非常到位。主要面向的使用群體是開發COM輕量級供網絡下載的可視化控件的開發者。

            6、GTK

            參考網站:http://gtkmm.sourceforge.net/

              GTK是一個大名鼎鼎的C的開源GUI庫。在Linux世界中有Gnome這樣的殺手應用。而Qt就是這個庫的C++封裝版本。

            C++各大有名庫的介紹——網絡通信

            1、ACE

            參考網站:http://www.cs.wustl.edu/~schmidt/ACE.html

              C++庫的代表,超重量級的網絡通信開發框架。ACE自適配通信環境(Adaptive Communication Environment)是可以自由使用、開放源代碼的面向對象框架,在其中實現了許多用于并發通信軟件的核心模式。ACE提供了一組豐富的可復用C++ 包裝外觀(Wrapper Facade)和框架組件,可跨越多種平臺完成通用的通信軟件任務,其中包括:事件多路分離和事件處理器分派、信號處理、服務初始化、進程間通信、共享內 存管理、消息路由、分布式服務動態(重)配置、并發執行和同步,等等。

            2、StreamModule

            參考網站:http://www.omnifarious.org/StrMod

              設計用于簡化編寫分布式程序的庫。嘗試著使得編寫處理異步行為的程序更容易,而不是用同步的外殼包起異步的本質。

            3、SimpleSocket

            參考網站:http://home.hetnet.nl/~lcbokkers/simsock.htm

              這個類庫讓編寫基于socket的客戶/服務器程序更加容易。

            4、A Stream Socket API for C++

            參考網站:http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html

              又一個對Socket的封裝庫。

            C++各大有名庫的介紹——XML

            1、Xerces

            參考網站:http://xml.apache.org/xerces-c/

              Xerces-C++ 是一個非常健壯的XML解析器,它提供了驗證,以及SAX和DOM API。XML驗證在文檔類型定義(Document Type Definition,DTD)方面有很好的支持,并且在2001年12月增加了支持W3C XMLSchema 的基本完整的開放標準。

            2、XMLBooster

            參考網站:http://www.xmlbooster.com/

              這個庫通過產生特制的parser的辦法極大的提高了XML解析的速度,并且能夠產生相應的GUI程序來修改這個parser。在DOM和SAX兩大主流XML解析辦法之外提供了另外一個可行的解決方案。

            3、Pull Parser

            參考網站:http://www.extreme.indiana.edu/xgws/xsoap/xpp

              這個庫采用pull方法的parser。在每個SAX的parser底層都有一個pull的parser,這個xpp把這層暴露出來直接給大家使用。在要充分考慮速度的時候值得嘗試。

            4、Xalan

            參考網站:http://xml.apache.org/xalan-c/

              Xalan是一個用于把XML文檔轉換為HTML,純文本或者其他XML類型文檔的XSLT處理器。

            5、CMarkup

            參考網站:http://www.firstobject.com/xml.htm

              這是一種使用EDOM的XML解析器。在很多思路上面非常靈活實用。值得大家在DOM和SAX之外尋求一點靈感。

            6、libxml++

            http://libxmlplusplus.sourceforge.net/

              libxml++是對著名的libxml XML解析器的C++封裝版本。

            C++各大有名庫的介紹——科學計算

            1、Blitz++

            參考網站:http://www.oonumerics.org/blitz

              Blitz++ 是一個高效率的數值計算函數庫,它的設計目的是希望建立一套既具像C++ 一樣方便,同時又比Fortran速度更快的數值計算環境。通常,用C++所寫出的數值程序,比 Fortran慢20%左右,因此Blitz++正是要改掉這個缺點。方法是利用C++的template技術,程序執行甚至可以比Fortran更快。

              Blitz++目前仍在發展中,對于常見的SVD,FFTs,QMRES等常見的線性代數方法并不提供,不過使用者可以很容易地利用Blitz++所提供的函數來構建。

            2、POOMA

            參考網站:http://www.codesourcery.com/pooma/pooma

              POOMA是一個免費的高性能的C++庫,用于處理并行式科學計算。POOMA的面向對象設計方便了快速的程序開發,對并行機器進行了優化以達到最高的效率,方便在工業和研究環境中使用。

            3、MTL

            參考網站:http://www.osl.iu.edu/research/mtl

              Matrix Template Library(MTL)是一個高性能的泛型組件庫,提供了各種格式矩陣的大量線性代數方面的功能。在某些應用使用高性能編譯器的情況下,比如Intel的編譯器,從產生的匯編代碼可以看出其與手寫幾乎沒有兩樣的效能。

            4、CGAL

            參考網站:www.cgal.org

              Computational Geometry Algorithms Library的目的是把在計算幾何方面的大部分重要的解決方案和方法以C++庫的形式提供給工業和學術界的用戶。

            ================================================================

            作者說:MFC是不大漂亮的。我至今沒有這樣的認識。好像很多人這樣說,我不明白為什么,我覺得MFC是優美的,合適的。而且只要 你明白了MFC的模塊狀態、線程狀態和模塊線程狀態,明白了OLE,那么MFC就是清晰的。有些說MFC的宏不好,我不認為,ATL也像MFC一樣用宏, 而且這些宏雖不利于調試,卻是利于閱讀的。如果說MFC提供的界面元素不夠新穎,不夠豐富,我沒有任何意見,這也是BCG庫及類似的庫存在的原因。



            posted @ 2008-09-12 13:55 茶 閱讀(799) | 評論 (1)編輯 收藏

            STL vector 容器介紹

                 摘要: http://blog.csdn.net/masterlee/archive/2004/11/09/174129.aspx STL vector 容器介紹 A Presentation of the STL Vector Container (By Nitron) 翻譯 masterlee 介紹std::vector,并且討論它在STL中的算法和條件函數remove_if()。 &nbs...  閱讀全文

            posted @ 2008-09-04 17:06 茶 閱讀(1395) | 評論 (0)編輯 收藏

            vc的stdafx文件和C1083、C1010錯誤(轉)

            http://blog.csdn.net/gofishing/archive/2006/04/12/660798.aspx

            今天在改一個舊的vc6工程(為了節省空間和方便備份,以前收尾時把中間文件都刪了),整理了一下文件,歸了歸類,結果不知怎么的,工程不能編譯了,編譯 什么文件都出現 fatal error C1083: Cannot open precompiled header file: 'Debug/xxx.pch': No such file or directory, 可是我也沒刪什么文件,改程序內容,就是把文件挪了挪,看來是vc的工程有點問題,只好查查怎么回事。

            用vc新建的工程一般都有這兩個文件(空工程除外),其實如果不用mfc,這兩個根本沒用
            StdAfx.cpp 就一句#include "stdafx.h"
            StdAfx.h 包含了一些頭文件,如果沒用mfc就一句有用的#include <stdio.h>
            要 是你把哪個源文件的#include "stdafx.h"這行刪除了,或者從其他工程考過來一個文件沒有這行的,編譯時一律是 fatal error C1010: unexpected end of file while looking for precompiled header directive, 這時你只要給該文件開頭加個#include "stdafx.h"就了事。
            這兩個文件除了這點之外還有一個問題,就是這兩個文件不能從工程里刪 除,不然你編譯任何一個.cpp/.c的文件都會報 fatal error C1083: Cannot open precompiled header file: 'Debug/xxx.pch': No such file or directory, 你build也不行,vc會給每一個源文件報這樣一個錯誤。

            你再把這兩個文件加入工程,一樣不行,不論你把他們加在哪,怎么編譯就是fatal error C1083,找不到.pch文件。只有新建一個工程,然后把原來的源文件都加過去,要是工程里有很多源文件,進行了很多設置的話,可就麻煩了。

            于 是,我新建了一個工程就叫test把,看看怎么會出現fatal error C1083的。在新建一個工程后,vc在工程目錄里生成了幾個文件,包括 test.dsp(工程文件)、StdAfx.h、StdAfx.cpp。和主程序源文件test.cpp等。如果你build工程,會在相應的編譯目錄 下(一般為debug或release)產生test.pch、vc60.idb、vc60.pdb、StdAfx.obj和源程序的obj、pdb文件 和一個test.exe程序,fatal error C1083就是說沒有這個.pch文件,他也不能產生這個文件。那到底vc是怎么產生這個文件的, 又是作了什么改動使他不能再產生這個文件的呢?我們將debug目錄刪除,然后編譯test.cpp文件,結果j:\test \test.cpp(4) : fatal error C1083: Cannot open precompiled header file: 'Debug/test.pch': No such file or directory; 不行,我build:
            --------------------Configuration: test - Win32 Debug--------------------
            Compiling...
            StdAfx.cpp
            Compiling...
            test.cpp
            Linking...
            test.exe - 0 error(s), 0 warning(s)

            看 來是編譯StdAfx.cpp產生了test.pch,然后再編譯test.cpp的把;再把debug目錄刪了,編譯StdAfx.cpp就ok,看看 debug目錄:test.pch、StdAfx.obj、vc60.idb、vc60.pdb。原來是編譯StdAfx.cpp產生的pch文件,那從 工程里刪除這個文件然后在添加這個文件為什么不行呢?肯定是在在刪除/添加StdAfx.cpp文件過程中,工程文件不一樣了。先關閉工程,把 test.dsp備份,然后打開工程,刪除StdAfx.cpp文件,在添加,編譯,錯誤C1083,然后關閉工程(保存工程)。fc比較一下剛才備份的 dsp和現在的工程文件,發現原來正常的那個工程文件里在SOURCE=.\StdAfx.cpp之后多這么一 行# ADD CPP /Yc"stdafx.h",而刪了StdAfx.cpp再添加的工程就沒有,其他的就完全一樣。

            正常的dsp文件包含StdAfx.cpp的這兩行是這樣的:
            SOURCE=.\StdAfx.cpp
            # ADD CPP /Yc"stdafx.h"
            # End Source File

            后記:
            vc 真是奇怪呀,這行# ADD CPP /Yc"stdafx.h"在新建工程時有,從工程里刪除了StdAfx.cpp就沒有了,再在工程里加上這個 StdAfx.cpp就沒有加上。看似刪除再添加好像沒有動工程,誰知道他來這么一手,艾,要是懂編譯懂vc的還好,要是遇上我這樣的菜鳥,艾,只有和他 奮斗半天才把他搞得稀里糊涂。把他寫出來,免得和我一樣的菜鳥再費半天勁。

            其實這個pch文件是預編譯頭 (PreCompiled Header),下邊是msdn里關于PreCompiled Header和/Yc選項的解釋。一直都是用集成編譯環境的, 先是tc,然后是vc,沒用過make,沒寫過makefile,對編譯、連接這些東西還不是很懂,高手見笑了。這個選項是可以在工程的設置里設的,具體 可以看下邊的msdn幫助。

            /Yc  (Create Precompiled Header File)
            Home | Overview | How Do I | Compiler Options
            This option instructs the compiler to create a precompiled header (.PCH) file that represents the state of compilation at a certain point. (To find this option in the development environment, click Settings on the Project menu. Then click the C/C++ tab, and click Precompiled Headers in the Category box.) 
            Command Line Project Settings Description 
            /Yc Create Precompiled Header File The compiler compiles all code up to the end of the base source file, or to the point in the base file where #pragma hdrstop occurs.
            /Ycfilename Through Header The compiler compiles all code up to and including the .H file specified in the Through Header text box (filename).

            The precompiled code is saved in a file with a name created from the base name of the file specified with the /Yc option and a .PCH extension. You can also use the /Fp option to specify a name for the precompiled header file.
            If you use /Ycfilename (Through Header), the compiler compiles all code up to and including the specified file for subsequent use with the /Yu option. 
            Note  If the options /Ycfilename and /Yufilename occur on the same command line and both reference, or imply, the same file name, /Ycfilename, takes precedence. This feature simplifies the writing of makefiles.
            Example
            Consider the following code:
            #include <afxwin.h>  // Include header for class library
            #include "resource.h" // Include resource definitions
            #include "myapp.h"  // Include information specific to this app
            ...
            When this code is compiled with the command
            CL /YcMYAPP.H PROG.CPP
            the compiler saves all the preprocessing for AFXWIN.H, RESOURCE.H, and MYAPP.H in a precompiled header file called MYAPP.PCH.
            See Also  Creating Precompiled Header Files

            posted @ 2008-09-04 14:17 茶 閱讀(1343) | 評論 (0)編輯 收藏

            同步通信方式與異步通信方式有什么區別

            最近在看通信的接口規范,對同步通信和異步通信概念不了解。這里收集點相關資料。以后如果用到也會逐步填加。有什么不對的地方也請各位幫忙指點下。

            同步通信方式與異步通信方式有什么區別

            資料一:
            在串行通信中,由于是一位一位地進行數據傳送。為了把每個字節區別開來,需
            要收發雙方在傳送數據的串行信息流中,加入一些標記信號位。根據所添加的標記信號
            位的不同方式,分成同步通信和異步通信兩種。

                異步通信在添加標記信號位時,把所傳送的數據以字節為單位。每個字節前加上
            一位起始位,每個字節的后面加上停止位,停止位可以是1位、1.5位或2位。有時,還
            要加上一位奇偶檢驗位。

                1(起始位)+2(停止位)+1(奇偶校驗位)Κ4位標記信號位。這樣,異步通
            信方式的效率就比較低。

                同步通信是把所傳送的數據以多個字節(100字節以上)為單位,在其前后添加
            標志。

            資料二:
            異步通信”是一種很常用的通信方式。異步通信在發送字符時,所發送的字符之間的時間間隔可以是任意的。當然,接收端必須時刻做好接收的準備(如果接收端主 機的電源都沒有加上,那么發送端發送字符就沒有意義,因為接收端根本無法接收)。發送端可以在任意時刻開始發送字符,因此必須在每一個字符的開始和結束的 地方加上標志,即加上開始位和停止位,以便使接收端能夠正確地將每一個字符接收下來。異步通信的好處是通信設備簡單、便宜,但傳輸效率較低(因為開始位和 停止位的開銷所占比例較大)。
            異步通信也可以是以幀作為發送的單位。接收端必須隨時做好接收幀的準備。這是,幀的首部必須設有一些特殊的比特組合,使得接收端能夠找出一幀 的開始。這也稱為幀定界。幀定界還包含確定幀的結束位置。這有兩種方法。一種是在幀的尾部設有某種特殊的比特組合來標志幀的結束。或者在幀首部中設有幀長 度的字段。需要注意的是,在異步發送幀時,并不是說發送端對幀中的每一個字符都必須加上開始位和停止位后再發送出去,而是說,發送端可以在任意時間發送一 個幀,而幀與幀之間的時間間隔也可以是任意的。在一幀中的所有比特是連續發送的。發送端不需要在發送一幀之前和接收端進行協調(不需要先進行比特同步)。 每個字符開始發送的時間可以是任意的t0 0 1 1 0 1 1 0起始位結束位t每個幀開始發送的時間可以是任意的以字符為單位發送以幀為單位發送幀開始幀結束
            “同步通信”的通信雙方必須先建立同步,即雙方的時鐘要調整到同一個頻率。收發雙方不停地發送和接收連續的同步比特流。但這時還有兩種不同的 同步方式。一種是使用全網同步,用一個非常精確的主時鐘對全網所有結點上的時鐘進行同步。另一種是使用準同步,各結點的時鐘之間允許有微小的誤差,然后采 用其他措施實現同步傳輸。

            posted @ 2008-08-21 10:26 茶 閱讀(2077) | 評論 (0)編輯 收藏

            學習linux/unix編程方法的建議(轉)

            首先先學學編輯器,vim, emacs什么的都行。
            然后學make file文件,只要知道一點就行,這樣就可以準備編程序了。

              然后看看《C程序設計語言》K&R,這樣呢,基本上就可以進行一般的編程了,順便找本數據結構的書來看。

              如果想學習UNIX/LINUX的編程,《APUE》絕對經典的教材,加深一下功底,學習《UNP》的第二卷。這樣基本上系統方面的就可以掌握了。

              然后再看Douglus E. Comer的《用TCP/IP進行網際互連》第一卷,學習一下網絡的知識,再看《UNP》的第一卷,不僅學習網絡編程,而且對系統編程的一些常用的技巧就很熟悉了,如果繼續網絡編程,建議看《TCP/IP進行網際互連》的第三卷,里面有很多關于應用協議telnet、ftp等協議的編程。
            如果想寫設備驅動程序,首先您的系統編程的接口比如文件、IPC等必須要熟知了,再學習《LDD》2。

              對于幾本經典教材的評價:

              《The C Programing Language》K&R 經典的C語言程序設計教材,作者是C語言的發明者,教材內容****。雖然有點老,但是必備的一本手冊,現在有時候我還常翻翻。篇幅比較小,但是每看一遍,就有一遍的收獲。另外也可用譚浩強的《C語言程序設計》代替。

              《Advanced Programing in Unix Envirement》 W.Richard Stevens:也是非常經典的書(廢話,Stevens的書哪有不經典的!),雖然初學者就可以看,但是事實上它是《Unix Network Programing》的一本輔助資料。國內的翻譯的《UNIX環境高級編程》的水平不怎么樣,現在有影印版,直接讀英文比讀中文來得容易。

              《Unix Network Programing》W.Richard Stevens:第一卷講BSD Socket網絡編程接口和另外一種網絡編程接口的,不過現在一般都用BSD Socket,所以這本書只要看大約一半多就可以了。第二卷沒有設計到網絡的東西,主要講進程間通訊和Posix線程。所以看了《APUE》以后,就可以看它了,基本上系統的東西就由《APUE》和《UNP》vol2概括了。看過《UNP》以后,您就會知道系統編程的絕大部分編程技巧,即使卷一是講網絡編程的。國內是清華翻譯得《Unix網絡編程》,翻譯者得功底也比較高,翻譯地比較好。所以建議還是看中文版。

              《TCP/IP祥解》一共三卷,卷一講協議,卷二講實現,卷三講編程應用。我沒有怎么看過。,但是據說也很經典的,因為我沒有時間看卷二,所以不便評價。

              《用TCP/IP進行網際互連》Douglus.E.Comer 一共三卷,卷一講原理,卷二講實現,卷三講高級協議。感覺上這一套要比Stevens的那一套要好,就連Stevens也不得不承認它的第一卷非常經典。事實上,第一卷即使你沒有一點網絡的知識,看完以后也會對網絡的來龍去脈了如指掌。第一卷中還有很多習題也設計得經典和實用,因為作者本身就是一位教師,并且卷一是國外研究生的教材。習題并沒有答案,留給讀者思考,因為問題得答案可以讓你成為一個中級的Hacker,這些問題的答案可以象Douglus索取,不過只有他只給教師卷二我沒有怎么看,卷三可以作為參考手冊,其中地例子也很經典。如果您看過Qterm的源代碼,就會知道Qterm的telnet 實現部分大多數就是從這本書的源代碼過來的。對于網絡原理的書,我推薦它,而不是Stevens的《TCP/IP祥解》。

              《Operating System - Design and Implement》這個是講操作系統的書,用Minix做的例子。作者母語不是英文,所以英文看起來比較晦澀。國內翻譯的是《操作系統 設計與實現》,我沒看過中文版,因為翻譯者是尤晉元,他翻譯的《APUE》已經讓我失望頭頂了。讀了這本書,對操作系統的底層怎么工作的就會
            有一個清晰的認識。

              《Linux Device Driver》2e ,為數不多的關于Linux設備驅動程序的好書。不過內容有些雜亂,如果您沒有一些寫驅動的經驗,初次看會有些摸不著南北。國內翻譯的是《Linux設備驅動程序》第二版,第一版,第二版的譯者我都有很深的接觸,不過總體上來說,雖然第二版翻譯的有些不盡人意,但是相比第一版來說已經超出了一大截。要讀這一本書,至少應該先找一些《計算機原理》《計算機體系結構》的書來馬馬虎虎讀讀,至少應該對硬件和計算機的工作過程有一些了解。

            posted @ 2008-08-05 00:04 茶 閱讀(289) | 評論 (0)編輯 收藏

            教你怎樣做項目開發總結報告

            I 引言
            1.1編寫目的
              說明編寫這份項目開發總結報告的目的,指出預期的閱讀范圍。
            1.2背景
              說明:
              a.本項目的名稱和所開發出來的軟件系統的名稱;
              b.此軟件的任務提出者、開發者、用戶及安裝此軟件的計算中心。
            I.3定義
              列出本文件中用到的專門術語的定義和外文首字母組詞的原詞組。
            1.4參考資料
              列出要用到的參考資料,如:
              a.本項目的已核準的計劃任務書或合同、上級機關的批文;
              b.屬于本項目的其他已發表的文件;
              c.本文件中各處所引用的文件、資料,包括所要用到的軟件開發標準。 列出這些文件的標題、文

            件編號、發表日期和出版單位,說明能夠得到這些文件資料的來源。
            2 實際開發結果
            2.1產品
              說明最終制成的產品,包括:
              a.程序系統中各個程序的名字,它們之間的層次關系,以千字節為單位的各個程序的程序量、存儲

            媒體的形式和數量;
              b.程序系統共有哪幾個版本,各自的版本號及它們之間的區別;
              c.每個文件的名稱;
              d.所建立的每個數據庫。 如果開發中制訂過配置管理計劃,要同這個計劃相比較。
            2.2主要功能和性能
              逐項列出本軟件產品所實際具有的主要功能和性能,對照可行性研究報告、項目開發計劃、功能需

            .求說明書的有關內容,說明原定的開發目標是達到了、未完全達到、或超過了。
            2.3基本流程
              用圖給出本程序系統的實際的基本的處理流程。
            2.4進度
              列出原定計劃進度與實際進度的對比,明確說明,實際進度是提前了、還是延遲了,分析主要原因


            2.5費用
              列出原定計劃費用與實際支出費用的對比,包括:
              a.工時,以人月為單位,并按不同級別統計;
              b.計算機的使用時間,區別CPU時間及其他設備時間;
              c.物料消耗、出差費等其他支出。
              明確說明,經費是超出了、還是節余了,分析其主要原因。
            3 開發工作評價
            3.1對生產效率的評價
              給出實際生產效率,包括:
              a.程序的平均生產效率,即每人月生產的行數;
              b.文件的平均生產效率,即每人月生產的千字數;
              并列出原訂計劃數作為對比。
            3.2對產品質量的評價
              說明在測試中檢查出來的程序編制中的錯誤發生率,即每干條指令(或語句)中的錯誤指令數(或

            語句數)。如果開發中制訂過質量保證計劃或配置管理計劃,要同這些計劃相比較。
            3.3對技術方法的評價
              給出對在開發中所使用的技術、方法、工具、手段的評價。
            3.4出錯原因的分析
              給出對于開發中出現的錯誤的原因分析。
            4 經驗與教訓
              列出從這項開發工作中所得到的最主要的經驗與教訓及對今后的項目開發工作的建議。

            posted @ 2008-07-02 00:26 茶 閱讀(561) | 評論 (0)編輯 收藏

            進程間通訊的方法

            進程通常被定義為一個正在運行的程序的實例,它由兩個部分組成:
                   一個是操作系統用來管理進程的內核對象。內核對象也是系統用來存放關于進程的統計信息的地方
                  另一個是地址空間,它包含所有的可執行模塊或DLL模塊的代碼和數據。它還包含動態分配的空間。如線程堆棧和堆分配空間。每個進程被賦予它自己的虛擬地址空間,當進程中的一個線程正在運行時,該線程可以訪問只屬于它的進程的內存。屬于其它進程的內存則是隱藏的,并不能被正在運行的線程訪問。
               為了能在兩個進程之間進行通訊,由以下幾種方法可供參考:

            0。剪貼板Clipboard: 在16位時代常使用的方式,CWnd中提供支持

            1。窗口消息 標準的Windows消息以及專用的WM_COPYDATA消息 SENDMESSAGE()接收端必須有一個窗口

            2。使用共享內存方式(Shared Memory)
               a.設定一塊共享內存區域          
                 HANDLE CreateFileMapping(HANDLE,LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD,  LPCSTR)
                 產生一個file-mapping核心對象
                 LPVOID MapViewOfFile(
                     HANDLE hFileMappingObject,
                     DWORD  dwDesiredAcess,
                     DWORD  dwFileOffsetHigh,
                     DWORD  dwFileOffsetLow,
                     DWORD  dwNumberOfBytesToMap
                 );
                得到共享內存的指針
               b.找出共享內存
                決定這塊內存要以點對點(peer to peer)的形式呈現
                    每個進程都必須有相同的能力,產生共享內存并將它初始化。每個進程
                    都應該調用CreateFileMapping(),然后調用GetLastError().如果傳回的
                    錯誤代碼是ERROR_ALREADY_EXISTS,那么進程就可以假設這一共享內存區         域已經被別的進程打開并初始化了,否則該進程就可以合理的認為自己 排在第          一位,并接下來將共享內存初始化。
                還是要使用client/server架構中
                   只有server進程才應該產生并初始化共享內存。所有的進程都應該使用

            HANDLE OpenFileMapping(DWORD dwDesiredAccess,
                                               BOOL bInheritHandle,
                                               LPCTSTR lpName);
                    再調用MapViewOfFile(),取得共享內存的指針
               c.同步處理(Mutex)
               d.清理(Cleaning up) BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);
                                    CloseHandle()

            3。動態數據交換(DDE)通過維護全局分配內存使的應用程序間傳遞成為可能
               其方式是再一塊全局內存中手工放置大量的數據,然后使用窗口消息傳遞內存    指針.這是16位WIN時代使用的方式,因為在WIN32下已經沒有全局和局部內存    了,現在的內存只有一種就是虛存。  

            4。消息管道(Message Pipe)
               用于設置應用程序間的一條永久通訊通道,通過該通道可以象自己的應用程序
               訪問一個平面文件一樣讀寫數據。
               匿名管道(Anonymous Pipes)
                   單向流動,并且只能夠在同一電腦上的各個進程之間流動。
               命名管道(Named Pipes)
                   雙向,跨網絡,任何進程都可以輕易的抓住,放進管道的數據有固定的格        式,而使用ReadFile()只能讀取該大小的倍數。
                   可以被使用于I/O Completion Ports

            5   郵件槽(Mailslots)
                廣播式通信,在32系統中提供的新方法,可以在不同主機間交換數據,在        WIN9X下只支持郵件槽客戶

            6。Windows套接字(Windows Socket)
               它具備消息管道所有的功能,但遵守一套通信標準使的不同操作系統之上的應    用程序之間可以互相通信。

            7。Internet通信 它讓應用程序從Internet地址上載或下載文件

            8。RPC:遠程過程調用,很少使用,因其與UNIX的RPC不兼容。

            9。串行/并行通信(Serial/Parallel Communication)
               它允許應用程序通過串行或并行端口與其他的應用程序通信

            10。COM/DCOM
                 通過COM系統的代理存根方式進行進程間數據交換,但只能夠表現在對接口     函數的調用時傳送數據,通過DCOM可以在不同主機間傳送數據。

            posted @ 2008-07-02 00:21 茶 閱讀(365) | 評論 (0)編輯 收藏

            C/C++預處理過程與語句總結

            轉載請保留: http://www.cnscn.org(CNS電腦與英語學習網)
            Author: cnscn <http://www.cnscn.org>

            1)預處理

              根據已放置在文件中的預處理指令來修改源文件的 內容
              預處理器會分析\執行所有的預處理器指令,然后刪除他們,得到一個僅包含C++語句的轉換單元
              預處理指令以#號開頭


              常用的預處理指令:
              #include       包含頭文件

              #if               條件
              #else          否則
              #elif            否則如果
              #endif         結束條件

              #ifdef  或 #if defined        如果定義了一個符號, 就執行操作
              #ifndef 或 #if !defined      如果沒有定義一個符號, 就指執行操作

              #define        定義一個符號
              #undef         刪除一個符號

              #line            重新定義當前行號和文件名

              #error            輸出編譯錯誤 消息, 停止編譯

              #pragma        提供 機器專用的特性,同時保證與C++的完全兼容


            2)#include  在 程序中包含頭文件
             頭文件通常以.h結尾,其 內容可使用#include預處理器指令包含到 程序
             頭文件中一般包含: 函數原型與全局變量

              形式常有下面兩種
              #include <iostream>
              #include "myheader.h"

              前者<>用來引用標準庫頭文件,后者""常用來引用自定義的頭文件
              前者<>編譯器只搜索包含標準庫頭文件的默認 目錄,后者首先搜索正在編譯的源文件所在的 目錄,找不到時再搜索包含標準庫頭文件的默認 目錄.
              如果把頭文件放在其他 目錄下,為了查找到它,必須在雙引號中指定從源文件到頭文件的完整路徑


            3)#define  定義符號、宏
            1>符號
              #define PI 3.1415925  定義符號PI為3.1415925
              #define PI      取消PI的值

              這里PI看起來像一個變量,但它與變量沒有任何關系,它只是一個符號或標志,在 程序代碼編譯前,此符號會用一組指定的字符來代替
              3.14159265 不是一個數值,只是一個字符串,不會進行檢查

              在編譯前,預處理器會遍歷代碼,在它認為置換有意義的地方,用字符串PI的定義值(3.14159265)來代替
             在注釋或字符串中的PI不進行替換

              在C中常以#define來定義符號常量,但在C++中最好使用const 來定義常量
              #define PI 3.14159265
              const long double PI=3.14159265;
              兩者比較下,前者沒有類型的指定容易引起不必須的麻煩,而后者定義清楚,所以在C++中推薦使用const來定義常量

             #define的缺點:
               1)不支持類型檢查
               2)不考慮作用域
               3)符號名不能限制在一個命名 空間



            2>#undef 刪除#define定義的符號
              #define PI 3.14159265
              ... //之間所有的PI都可以被替換為3.14159265

              #undef PI
              之后不再有PI這個標識符


            3>定義宏
              #define Print(Var) count<<(Var)<<endl
              用宏名中的參數帶入語句中的參數
              宏后面沒有;號
              Print(Var)中的Print和(之間不能有空格,否則(就會被解釋為置換字符串的一部分

              #define Print(Var, digits)  count << setw(digits) << (Var) << endl
              調用
              Print(ival, 15)
              預處理器就會把它換成
              cout << setw(15) << (ival) << endl;


              所有的情況下都可以使用內聯函數來代替宏,這樣可以增強類型的檢查
              template<class T> inline void Print (const T& var, const int& digits)
              {
                  count<<setw(digits)<<var<<endl;
              }

              調用
              Print(ival, 15);


              使用宏時應注意的易引起的錯誤:
              #define max(x,y) x>y?x:y;+


              調用 result = max(myval, 99);  則換成 result = myval>99?myval:99;  這個沒有問題是正確的
              調用 result = max(myval++, 99);  則換成 result = myval++>99?myval++:99; 這樣如果myval>99那么myval就會遞增兩次,這種情況下()是沒什么用的如result=max((x),y)則 result = (myval++)>99?(myval++):99;

              再如
              #define product(m,n) m*n

              調用
              result = product(5+1,6);則替換為result = 5+1*6; 所以產生了錯誤的結果,此時應使用()把參數括起
              #define product(m,n) (m)*(n)
              則result = product(5+1,6);則替換為result = (5+1)*(6); 所以產生了錯誤的結果,此時應使用()把參數括起


            結論: 一般用內聯函數來代替預處理器宏


            技巧:
                1)給替換變量加引號
                #define MYSTR "I love you"

                cout << MYSTR ; //I love you而不是"I love you"
                如果
                cout << "MYSTR" ; //則會輸出"MYSTR"而不是"I love you"

                可以這樣做
                cout << #MYSTR ;  //則會輸出 "I love you"即cout << "\"I love you\"";

                2)在宏表達式中連接幾個參數
                如
                  #define join(a,b) ab 這樣不會理解為參數a的值與參數b的值的連接,即如join(10,999)不會理解為10999而是把ab理解為字符串,即輸出ab
                這時可以
                #define join(a,b) a##b
                  則join(10,999)就會輸出10999


            3)邏輯預處理器指令
             #if defined CALCAVERAGE 或 #ifdef CALCAVERAGE
               int count=sizeof(data)/sizeof(data[0]);
               for(int i=0; i<count; i++)
                 average += data;
               average /= count;
              #endif

              如果已經定義符號CALCAVERAGE則把#if與#endif間的語句放在要編譯的源代碼內


              防止重復引入某些頭文件
              #ifndef COMPARE_H
              #define COMPARE_H     注意: 這里只是定義一個沒有值的符號COMPARE_H, 下面的namespace compare不是COMPARE_H的 內容,這里的定義不像是定義一個常量或宏,僅僅定義一個符號,指出此符號已定義,則就會有下面的 內容namespace compare{...
               namespace compare{
                 double max(const double* data, int size);
                 double min(const double* data, int size);
               }
              #endif

              比較
              #define VERSION \
               3
              因為有換行符\ 所以上句等價于 #define VERSION 3
              由此可以看出#define COMPARE_H與namespace compare是獨立沒有關系的兩個行


              也可以這樣用
              #if defined block1 && defined block2
              ...
              #endif

              #if CPU==PENTIUM4
                ...
              #endif


              #if LANGUAGE == ENGLISH
              #define Greeting "Good Morning."
              #elif LANGUAGE == GERMAN
              #define Greeting "Guten Tag."
              #elif LANGUAGE == FRENCH
              #define Greeting "Bonjour."
              #else
              #define Greeting "Hi."
              #endif
              std::cout<<Greeting << std::endl;


              #if VERSION == 3
              ...
              #elif VERSION == 4
              ...
              #else
              ...
              #endif


            5)標準的預處理器宏
              __LINE__     當前源文件中的代碼行號,十進制整數
              __FILE__   源文件的名稱,字符串字面量
              __DATE__  源文件的處理日期,字符串字面量,格式mmm dd yyyy其中mmm是月份如Jan、Feb等 dd是01-31 yyyy是四位的年份
              __TIME__    源文件的編譯 時間,也是字符串字面量格式是hh:mm:ss
              __STDC__   這取決于實現方式,如果編譯器選項設置為編譯標準的C代碼,通常就定義它,否則就不定義它
              __cplusplus  在編譯C++ 程序時,它就定義為199711L

              使用#line可以修改__FILE__返回的字符串
              如
              #line 1000    把當前行號設置為1000
              #line 1000 "the program file"      修改__FILE__返回的字符串行號改為了1000,文件名改為了"the program file"
              #line __LINE__ "the program file"  修改__FILE__返回的字符串行號沒變,文件名改為了"the program file"

              cout << "program last complied at "<<__TIME__
                   << " on " << __DATE__
                   << endl;


            6)#error
              在預處理階段,如果出現了錯誤,則#error指令可以生成一個診斷 消息,并顯示為一個編譯錯誤,同時中止編譯
              #ifndef __cplusplus
              #error "Error -  Should be C++"
              #endif


            7)#pragma
             專門用于實現預先定義好的選項,其結果在編譯器說明文檔中進行了詳細的解釋。編譯器未識別出來的#pragma指令都會被忽略


            8)assert()宏
              在標準庫頭文件<cassert>中聲明
              用于在 程序 測試一個邏輯表達式,如果邏輯表達式為false, 則assert()會終止 程序,并顯示診斷 消息
              用于在條件不滿足就會出現重大錯誤,所以應確保后面的語句不應再繼續執行,所以它的應用非常靈活
              注意: assert不是錯誤處理 機制,邏輯表達式的結果不應產生負面效果,也不應超出 程序員的控制(如找開一個文件是否成功), 程序應提供適當的代碼來處理這種情況
             assert(expression);
              assert(expression) && assert(expression2);
              可以使用#define NDEBUG來關閉斷言 機制

              #include <iostream>
              #include <cassert>
              using std::cout;
              using std::endl;

              int main()
              {
                 int x=0;
                 int y=0;

                 cout<<endl;

                 for(x=0; x<20; x++)
                 {
                    cout<<"x= "<<x <<" y= "<<y<<endl;
                    assert(x<y); //當x>=y與x==5時,就報錯,并終止 程序的執行
                 }
                 return 0;
              }

            posted @ 2008-01-03 13:59 茶 閱讀(3553) | 評論 (1)編輯 收藏

            僅列出標題
            共4頁: 1 2 3 4 
            久久精品国产99国产精品亚洲| 欧美与黑人午夜性猛交久久久| 久久91精品综合国产首页| 91久久精品国产免费直播| 青青草原综合久久大伊人导航 | 久久精品一区二区影院| 成人久久免费网站| 国产综合精品久久亚洲| 久久亚洲精品国产亚洲老地址| 97超级碰碰碰久久久久| 一本大道久久东京热无码AV | 久久婷婷五月综合色奶水99啪 | 久久午夜羞羞影院免费观看| 国产精品99久久久久久董美香 | 久久伊人色| 久久国产精品免费一区| 久久精品免费一区二区| 国产精品热久久无码av| 无码日韩人妻精品久久蜜桃| 国内精品伊人久久久久妇| 国产精品久久久久久一区二区三区| 欧美激情精品久久久久久| 天天综合久久久网| 岛国搬运www久久| 日韩人妻无码精品久久免费一| 久久WWW免费人成—看片| 久久er国产精品免费观看2| 2022年国产精品久久久久| 久久伊人精品一区二区三区| 蜜桃麻豆www久久国产精品| 久久最近最新中文字幕大全 | 久久国产精品久久久| 午夜天堂av天堂久久久| 99精品国产综合久久久久五月天| 久久青青草原精品国产不卡| 精品国产一区二区三区久久| 国产精品99久久久久久人| 国产亚洲综合久久系列| 伊人久久大香线蕉精品| avtt天堂网久久精品| 99国产精品久久久久久久成人热|