• <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>

            xyjzsh

            c++中的位運算

            先來考考大家:

            testBitOperate()
            {
               int data =7;
               int mask = 0x8;

               int res = 1<<7;

               printf("res=%d",res);
            }
            res的結果是多少?答案:請拖到帖子最后


            今天學習了一下c++的位運算。
            按位邏輯運算符&,|,^,~,>>,<<可以應用于整形和枚舉。可以應用于
            bool char short int long ,以及它們對應的無符號的類型,以及enum。

            在此我要強調一下移位的兩個運算符>>,<<的使用。形式如:

            結果 = 要移位的數據 移位運算符 移位的個數;


            有6種位運算:
                  &       與運算
                  |       或運算
                  ^       異或運算
                  ~       非運算(求補)
                > >       右移運算
                < <       左移運算


            res的結果是:128。你打對了嗎?
            如果答對了你將獲得
            如果答錯了。在此有個不情之請,如果您答錯了,能否給我留言,讓我們在以后的日子里共同努力!!

            posted @ 2010-11-01 10:23 呆人 閱讀(1903) | 評論 (0)編輯 收藏

            c++構造函數間的調用

             

            #include <stdio.h>

            class CTest
            {
            public:
               CTest() 
            {
                 CTest(
            0);
                
            //已經調用析構函數
                 printf("CTest()\r\n");
               }

            CTest(
            int i) {
                 CTest(i, 
            0);
                
            //已經調用析構函數
                 printf("CTest(%d)\r\n", i);
            }

            CTest(
            int i, int j) {
                   printf(
            "CTest(%d, %d)\r\n", i, j);
            }

            virtual ~CTest(){
                  m_CTestCount
            ++;
                  printf(
            " ~CTest() m_CTestCount = %d\r\n", m_CTestCount);
            }

            static int m_CTestCount;
            }
            ;
            int CTest::m_CTestCount = 0;
            int main()
            {
            CTest cT;
            printf(
            "main()\r\n");
            //調用析構函數
            return 0;
            }
            調用CTest()時會產生一個臨時變量。
            如果想在構造函數間調用要用一下形式:
            class CTest2
            {
            public:
                CTest2()
                
            {
                    a
            =0;
                    b
            =0;
                }

                CTest2(
            int _a)
                
            {
                    
            this->CTest2::CTest2();
                    a 
            = _a;
                    printf(
            "in CTest2(int a) and a=%d,b=%d\n",a,b);
                }

                
            ~CTest2()
                
            {
                    printf(
            "in destrcutor and c=%d\n",c);
                }

                
            int a;
                
            int b;
                
            int static c;
            }
            ;
            注意 this->CTest2::CTest();
            建議:
            因為構造函數的特別,我們應該盡量避免構造函數間的調用
            可以采用狗仔函數默認值的方式
            以上為例:
            CTest2(int _a=0,int_b=0);
            這樣就可以省去CTest2()這個默認構造函數。

            posted @ 2010-10-29 17:11 呆人 閱讀(293) | 評論 (0)編輯 收藏

            c++中 拷貝子字符串(copy substring!!)

            實現功能:
            拷貝任意字符串的子字符串.
            使用函數:strncpy_s
            MSDN解釋:
            errno_errno_t strncpy_s(
               char *strDest,
               size_t numberOfElements,
               const char *strSource,
               size_t count
            );

            其中各個變量的含義:
            strDest:目標字符串
            numberOfElements:目標字符串的大小(以字符為單位
            strSource:源字符串
            count:要拷貝的字符串的字符數

            Demo:
            將morning拷貝到一個新的變量中

            char source[100]="good morning everyone and hope you have a good time this winter!!";
            char dest[30];
            strncpy_s(dest,
            30,source+5,7);


            對于寬字符使用如下:
            errno_t wcsncpy_s(
               wchar_t *strDest,
               size_t numberOfElements,
               const wchar_t *strSource,
               size_t count
            );

            方法二:

            void *_memccpy(
               void *dest,
               const void *src,
               int c,
               size_t count
            );
            解釋:
            c為最后一個要拷貝的字符
            count為dest中可容納的最大字符數
            功能就是將從source開始到c的字符串拷貝到新的變量中。
            void test()
            {
                
            char buffer[61];
               
            char *pdest;
                
            char string1[60= "The quicks brown dog jumps over the lazy fox";

               printf( 
            "Function: _memccpy 60 characters or to character 's'\n" );
               printf( 
            "Source: %s\n", string1 );
               pdest 
            = (char*)_memccpy( buffer, string1+4's'60 );
               
            *pdest = '\0';
               printf( 
            "Result: %s\n", buffer );
               printf( 
            "Length: %d characters\n", strlen( buffer ) );

            }

            posted @ 2010-10-25 11:23 呆人 閱讀(3622) | 評論 (0)編輯 收藏

            memcpy,_tcscpy_s的使用

            我想完成的任務:
            對于一個字符串 LPCTSTR sourceCode
            根據某些符合條件的字串subStr拷貝到一個新的字符串中。
            使用安全的拷貝函數:_tcscpy_s實際是一個宏,根據是多字節編碼或者是Unicode編碼而調用不同的函數。
            在tchar.h中我們可以找到:
            #ifdef  _UNICODE
            .......
            #define _tcscpy_s       wcscpy_s
            .......
            #else
            ....
            #define _tcscpy_s   strcpy_s
            ...
            #endif
            原型:
            _Check_return_wat_ _CRTIMP_ALTERNATIVE errno_t __cdecl wcscpy_s(_Out_z_cap_(_DstSize) wchar_t * _Dst, _In_ rsize_t _DstSize, _In_z_ const wchar_t * _Src);
            使用:
            wcscpy_s(dest,count,src);
            src不得多于count-1個字符;
            該函數最多將count-1個字符從src拷貝到dest中,然后在會在dest的字符串后面自動的加上'\0'
            其中count是字符數,而不是字節數。

            解析memcpy
            使用 void* memcpy(void* dest , const void* src, size_t count);
            特別注意這里的count指的是字節數。
            當source中的字符數<count時memcpy會在將count后面全部清零。
            但是允許拷貝count*sizeof(TCHAR)

            posted @ 2010-10-22 17:11 呆人 閱讀(12860) | 評論 (0)編輯 收藏

            c++ 中關于int,unsigned int , short的關系與應用

            int類型比較特殊,具體的字節數同機器字長和編譯器有關。如果要保證移植性,盡量用__int16 __int32 __int64吧
            __int16、__int32這種數據類型在所有平臺下都分配相同的字節。所以在移植上不存在問題。
            所謂的不可移植是指:在一個平臺上編寫的代碼無法拿到另一個平臺上運行時,不能達到期望的運行結果
            例如:在32為平臺上(所謂32位平臺是指通用寄存器的數據寬度是32)編寫代碼,int 類型分配4個字節,而在16位平臺是則分配2個字節,那么在16位上編譯出來的exe,
            其中是為int分配2字節,而在32位平臺上運行時,會按照4個字節來解析,顯然會出錯誤的!!

            而對于非int行,目前為止,所有的類型分配的字節數都是兼容的,即不同平臺對于同一個類型分配相同的字節數!!

            建議:在代碼中盡量避免使用int類型,根據不同的需要可以用short,long,unsigned int 等代替。

            下面是各個類型一覽表【轉】

            64位指的是cpu通用寄存器的數據寬度是64位的。

            數據類型名稱 字節數 別名 取值范圍
            int * signed,signed int 操作系統決定,即與操作系統的"字長"有關
            unsigned int * unsigned 由操作系統決定,即與操作系統的"字長"有關
            __int8 1 char,signed char –128 到 127
            __int16 2 short,short int,signed short int –32,768 到 32,767
            __int32 4 signed,signed int –2,147,483,648 到 2,147,483,647
            __int64 8 –9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
            bool 1 false 或 true
            char 1 signed char –128 到 127
            unsigned char 1 0 到 255
            short 2 short int,signed short int –32,768 到 32,767
            unsigned short 2 unsigned short int 0 到 65,535
            long 4 long int,signed long int –2,147,483,648 到 2,147,483,647
            long long 8 none (but equivalent to __int64) –9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
            unsigned long 4 unsigned long int 0 到 4,294,967,295
            enum * 由操作系統決定,即與操作系統的"字長"有關
            float 4 3.4E +/- 38 (7 digits)
            double 8 1.7E +/- 308 (15 digits)
            long double 8 1.7E +/- 308 (15 digits)
            wchar_t 2 __wchar_t 0 到 65,535

            類型標識符 類型說明 長度
            (字節)
            范圍 備注
            char 字符型 1 -128 ~ 127 -27 ~ (27 -1)
            unsigned char 無符字符型 1 0 ~ 255 0 ~ (28 -1)
            short int 短整型 2 -32768 ~ 32767 2-15 ~ (215 - 1)
            unsigned short int 無符短整型 2 0 ~ 65535 0 ~ (216 - 1)
            int 整型 4 -2147483648 ~ 2147483647 -231 ~ (231 - 1)
            unsigned int 無符整型 4 0 ~ 4294967295 0 ~ (232-1)
            float 實型(單精度) 4 1.18*10-38 ~ 3.40*1038 7位有效位
            double 實型(雙精度) 8 2.23*10-308 ~ 1.79*10308 15位有效位
            long double 實型(長雙精度) 10 3.37*10-4932 ~ 1.18*104932 19位有效位


            posted @ 2010-10-20 11:31 呆人 閱讀(21951) | 評論 (1)編輯 收藏

            c++中枚舉類型的使用

            一個枚舉是一個類型,它可以保存一組由用戶刻畫的值。一旦定義之后,枚舉的使用就像一個整數類型。
            enum {ASM,AUTO,BREAK};
            默認方式,枚舉符所賦得值從0開始遞增。枚舉也可以沖命名。

            posted @ 2010-10-19 13:41 呆人 閱讀(329) | 評論 (0)編輯 收藏

            c++的一些建議及圖書推薦【轉】

            第一篇

            一些同學問我,如何學好C++,我沒有別的辦法給你們,唯一的辦法就是讀書,讀大
            量的書,就可以解決。要把C++作為日常語言,而不是一種程序語言,這樣就好辦了。

            有人又要問我,那么我應該讀什么書才好?沒有時間怎么辦?

            我只能對你們說,沒時間的話,就別學C++了,做你們喜歡做的事。生活中沒有
            C++,也同樣美好。

            如果你準備學,一定要學好,那么我開個書單,應該問題不是甚大。

            首先肯定要讀一讀Bjarne Stroustrup的The Design and Evolution of C++,了解
            一下這個語言的歷史。接下來就可以看別的書了,但要不停地回頭看這本書,看到
            你不斷地學到的新技術是怎么樣一點點地被接納到這個語言中去的。

            第一本書因人而異,基礎好一些的,可以看Stanley B. Lippman的C++ Primer,這
            本書非常地巨大,你打星號的部分可以不要看。基礎不太好的,可以看Stanley B.
            Lippman的Essential C++,這本書份量要輕得多,不過四個C++的范型都講了,而
            且講得非常清楚。

            第二本應該停止技術層面的東西,靜下心來看看Pike和Kernighan的The Practice
            of Programming,好好地整理一下,在程序設計中應該有哪些注意的事項。這本
            非常薄的booklet,可以說是程序員必讀的指南。

            第三本書,就應該是Bruce Eckel寫的、候捷譯的Thinking in C++,這本書每過
            半年我就要重讀一遍。可以說每一章都是寫得發人深省的,這本書讓我感覺到了
            技術運用的非常高的境界,但是語言非常平實,只要認真地讀,即使基礎不行,
            也一定可以懂。我在教課的時候,就是用這本書(面對的學生是零基礎)。

            要更上一層的話,就要慢一步,先要把握C++設計習慣的良好。這是Scott
            Meyers的Effective C++和More Effective C++帶給我們的無盡收益。我More
            Effective C++買不起,只好花了10塊錢復印裝訂了一本"線裝本",看起來像葵花
            寶典(;-))。這兩本書是真正的經典,作者對C++的純熟,使得語言的風格讀起來
            簡直是如飴甘甜,就像他站在對面在講課。我手中有這兩本書的原版CD,如果有興
            趣,可以發E-mail到sjtu@263.net或在飲水思源投條兒給gaobo索要,只要您提供
            光盤我就給免費燒。如果你已經深刻地理解了Effective C++和More Effective
            C++,那你可以發現,你在眾人中已經是雞群之鶴。可以指導項目運作了,可以編
            寫一切你想做的程序了,可以指出別人看起來不錯的代碼的大小問題了。如果你能
            一眼看出有人的代碼是對應于"條款27"或"條款M6",那你可真是讓本人刮目了。

            我已經講了,如果要寫程序,EC++和MEC++的境界已經足以使你自如應付,可是如
            果你還不滿足,想關注一些理論層面的問題,或是想看看實現的代碼,你就不應該
            錯過這幾本好極了的書。我是說Herb Sutter的Exceptional C++和More
            Exceptional C++,這兩本書的難度是非常大的,我對每一條的閱讀筆記都是十多
            頁。特別是泛型程序設計的部分,這兩本書旁征博引,極盡深入探討之能事,每每
            看懂一條,都抹汗一次,大感酣暢淋漓;還有侯捷的 STL源碼剖析 ,以實際的
            例子一點點地講解一個STL是怎么樣實現的,我是剛開始讀,不發表評論;而
            Stanley B. Lippman,Cfront的實現者之一,執筆寫出Inside the C++ Object
            Model,我只有一個字,就是基本帥呆了。我從中了解了無數的編譯器解釋源代碼
            的細節,以及記憶體分配的細節,呵呵,這些都知道了,我還怕什么呢?最近得到
            了另一Cfront實現者、C++標準委員會Koenig的 C++沉思錄,看起來非常不錯,這
            里也推薦給大家,但我也沒看完,亦無發言權。

            最后最后,你們,未來的C++理論家們,可要記住,Bjarne Stroustrup的The C++
            Programming Language無論如何也應該讀個四五遍!這是一切C++的書本的源泉。
            如果還覺得不夠,就向C++標準委員會訂購一本C++標準。

            一切中國大陸作者的書,一概不要看(包括我的)。一切VC++或講特定的編譯器的
            書,一概不要看。如果需要補C語言的課,買一本非常小的K&R的The C
            Programming Language足矣,其它的書一概不要看。不要先學C,再學C++,而要直
            接學C++。你不是先學古文,再學白話的,對不對?所以相信我,直接來更容易。

            以上文字,皆為原創,本人愿意為每個字負責。

            第二篇

            好久未來C板了,原因這段時間一直在研究兩本書,看得自己不敢多說一句話。

            1、《Effective STL》
            訂購:http://www.cnforyou.com/query/bookdetail.asp?viBookCode=8537
            作者:Scott Meyers
            出版社:中國電力出版社
              一開始欺負這本書比較薄,想快點看完,但不久就發現自己已經翻不動了。直
            到看完最后一個字,才發現一個基本的事實:薄的不是這本書,而是自己的見識。
              有關STL的書也讀了不少,正如讀《Effective C++》以前,有關C++的書也讀了
            不少。Meyers的書總是給人一種脫胎換骨的提升感覺,他總能在大家以為老生常談
            的地方挖出意想不到的新意,并指出一些一般人習以為常的東西其實存在種種危機,
            或是在一些看來完全等價的選擇中,為特定的場合選擇最有效的(Most
            Effective)那一種。而且他的切入口總是讓人看得懂的(不像Stroustrup的書,
            第一句話就要琢磨半天),但是他總是會選擇幾個拓展點,并把它們分析得淋漓盡
            致,這時候就需要一段代碼一段代碼甚至是語句粒度地閱讀了——當然,最后總是
            看得懂,這和讀者的閱讀程度總是正比,這會給人極大的成就感。可以說,在STL
            實踐的書籍,無書可出其右(當然在STL實作方面,我還是要向大家推薦侯捷的
            《STL源碼剖析》)。
              讀完這本書后,和Pascal就產生明顯的距離感了。這里我仍然要說:請熱愛
            Delphi!我還是更愿意寫“var s:set of char;”而不是
            “set <char*, less<char*>, allocator<char*> > s”,;-)。

            2、《Modern C++ Design》
            訂購(中文):http://www.cnforyou.com/query/bookdetail.asp?viBookCode=8184
            訂購(影印):http://www.cnforyou.com/query/bookdetail.asp?viBookCode=8319
            作者:Andrei Alexandrescu
            譯者:侯捷、於春景
            出版社:華中科技大學出版社(中文)
                中國電力出版社(影印)
              讀完這本書的第一頁,我就知道自己放不下它了,但我也知道,我的苦難經歷
            又要多上一筆了。用C++實作設計模式,已經是骨灰級的難度,但這本書明顯還在講
            一個template的對象模型的問題,這在我讀《Inside the C++ Object Model》時是
            屢攻不下的難點。不過,出乎意料的是這本書居然使我具有一些概念了,而且動手寫
            出了一個SmartPointer。
              這本書我還遠不能說我讀懂了,但是確乎是讀完了。如果你還沒有讀過對象模型
            和設計模式的書,我認為需要讀一讀。否則,直接看這本書根本就是受罪。最近,有
            一些朋友也注意到設計模式的重要性了,可能從明年起我在《電腦報》上要發表一些
            文章,屆時請朋友們指教吧。

            另外就是Effective C++點評繼續寫,我現在覺得更惶恐,但是信心也更足了。
            --
            La cinquième planète était très curieuse.
            C'était la plus petite de toutes.
            Il y avait là juste assez de place pour loger un réverbère et un allumeur de
            réverbères. le petit prince ne parvenait pas à s'expliquer à quoi pouvaient
            servir, quelque part dans le ciel, sur une planète sans maison, ni population,
            un réverbère et un allumeur de réverbères.

            posted @ 2010-10-19 09:36 呆人 閱讀(365) | 評論 (1)編輯 收藏

            1.VC++中的char,wchar_t,TCHAR(轉載)

            總體簡介:
            由于字符編碼的不同,在C++中有三種對于字符類型:char, wchar_t , TCHAR。其實TCHAR不能算作一種類型,他緊緊是一個宏。我們都知道,宏在預編譯的時候會被替換成相應的內容。TCHAR 在使用多字節編碼時被定義成char,在Unicode編碼時定義成wchar_t。

            1.VC++中的char,wchar_t,TCHAR
            大家一起做一個項目,經常發現有的人愛用strcpy等標準ANSI函數,有的人愛用_tXXXX函數,這個問題曾經搞的很混亂。為了統一,有必要把來龍去脈搞清楚。

             為了搞清這些函數,就必須理請幾種字符類型的寫法。char就不用說了,先說一些wchar_t。wchar_t是Unicode字符的數據類型,它實際定義在<string.h>里:
             typedef unsigned short wchar_t;
            不能使用類似 strcpy這樣的ANSI C字符串函數來處理wchar_t字符串,必須使用wcs前綴的函數,例如wcscpy。為了讓編譯器識別Unicode字符串,必須以在前面加一個 “L”,例如:
             wchar_t *szTest=L"This is a Unicode string.";

             下面在看看TCHAR。如果你希望同時為ANSI和Unicode編譯的源代碼,那就要include TChar.h。TCHAR是定義在其中的一個宏,它視你是否定義了_UNICODE宏而定義成char或者wchar_t。如果你使用了TCHAR,那么就不應該使用ANSI的strXXX函數或者Unicode的wcsXXX函數了,而必須使用TChar.h中定義的_tcsXXX函數。另外,為了解決剛才提到帶“L”的問題,TChar.h中定義了一個宏:“_TEXT”。

             以strcpy函數為例子,總結一下:
             .如果你想使用ANSI字符串,那么請使用這一套寫法:
             char szString[100];
             strcpy(szString,"test");
             .如果你想使用Unicode字符串,那么請使用這一套:
             wchar_t szString[100];
             wcscpyszString,L"test");
             .如果你想通過定義_UNICODE宏,而編譯ANSI或者Unicode字符串代碼:
             TCHAR szString[100];
             _tcscpy(szString,_TEXT("test"));

            2.字符串及處理之三: 使用TCHAR系列方案
            使用TCHAR系列方案編寫程序
              TCHAR是一種字符串類型,它讓你在以MBCS和UNNICODE來build程序時可以使用同樣的代碼,不需要使用繁瑣的宏定義來包含你的代碼。 
                  TCHAR的引入,主要是在Tchar.h文件中,該文件包含這方面的重要的定義信息。
                  對于包含了對str函數或wcs函數進行顯式調用的代碼來說,無法非常容易地同時為ANSI和Unicode對這些代碼進行編譯。本章前面說過,可以創建同時為ANSI和Unicode進行編譯的單個源代碼文件。若要建立雙重功能,必須包含TChar.h文件,而不是包含String.h文件。
                  TChar.h文件的唯一作用是幫助創建ANSI/Unicode通用源代碼文件。它包含你應該用在源代碼中的一組宏,而不應該直接調用str函數或者 wcs函數。如果在編譯源代碼文件時定義了_UNICODE,這些宏就會引用wcs這組函數。如果沒有定義_UNICODE,那么這些宏將引用str這組宏。
                  TCHAR的定義如下:
                  #ifdef UNICODE
                  typedef wchar_t TCHAR;
                  #else
                  typedef char TCHAR;
                  #endif
                  所以用MBCS來build時,TCHAR是char,使用UNICODE時,TCHAR是wchar_t。
                  還有一個宏來處理定義Unicode字符串常量時所需的L前綴。
                  #ifdef UNICODE
                  #define _T(x) L##x
                  #define _TEXT(x) L##x
                  #define __T(x) L##x
                  #else
                  #define _T(x) x
                  #define _TEXT(x) x
                  #define __T(x) x
                  #endif
                 ## 是一個預處理操作符,它可以把兩個參數連在一起。如果你的代碼中需要字符串常量,在它前面加上_T宏。如果你使用Unicode來build,它會在字符串常量前加上L前綴。
                  TCHAR szNewText[] = _T("we love Bob!");
                _UNICODE宏用于C運行期頭文件,而UNICODE宏則用于Windows頭文件。當編譯源代碼模塊時,通常必須同時定義這兩個宏。
              像是用宏來隱藏SetWindowTextA/W的細節一樣,還有很多可以供你使用的宏來實現str***()和_mbs***()等字符串函數。例如,你可以使用_tcsrchr宏來替換strrchr()、_mbsrchr()和wcsrchr()。_tcsrchr根據你預定義的宏是_MBCS還是 UNICODE來擴展成正確的函數,就象SetWindowText所作的一樣。
               不僅str***()函數有TCHAR宏。其他的函數如, _stprintf(代替sprinft()和swprintf()),_tfopen(代替fopen()和_wfopen())。 MSDN中"Generic-Text Routine Mappings."標題下有完整的宏列表。

            3.字符串及處理之二: 基本字符串類型及函數
            常用的字符串類型有:char * ,wchar_t * ,WCHAR * , TCHAR *
            char *
                最基本的類型,其對應的一組處理函數是以str...開頭的標準的ANSI C字符串函數。
            wchar_t *
                是這樣定義的:typedef unsigned short wchar_t;
                另外,在頭文件中有這樣的定義:typedef wchar_t WCHAR; 所以WCHAR實際就是wchar_t
                wchar_t * 是16-bit UNICODE character(寬字符)所使用的基本類型。
            其對應的一組處理函數是以wcs...開頭的標準的字符串函數。

            常用的字符串處理函數和宏:
            1、str 開頭的 函數 處理SBCS字符串
            2、wcs 開頭的 函數 處理寬字符串,wcs是寬字符串的英文縮寫
                所有的unicode函數均以wcs開頭。若要調用Unicode函數,只需用前綴wcs來取代ANSI字符串函數的前綴str即可。
                對于每一個標準的ANSI C字符串函數,基本都有等價的unicode函數.
            3、_mbs 開頭的 函數 處理DBCS字符串
                微軟還在它的CRT(C runtime library)中增加了操作DBCS字符串的版本。Str***()函數都有對應名字的DBCS版本_mbs***()。
                如果你料到可能會遇到DBCS字符串(如果你的軟件會被安裝在使用DBCS編碼的國家,如中國,日本等,你就可能會),你應該使用_mbs***()函數,因為他們也可以處理SBCS字符串。(一個DBCS字符串也可能含有單字節字符,這就是為什么_mbs***()函數也能處理SBCS字符串的原因)。微軟還提供了幾個函數方便對dbcs的處理 , 見后面的描述。
                如果只是調用strlen函數,那么你無法真正了解字符串中究竟有多少字符,它只能告訴你到達結尾的0之前有多少個字節。ANSI的C運行期庫中沒有配備相應的函數,使你能夠對雙字節字符集進行操作。但是,Microsoft Visual C++的運行期庫卻包含許多函數,如_mbslen ,它可以用來操作多字節(既包括單字節也包括雙字節)字符串。
            4、_tcs 開頭的 宏 配合TCHAR使用
                根據預定義分別擴展為str wcs _mbs, 見后面的描述。
            5、l開頭的windows自帶的寬字符處理函數
            6、大小寫兼有的 windows自帶的寬字符處理函數

                5和6見后面的描述
            更進一步的字符串以及其指針的類型定義

             由于Win32 API文檔的函數列表使用函數的常用名字(例如, "SetWindowText"),所有的字符串都是用TCHAR來定義的。(除了XP中引入的只適用于Unicode的API)。下面列出一些常用的 typedefs,你可以在msdn中看到他們。
            type                Meaning in MBCS builds          Meaning in Unicode builds
            WCHAR                 wchar_t                             wchar_t
            LPSTR                   char*                                char*
            LPCSTR                 const char*                        const char*
            LPWSTR                wchar_t*                           wchar_t*
            LPCWSTR              const wchar_t*                    const wchar_t* 
            TCHAR                  char                                  wchar_t
            LPTSTR                 TCHAR*                            TCHAR*
            LPCTSTR               const TCHAR*                     const TCHAR*

            4.strings(字符串)詳解(一)
            之所以拋棄char*的字符串而選用C++標準程序庫中的string類,是因為他和前者比較起來,不必擔心內存是否足夠、字符串長度等等,而且作為一個類出現,他集成的操作函數足以完成我們大多數情況下(甚至是100%)的需要。我們可以用 = 進行賦值操作,== 進行比較,+ 做串聯(是不是很簡單?)。我們盡可以把它看成是C++的基本數據類型。
                好了,進入正題………
            首先,為了在我們的程序中使用 string類型,我們必須包含頭文件 <string>。如下:
                #include <string> //注意這里不是string.h string.h是C字符串頭文件

            1.聲明一個C++字符串
            聲明一個字符串變量很簡單:
                string Str;
            這樣我們就聲明了一個字符串變量,但既然是一個類,就有構造函數和析構函數。上面的聲明沒有傳入參數,所以就直接使用了string的默認的構造函數,這個函數所作的就是把Str初始化為一個空字符串。String類的構造函數和析構函數如下:
            a)    string s;  //生成一個空字符串s
            b)    string s(str) //拷貝構造函數 生成str的復制品
            c)    string s(str,stridx) //將字符串str內“始于位置stridx”的部分當作字符串的初值
            d)    string s(str,stridx,strlen) //將字符串str內“始于stridx且長度頂多strlen”的部分作為字符串的初值
            e)    string s(cstr) //將C字符串作為s的初值
            f)    string s(chars,chars_len) //將C字符串前chars_len個字符作為字符串s的初值。
            g)    string s(num,c) //生成一個字符串,包含num個c字符
            h)    string s(beg,end) //以區間beg;end(不包含end)內的字符作為字符串s的初值
            i)    s.~string() //銷毀所有字符,釋放內存
            都很簡單,我就不解釋了。
            2.字符串操作函數
                這里是C++字符串的重點,我先把各種操作函數羅列出來,不喜歡把所有函數都看完的人可以在這里找自己喜歡的函數,再到后面看他的詳細解釋。
            a) =,assign()   //賦以新值
            b) swap()   //交換兩個字符串的內容
            c) +=,append(),push_back() //在尾部添加字符
            d) insert() //插入字符
            e) erase() //刪除字符
            f) clear() //刪除全部字符
            g) replace() //替換字符
            h) + //串聯字符串
            i) ==,!=,<,<=,>,>=,compare()  //比較字符串
            j) size(),length()  //返回字符數量
            k) max_size() //返回字符的可能最大個數
            l) empty()  //判斷字符串是否為空
            m) capacity() //返回重新分配之前的字符容量
            n) reserve() //保留一定量內存以容納一定數量的字符
            o) [ ], at() //存取單一字符
            p) >>,getline() //從stream讀取某值
            q) <<  //將謀值寫入stream
            r) copy() //將某值賦值為一個C_string
            s) c_str() //將內容以C_string返回
            t) data() //將內容以字符數組形式返回
            u) substr() //返回某個子字符串
            v)查找函數
            w)begin() end() //提供類似STL的迭代器支持
            x) rbegin() rend() //逆向迭代器
            y) get_allocator() //返回配置器
            下面詳細介紹:
            2.1 C++字符串和C字符串的轉換
                C++提供的由C++字符串得到對應的 C_string的方法是使用data()、c_str()和copy(),其中,data()以字符數組的形式返回字符串內容,但并不添加’\0’。 c_str()返回一個以‘\0’結尾的字符數組,而copy()則把字符串的內容復制或寫入既有的c_string或字符數組內。C++字符串并不以’ \0’結尾。我的建議是在程序中能使用C++字符串就使用,除非萬不得已不選用c_string。由于只是簡單介紹,詳細介紹掠過,誰想進一步了解使用中的注意事項可以給我留言(到我的收件箱)。我詳細解釋。
            2.2 大小和容量函數
                一個C++字符串存在三種大小:a)現有的字符數,函數是size()和length(),他們等效。Empty()用來檢查字符串是否為空。b)max_size() 這個大小是指當前C++字符串最多能包含的字符數,很可能和機器本身的限制或者字符串所在位置連續內存的大小有關系。我們一般情況下不用關心他,應該大小足夠我們用的。但是不夠用的話,會拋出length_error異常c)capacity()重新分配內存之前 string所能包含的最大字符數。這里另一個需要指出的是reserve()函數,這個函數為string重新分配內存。重新分配的大小由其參數決定,默認參數為0,這時候會對string進行非強制性縮減。

            還有必要再重復一下C++字符串和C字符串轉換的問題,許多人會遇到這樣的問題,自己做的程序要調用別人的函數、類什么的(比如數據庫連接函數Connect(char*,char*)),但別人的函數參數用的是char*形式的,而我們知道,c_str()、data()返回的字符數組由該字符串擁有,所以是一種const char*,要想作為上面提及的函數的參數,還必須拷貝到一個char*,而我們的原則是能不使用C字符串就不使用。那么,這時候我們的處理方式是:如果此函數對參數(也就是char*)的內容不修改的話,我們可以這樣Connect((char*)UserID.c_str(), (char*)PassWD.c_str()),但是這時候是存在危險的,因為這樣轉換后的字符串其實是可以修改的(有興趣地可以自己試一試),所以我強調除非函數調用的時候不對參數進行修改,否則必須拷貝到一個char*上去。當然,更穩妥的辦法是無論什么情況都拷貝到一個char*上去。同時我們也祈禱現在仍然使用C字符串進行編程的高手們(說他們是高手一點兒也不為過,也許在我們還穿開襠褲的時候他們就開始編程了,哈哈…)寫的函數都比較規范,那樣我們就不必進行強制轉換了。

            2.3元素存取
                我們可以使用下標操作符[]和函數at()對元素包含的字符進行訪問。但是應該注意的是操作符[]并不檢查索引是否有效(有效索引0~str.length()),如果索引失效,會引起未定義的行為。而at()會檢查,如果使用 at()的時候索引無效,會拋出out_of_range異常。
                有一個例外不得不說,const string a;的操作符[]對索引值是a.length()仍然有效,其返回值是’\0’。其他的各種情況,a.length()索引都是無效的。舉例如下:
            const string Cstr(“const string”);
            string Str(“string”);

            Str[3];    //ok
            Str.at(3);  //ok

            Str[100]; //未定義的行為
            Str.at(100);  //throw out_of_range

            Str[Str.length()]  // 未定義行為
            Cstr[Cstr.length()] //返回 ‘\0’
            Str.at(Str.length());//throw out_of_range
            Cstr.at(Cstr.length()) ////throw out_of_range

            我不贊成類似于下面的引用或指針賦值:
            char& r=s[2];
            char* p= &s[3];
            因為一旦發生重新分配,r,p立即失效。避免的方法就是不使用。

            2.4比較函數
                C++字符串支持常見的比較操作符(>,>=,<,<=,==,!=),甚至支持string與C-string的比較(如 str<”hello”)。在使用>,>=,<,<=這些操作符的時候是根據“當前字符特性”將字符按字典順序進行逐一得比較。字典排序靠前的字符小,比較的順序是從前向后比較,遇到不相等的字符就按這個位置上的兩個字符的比較結果確定兩個字符串的大小。同時,string(“aaaa”) <string(aaaaa)。
                另一個功能強大的比較函數是成員函數compare()。他支持多參數處理,支持用索引值和長度定位子串來進行比較。他返回一個整數來表示比較結果,返回值意義如下:0-相等 〉0-大于 <0-小于。舉例如下:
                string s(“abcd”);
                
                s.compare(“abcd”); //返回0
                s.compare(“dcba”); //返回一個小于0的值
                s.compare(“ab”); //返回大于0的值
                
            s.compare(s); //相等
                s.compare(0,2,s,2,2); //用”ab”和”cd”進行比較 小于零
                s.compare(1,2,”bcx”,2); //用”bc”和”bc”比較。
            怎么樣?功能夠全的吧!什么?還不能滿足你的胃口?好吧,那等著,后面有更個性化的比較算法。先給個提示,使用的是STL的比較算法。什么?對STL一竅不通?靠,你重修吧!

            2.5 更改內容
            這在字符串的操作中占了很大一部分。
            首先講賦值,第一個賦值方法當然是使用操作符=,新值可以是string(如:s=ns) 、c_string(如:s=”gaint”)甚至單一字符(如:s=’j’)。還可以使用成員函數assign(),這個成員函數可以使你更靈活的對字符串賦值。還是舉例說明吧:
            s.assign(str); //不說
            s.assign(str,1,3);//如果str 是”iamangel” 就是把”ama”賦給字符串
            s.assign(str,2,string::npos);//把字符串str從索引值2 開始到結尾賦給s
            s.assign(“gaint”); //不說
            s.assign(“nico”,5);//把’n’ ‘I’ ‘c’ ‘o’ ‘\0’賦給字符串
            s.assign(5,’x’);//把五個x賦給字符串
            把字符串清空的方法有三個:s=””; s.clear();s.erase();(我越來越覺得舉例比說話讓別人容易懂!)。
            string提供了很多函數用于插入(insert)、刪除(erase)、替換(replace)、增加字符。
            先說增加字符(這里說的增加是在尾巴上),函數有 +=、append()、push_back()。舉例如下:
            s+=str;//加個字符串
            s+=”my name is jiayp”;//加個C字符串
            s+=’a’;//加個字符

            s.append(str);
            s.append(str,1,3);// 不解釋了 同前面的函數參數assign的解釋
            s.append(str,2,string::npos)//不解釋了

            s.append(“my name is jiayp”);
            s.append(“nico”,5);
            s.append(5,’x’);

            s.push_back(‘a’);// 這個函數只能增加單個字符 對STL熟悉的理解起來很簡單

            也許你需要在string中間的某個位置插入字符串,這時候你可以用 insert()函數,這個函數需要你指定一個安插位置的索引,被插入的字符串將放在這個索引的后面。
                s.insert(0,”my name”);
                s.insert(1,str);
            這種形式的insert()函數不支持傳入單個字符,這時的單個字符必須寫成字符串形式(讓人惡心)。既然你覺得惡心,那就不得不繼續讀下面一段話:為了插入單個字符,insert()函數提供了兩個對插入單個字符操作的重載函數:insert(size_type index,size_type num,chart c)和insert(iterator pos,size_type num,chart c)。其中size_type是無符號整數,iterator是char*,所以,你這么調用insert函數是不行的:insert(0,1,’j’);這時候第一個參數將轉換成哪一個呢?所以你必須這么寫:insert((string::size_type)0,1,’j’)!第二種形式指出了使用迭代器安插字符的形式,在后面會提及。順便提一下,string有很多操作是使用STL的迭代器的,他也盡量做得和STL靠近。
            刪除函數erase()的形式也有好幾種(真煩!),替換函數 replace()也有好幾個。舉例吧:
            string s=”il8n”;
            s.replace(1,2,”nternationalizatio”);// 從索引1開始的2個替換成后面的C_string
            s.erase(13);//從索引13開始往后全刪除
            s.erase(7,5);// 從索引7開始往后刪5個

            2.6提取子串和字符串連接

            題取子串的函數是:substr(),形式如下:
            s.substr();// 返回s的全部內容
            s.substr(11);//從索引11往后的子串
            s.substr(5,6);//從索引5開始6個字符
            把兩個字符串結合起來的函數是+。(誰不明白請致電120)

            2.7輸入輸出操作
            1.>> 從輸入流讀取一個string。
            2.<< 把一個string寫入輸出流。
            另一個函數就是getline(),他從輸入流讀取一行內容,直到遇到分行符或到了文件尾。

            2.8搜索與查找
            查找函數很多,功能也很強大,包括了:
                find()
                rfind()
                find_first_of()
                find_last_of()
                find_first_not_of()
                find_last_not_of()
            這些函數返回符合搜索條件的字符區間內的第一個字符的索引,沒找到目標就返回npos。所有的函數的參數說明如下:
            第一個參數是被搜尋的對象。第二個參數(可有可無)指出string內的搜尋起點索引,第三個參數(可有可無)指出搜尋的字符個數。比較簡單,不多說 不理解的可以向我提出,我再仔細的解答。當然,更加強大的STL搜尋在后面會有提及。
            最后再說說npos的含義,string::npos的類型是string::size_type,所以,一旦需要把一個索引與npos相比,這個索引值必須是string::size)type類型的,更多的情況下,我們可以直接把函數和npos進行比較(如:if(s.find(“jia”)==string::npos))。
                第二部分是關于 C++字符串對迭代器的支持的,視大家的需要我將寫出來(意思就是不需要就算了,我樂得輕省,哈哈…)。
            好了,大概的對string類型進行了闡述,希望起到拋磚引玉的作用,讓初學者對string有個了解而不必已開始就面對復雜的內部結構和無數個注意事項。對字符串更詳細地講解有很多參考書,其實我的內容也是從C++標準程序庫得來的,加上幾句自己的看法,所以要感謝這本書的作者和譯者。任何人對本文進行引用都要標明作者是Nicolai M.Josuttis 譯者是侯捷/孟巖。不過不要提及我,任何觀點的錯誤都與我無關(除了這里邊體現我主觀想法的幾句話,也就那幾句話)。

            posted @ 2010-10-15 16:30 呆人 閱讀(8472) | 評論 (0)編輯 收藏

            編譯項目跟蹤文檔(1)

            最近要做一個簡易的編譯器,第一個版本幾乎是裸寫出來的,到了后期連我自己都不知道如何收場,這讓我很是惱火。第一個版本帶給我主要是教訓,但也有小小的成果。為了讓自己又更清晰地思路,在第二個版本開始之際,我將把主要思想和代碼記錄下來和大家分享。希望大家能提出寶貴的意見。

            posted @ 2010-10-14 13:44 呆人 閱讀(149) | 評論 (0)編輯 收藏

            僅列出標題
            共6頁: 1 2 3 4 5 6 
            <2011年5月>
            24252627282930
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            導航

            統計

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品成人久久久| 99久久免费国产精精品| 国产福利电影一区二区三区久久久久成人精品综合 | 欧美午夜精品久久久久免费视 | 蜜桃麻豆WWW久久囤产精品| 国产精品美女久久久免费| 久久亚洲美女精品国产精品| 色狠狠久久AV五月综合| 久久久久人妻精品一区 | 精品久久久久中文字幕日本| 国产三级观看久久| 久久久久亚洲AV无码专区体验| 蜜臀av性久久久久蜜臀aⅴ| 久久精品国产亚洲AV电影| www.久久热.com| 亚洲色欲久久久综合网东京热| 久久国产成人| 日本福利片国产午夜久久| 久久99久久99小草精品免视看 | 国产精品美女久久久久AV福利| 中文成人久久久久影院免费观看| 国产亚洲综合久久系列| 婷婷久久五月天| 亚洲欧洲久久av| segui久久国产精品| 久久99精品久久久久久9蜜桃 | 亚洲AV无码久久精品色欲| 久久亚洲综合色一区二区三区| 午夜精品久久久久久久无码| 国产精品久久久福利| 久久人人爽人人爽人人片AV东京热| 97久久国产综合精品女不卡| 国产精品中文久久久久久久| 一本色道久久88综合日韩精品 | 久久综合九色综合欧美就去吻| 欧美久久精品一级c片片| 中文精品99久久国产| 91久久国产视频| 亚洲一区中文字幕久久| 国产精品久久网| 久久青青草原综合伊人|