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

            指針問(wèn)題
            信息來(lái)源:網(wǎng)絡(luò)


            譯者序:

              這是一篇我所見過(guò)的關(guān)于指針的最好的入門級(jí)文章,它可使初學(xué)者在很短的時(shí)間內(nèi)掌握復(fù)雜的指針操作。雖然,現(xiàn)在的JAVA、C#等語(yǔ)言已經(jīng)取消了指針,但作為一個(gè)C++程序員,指針的直接操作內(nèi)存,在數(shù)據(jù)操作方面有著速度快,節(jié)約內(nèi)存等優(yōu)點(diǎn),仍是很多C++程序員的最愛。指針就像是一把良劍,就看你怎么去應(yīng)用它!
              有關(guān)這篇文章的技術(shù)性問(wèn)題你可以寫信給我:webmaster@chinahai.com.同時(shí)我的另外兩篇相關(guān)文章《模板Guide》和《STL Guide》也快完成,希望能對(duì)您有所幫助!Loading... ...

            譯者:萬(wàn)江(chinahai)


            什么是指針?

              其實(shí)指針就像是其它變量一樣,所不同的是一般的變量包含的是實(shí)際的真實(shí)的數(shù)據(jù),而指針是一個(gè)指示器,它告訴程序在內(nèi)存的哪塊區(qū)域可以找到數(shù)據(jù)。這是一個(gè)非常重要的概念,有很多程序和算法都是圍繞指針而設(shè)計(jì)的,如鏈表。


            開始學(xué)習(xí)

              如何定義一個(gè)指針呢?就像你定義一個(gè)其它變量一樣,只不過(guò)你要在指針名字前加上一個(gè)星號(hào)。我們來(lái)看一個(gè)例子:
              下面這個(gè)程序定義了兩個(gè)指針,它們都是指向整型數(shù)據(jù)。


            int* pNumberOne;
            int* pNumberTwo;

              你注意到在兩個(gè)變量名前的“p”前綴了嗎?這是程序員通常在定義指針時(shí)的一個(gè)習(xí)慣,以提高便程序的閱讀性,表示這是個(gè)指針?,F(xiàn)在讓我們來(lái)初始化這兩個(gè)指針:
            pNumberOne = &some_number;
            pNumberTwo = &some_other_number;
              &號(hào)讀作“什么的地址”,它表示返回的是變量在內(nèi)存中的地址而不是變量本身的值。在這個(gè)例子中,pNumberOne 等于some_number的地址,所以現(xiàn)在pNumberOne指向some_number。 如果現(xiàn)在我們?cè)诔绦蛑幸玫絪ome_number,我們就可以使用pNumberOne。


            我們來(lái)學(xué)習(xí)一個(gè)例子:

              在這個(gè)例子中你將學(xué)到很多,如果你對(duì)指針的概念一點(diǎn)都不了解,我建議你多看幾遍這個(gè)例子,指針是個(gè)很復(fù)雜的東西,但你會(huì)很快掌握它的。
              這個(gè)例子用以增強(qiáng)你對(duì)上面所介紹內(nèi)容的了解。它是用C編寫的(注:原英文版是用C寫的代碼,譯者重新用C++改寫寫了所有代碼,并在DEV C++ 和VC++中編譯通過(guò)?。?br>

            #include <iostream.h>

            void main()
            {
            // 聲明變量:
            int nNumber;
            int *pPointer;


            // 現(xiàn)在給它們賦值:
            nNumber = 15;
            pPointer = &nNumber;

            //打印出變量nNumber的值:
            cout<<"nNumber is equal to :"<< nNumber<<endl;

            // 現(xiàn)在通過(guò)指針改變nNumber的值:
            *pPointer = 25;

            //證明nNumber已經(jīng)被上面的程序改變
            //重新打印出nNumber的值:
            cout<<"nNumber is equal to :"<<nNumber<<endl;
            }

              通讀一下這個(gè)程序,編譯并運(yùn)行它,務(wù)必明白它是怎樣工作的。如果你完成了,準(zhǔn)備好,開始下一小節(jié)。


            陷井!

              試一下,你能找出下面這段程序的錯(cuò)誤嗎?

            #include <iostream.h>

            int *pPointer;

            void SomeFunction();
            {
            int nNumber;
            nNumber = 25;


            //讓指針指向nNumber:
            pPointer = &nNumber;
            }

            void main()
            {
            SomeFunction(); //為pPointer賦值

            //為什么這里失敗了?為什么沒有得到25
            cout<<"Value of *pPointer: "<<*pPointer<<endl;
            }

              這段程序先調(diào)用了SomeFunction函數(shù),創(chuàng)建了個(gè)叫nNumber的變量,接著讓指針pPointer指向了它??墒菃?wèn)題出在哪兒呢?當(dāng)函數(shù)結(jié)束后,nNumber被刪掉了,因?yàn)檫@一個(gè)局部變量。局部變量在定義它的函數(shù)執(zhí)行完后都會(huì)被系統(tǒng)自動(dòng)刪掉。也就是說(shuō)當(dāng)SomeFunction 函數(shù)返回主函數(shù)main()時(shí),這個(gè)變量已經(jīng)被刪掉,但pPointer還指著變量曾經(jīng)用過(guò)的但現(xiàn)在已不屬于這個(gè)程序的區(qū)域。如果你還不明白,你可以再讀讀這個(gè)程序,注意它的局部變量和全局變量,這些概念都非常重要。
              但這個(gè)問(wèn)題怎么解決呢?答案是動(dòng)態(tài)分配技術(shù)。注意這在C和C++中是不同的。由于大多數(shù)程序員都是用C++,所以我用到的是C++中常用的稱謂。


            動(dòng)態(tài)分配

              動(dòng)態(tài)分配是指針的關(guān)鍵技術(shù)。它是用來(lái)在不必定義變量的情況下分配內(nèi)存和讓指針去指向它們。盡管這么說(shuō)可能會(huì)讓你迷惑,其實(shí)它真的很簡(jiǎn)單。下面的代碼就是一個(gè)為一個(gè)整型數(shù)據(jù)分配內(nèi)存的例子:
            int *pNumber;
            pNumber = new int;
              第一行聲明一個(gè)指針pNumber。第二行為一個(gè)整型數(shù)據(jù)分配一個(gè)內(nèi)存空間,并讓pNumber指向這個(gè)新內(nèi)存空間。下面是一個(gè)新例,這一次是用double雙精型:
            double *pDouble;
            pDouble = new double;
              這種格式是一個(gè)規(guī)則,這樣寫你是不會(huì)錯(cuò)的。
              但動(dòng)態(tài)分配又和前面的例子有什么不同呢?就是在函數(shù)返回或執(zhí)行完畢時(shí),你分配的這塊內(nèi)存區(qū)域是不會(huì)被刪除的所以我們現(xiàn)在可以用動(dòng)態(tài)分配重寫上面的程序:
            #include <iostream.h>

            int *pPointer;

            void SomeFunction()
            {
            // 讓指針指向一個(gè)新的整型
            pPointer = new int;
            *pPointer = 25;
            }

            void main()
            {
            SomeFunction(); // 為pPointer賦值

            cout<<"Value of *pPointer: "<<*pPointer<<endl;
            }
              通讀這個(gè)程序,編譯并運(yùn)行它,務(wù)必理解它是怎樣工作的。當(dāng)SomeFunction 調(diào)用時(shí),它分配了一個(gè)內(nèi)存,并讓pPointer指向它。這一次,當(dāng)函數(shù)返回時(shí),新的內(nèi)存區(qū)域被保留下來(lái),所以pPointer始終指著有用的信息,這是因?yàn)榱藙?dòng)態(tài)分配。但是你再仔細(xì)讀讀上面這個(gè)程序,雖然它得到了正確結(jié)果,可仍有一個(gè)嚴(yán)重的錯(cuò)誤。


            分配了內(nèi)存,別忘了回收

              太復(fù)雜了,怎么會(huì)還有嚴(yán)重的錯(cuò)誤!其實(shí)要改正并不難。問(wèn)題是:你動(dòng)態(tài)地分配了一個(gè)內(nèi)存空間,可它絕不會(huì)被自動(dòng)刪除。也就是說(shuō),這塊內(nèi)存空間會(huì)一直存在,直到你告訴電腦你已經(jīng)使用完了??山Y(jié)果是,你并沒有告訴電腦你已不再需要這塊內(nèi)存空間了,所以它會(huì)繼續(xù)占據(jù)著內(nèi)存空間造成浪費(fèi),甚至你的程序運(yùn)行完畢,其它程序運(yùn)行時(shí)它還存在。當(dāng)這樣的問(wèn)題積累到一定程度,最終將導(dǎo)致系統(tǒng)崩潰。所以這是很重要的,在你用完它以后,請(qǐng)釋放它的空間,如:
            delete pPointer;
              這樣就差不多了,你不得不小心。在這你終止了一個(gè)有效的指針(一個(gè)確實(shí)指向某個(gè)內(nèi)存的指針)。
              下面的程序,它不會(huì)浪費(fèi)任何的內(nèi)存:

            #include <iostream.h>

            int *pPointer;

            void SomeFunction()
            {
            // 讓指針指向一個(gè)新的整型
            pPointer = new int;
            *pPointer = 25;
            }

            void main()
            {
            SomeFunction(); //為pPointer賦值
            cout<<"Value of *pPointer: "<<*pPointer<<endl;

            delete pPointer;
            } 

              只有一行與前一個(gè)程序不同,但就是這最后一行十分地重要。如果你不刪除它,你就會(huì)制造一起“內(nèi)存漏洞”,而讓內(nèi)存逐漸地泄漏。
              (譯者:假如在程序中調(diào)用了兩次SomeFunction,你又該如何修改這個(gè)程序呢?請(qǐng)讀者自己思考)

            傳遞指針到函數(shù)

              傳遞指針到函數(shù)是非常有用的,也很容易掌握。如果我們寫一個(gè)程序,讓一個(gè)數(shù)加上5,看一看這個(gè)程序完整嗎?:
            #include <iostream.h>

            void AddFive(int Number)
            {
            Number = Number + 5;
            }

            void main()
            {
            int nMyNumber = 18;

            cout<<"My original number is "<<nMyNumber<<endl;
            AddFive(nMyNumber);
            cout<<"My new number is "<<nMyNumber<<endl;
            //得到了結(jié)果23嗎?問(wèn)題出在哪兒?
            }
              問(wèn)題出在函數(shù)AddFive里用到的Number是變量nMyNumber的一個(gè)副本而傳遞給函數(shù),而不是變量本身。因此, " Number = Number + 5" 這一行是把變量的副本加了5,而原始的變量在主函數(shù)main()里依然沒變。試著運(yùn)行這個(gè)程序,自己去體會(huì)一下。
              要解決這個(gè)問(wèn)題,我們就要傳遞一個(gè)指針到函數(shù),所以我們要修改一下函數(shù)讓它能接受指針:把'void AddFive(int Number)' 改成 'void AddFive(int* Number)' 。下面就是改過(guò)的程序,注意函數(shù)調(diào)用時(shí)要用&號(hào),以表示傳遞的是指針:
            #include <iostream.h>
            void AddFive(int* Number)
            {
            *Number = *Number + 5;
            }

            void main()
            {
            int nMyNumber = 18;

            cout<<"My original number is "<<nMyNumber<<endl;
            AddFive(&nMyNumber);
            cout<<"My new number is "<<nMyNumber<<endl;
            }


              試著自己去運(yùn)行它,注意在函數(shù)AddFive的參數(shù)Number前加*號(hào)的重要性:它告訴編譯器,我們是把指針?biāo)傅淖兞考?。而不并指針自己加5。

              最后,如果想讓函數(shù)返回指針的話,你可以這么寫:
            int * MyFunction();
              在這句里,MyFunction返回一個(gè)指向整型的指針。


            指向類的指針

              指針在類中的操作要格外小心,你可以用如下的辦法定義一個(gè)類:
            class MyClass
            {
              public:
              int m_Number;
              char m_Character;
            };
              接著你就可以定義一個(gè)MyClass 類的變量了:
            MyClass thing;
              你應(yīng)該已經(jīng)知道怎樣去定義一個(gè)指針了吧:
            MyClass *thing;
              接著你可以分配個(gè)內(nèi)存空間給它:
            thing = new MyClass;
              注意,問(wèn)題出現(xiàn)了。你打算怎樣使用這個(gè)指針呢,通常你可能會(huì)寫'thing.m_Number',但是thing是類嗎,不,它是一個(gè)指向類的指針,它本身并不包含一個(gè)叫m_Number的變量。所以我們必須用另一種方法:就是把'.'(點(diǎn)號(hào))換成 -> ,來(lái)看下面的例子:
            class MyClass
            {
            public:
            int m_Number;
            char m_Character;
            };

            void main()
            {
            MyClass *pPointer;
            pPointer = new MyClass;

            pPointer->m_Number = 10;
            pPointer->m_Character = 's';

            delete pPointer;
            }

            指向數(shù)組的指針

              你也可以讓指針指向一個(gè)數(shù)組,按下面的方法操作:
            int *pArray;
            pArray = new int[6];
              程序會(huì)創(chuàng)建一個(gè)指針pArray,讓它指向一個(gè)有六個(gè)元素的數(shù)組。另外一種方法,不用動(dòng)態(tài)分配:
            int *pArray;
            int MyArray[6];
            pArray = &MyArray[0];
              注意,&MyArray[0] 也可以簡(jiǎn)寫成 MyArray ,都表示是數(shù)組的第一個(gè)元素地址。但如果寫成pArray = &MyArray可能就會(huì)出問(wèn)題,結(jié)果是 pArray 指向的是指向數(shù)組的指針(在一維數(shù)組中盡管與&MyArray[0]相等),而不是你想要的,在多維數(shù)組中很容易出錯(cuò)。


            在數(shù)組中使用指針

              一旦你定義了一個(gè)指向數(shù)組的指針,你該怎樣使用它呢?讓我們來(lái)看一個(gè)例子,一個(gè)指向整型數(shù)組的指針:

            #include <iostream.h>

            void main()
            {
            int Array[3];
            Array[0] = 10;
            Array[1] = 20;
            Array[2] = 30;

            int *pArray;
            pArray = &Array[0];

            cout<<"pArray points to the value %d\n"<<*pArray<<endl;
            }

              如果讓指針指向數(shù)組元素中的下一個(gè),可以用pArray++.也可以用你應(yīng)該能想到的pArray + 1,都會(huì)讓指針指向數(shù)組的下一個(gè)元素。要注意的是你在移動(dòng)指針時(shí),程序并不檢查你是否已經(jīng)移動(dòng)地超出了你定義的數(shù)組,也就是說(shuō)你很可能通過(guò)上面的簡(jiǎn)單指針加操作而訪問(wèn)到數(shù)組以外的數(shù)據(jù),而結(jié)果就是,可能會(huì)使系統(tǒng)崩潰,所以請(qǐng)格外小心。
              當(dāng)然有了pArray + 1,也可以有pArray - 1,這種操作在循環(huán)中很常用,特別是while循環(huán)中。
              另一個(gè)需要注意的是,如果你定義了一個(gè)指向整型數(shù)的指針:int* pNumberSet ,你可以把它當(dāng)作是數(shù)組,如:pNumberSet[0] 和 *pNumberSet是相等的,pNumberSet[1]與*(pNumberSet + 1)也是相等的。
              在這一節(jié)的最后提一個(gè)警告:如果你用 new 動(dòng)態(tài)地分配了一個(gè)數(shù)組,
            int *pArray;
            pArray = new int[6];
              別忘了回收,
            delete[] pArray;
              這一句是告訴編譯器是刪除整個(gè)數(shù)組而不一個(gè)單獨(dú)的元素。千萬(wàn)記住了。


            后話

              還有一點(diǎn)要小心,別刪除一個(gè)根本就沒分配內(nèi)存的指針,典型的是如果沒用new分配,就別用delete:

            void main()
            {
              int number;
              int *pNumber = number;

              delete pNumber; // 錯(cuò)誤 - *pNumber 沒有用new動(dòng)態(tài)分配內(nèi)存.
            }

            常見問(wèn)題解答

            Q:為什么我在編譯程序時(shí)老是在 new 和 delete語(yǔ)句中出現(xiàn)'symbol undefined' 錯(cuò)誤?
            A:new 和 delete都是C++在C上的擴(kuò)展,這個(gè)錯(cuò)誤是說(shuō)編譯器認(rèn)為你現(xiàn)在的程序是C而不C++,當(dāng)然會(huì)出錯(cuò)了??纯茨愕奈募遣皇?cpp結(jié)尾。

            Q:new 和 malloc有什么不同?
            A:new 是C++中的關(guān)健字,用來(lái)分配內(nèi)存的一個(gè)標(biāo)準(zhǔn)函數(shù)。如果沒有必要,請(qǐng)不要在C++中使用malloc。因?yàn)閙alloc是C中的語(yǔ)法,它不是為面向?qū)ο蟮腃++而設(shè)計(jì)的。

            Q:我可以同時(shí)使用free 和 delete嗎?
            A:你應(yīng)該注意的是,它們各自所匹配的操作不同。free只用在用malloc分配的內(nèi)存操作中,而delete只用在用new分配的內(nèi)存操作中。


            引用(寫給某些有能力的讀者)

              這一節(jié)的內(nèi)容不是我的這篇文章的中心,只是供某些有能力的讀者參考。
              有些讀者經(jīng)常問(wèn)我關(guān)于引用和指針的問(wèn)題,這里我簡(jiǎn)要地討論一下。
              在前面指針的學(xué)習(xí)中,我們知道(&)是讀作“什么的地址”,但在下面的程序中,它是讀作“什么的引用”

            int& Number = myOtherNumber;
            Number = 25;
              引用有點(diǎn)像是一個(gè)指向myOtherNumber的指針,不同的是它是自動(dòng)刪除的。所以他比指針在某些場(chǎng)合更有用。與上面等價(jià)的代碼是:
            int* pNumber = &myOtherNumber;
            *pNumber = 25;
              指針與引用另一個(gè)不同是你不能修改你已經(jīng)定義好的引用,也就是說(shuō)你不能改變它在聲明時(shí)所指的內(nèi)容。舉個(gè)例子:
            int myFirstNumber = 25;
            int mySecondNumber = 20;
            int &myReference = myFirstNumber;

            myReference = mySecondNumber;//這一步能使myReference 改變嗎?

            cout<<myFristNumber<<endl;//結(jié)果是20還是25?

              當(dāng)在類中操作時(shí),引用的值必須在構(gòu)造函數(shù)中設(shè)定,例:

            CMyClass::CMyClass(int &variable) : m_MyReferenceInCMyClass(variable)
            {
              // constructor code here
            }


            總結(jié)

              這篇文章開始可能會(huì)較難掌握,所以最好是多讀幾遍。有些讀者暫時(shí)還不能理解,在這兒我再做一個(gè)簡(jiǎn)要的總結(jié):
              指針是一個(gè)指向內(nèi)存區(qū)域的變量,定義時(shí)在變量名前加上星號(hào)(*)(如:int *number)。
              你可以得到任何一個(gè)變量的地址,只在變量名前加上&(如:pNumber = &my_number)。
              你可以用'new' 關(guān)鍵字動(dòng)態(tài)分配內(nèi)存。指針的類型必須與它所指的變量類型一樣(如:int *number 就不能指向 MyClass)。
              你可以傳遞一個(gè)指針到函數(shù)。必須用'delete'刪除你動(dòng)態(tài)分配的內(nèi)存。
              你可以用&array[0]而讓指針指向一個(gè)數(shù)組。
              你必須用delete[]而不是delete來(lái)刪除動(dòng)態(tài)分配的數(shù)組。

              文章到這兒就差不多結(jié)束了,但這些并不就是指針?biāo)械臇|西,像指向指針的指針等我還沒有介紹,因?yàn)檫@些東西對(duì)于一個(gè)初學(xué)指針的人來(lái)說(shuō)還太復(fù)雜了,我不能讓讀者一開始就被太復(fù)雜的東西而嚇走了。好了,到這兒吧,試著運(yùn)行我上面寫的小程序,也多自己寫寫程序,你肯定會(huì)進(jìn)步不小的!
            posted @ 2010-06-21 22:32 lhking 閱讀(372) | 評(píng)論 (0)編輯 收藏
            1. int *a = new a;   
            2. int *b = new b();  

             

            其中a 為 隨機(jī)值,按書上說(shuō)法是,a為上次位于該內(nèi)存的值,b初始化為0;現(xiàn)測(cè)試類類型的結(jié)果

            也就是說(shuō), 對(duì)于沒有提供任何構(gòu)造函數(shù)的類,new 的時(shí)候加括號(hào),會(huì)幫你創(chuàng)造一個(gè)默認(rèn)構(gòu)造函數(shù),而且?guī)湍愠跏蓟?/span>

            而new的時(shí)候沒有加括號(hào),也會(huì)幫你構(gòu)造一個(gè)默認(rèn)構(gòu)造函數(shù),只是什么都沒做。

            posted @ 2010-05-28 11:19 lhking 閱讀(125) | 評(píng)論 (0)編輯 收藏
            請(qǐng)問(wèn)個(gè)位高手小弟看c++教程有一點(diǎn)沒明白
            new一個(gè)對(duì)象必須delete刪除,不是new的對(duì)象就不需要?jiǎng)h除了嗎?

            代碼:
            Person p("john green"); 
            cout < < p.getName();    //string name的屬性值還存在,此時(shí)還占著內(nèi)存

            delete &p;        //只有

            cout < < p.getName();  //這樣才提示不存在,如果delete &p注釋掉,p對(duì)象的name屬性始終是占著內(nèi)存的


            但是我看很多教程上的代碼不是new的對(duì)象他們并沒有delete,
            難道不是new的對(duì)象就不用delete,但是他自己并不回收內(nèi)存阿()????????


            解析:
            1、p只是一個(gè)棧變量,不是堆變量,會(huì)自動(dòng)析構(gòu)的,不能使用delete

            2、你這個(gè)問(wèn)題讓我感覺無(wú)可奈何。

            感覺缺少基本的理解。


            生存在棧上的對(duì)象和生存在堆上的對(duì)象你要搞清楚。

            堆需要手動(dòng)回收。

            棧則由系統(tǒng)自動(dòng)回收!
            3、不是new的,在退出作用域后會(huì)自動(dòng)析構(gòu)。其占用的內(nèi)存也會(huì)被自動(dòng)回收掉。
            這種自動(dòng)變量才是最方便的,也不會(huì)造成內(nèi)存泄露,因此,能用的時(shí)候盡量用,不要在自動(dòng)變量完全可以解決問(wèn)題的時(shí)候卻硬是要采用堆上動(dòng)態(tài)申請(qǐng)的對(duì)象。
            posted @ 2010-05-28 11:06 lhking 閱讀(863) | 評(píng)論 (0)編輯 收藏

            這個(gè)問(wèn)題在許多C++程序員看來(lái)會(huì)很搞笑,“這么簡(jiǎn)單的問(wèn)題還用得著你廢話!”。但是由于本人生性愚鈍,學(xué)C++的時(shí)候,確實(shí)花了很久的時(shí)間都搞不明白,只是會(huì)寫一個(gè)文件,但不會(huì)寫一個(gè)工程。而用C++編寫比較大型的項(xiàng)目時(shí),文件的分割管理確實(shí)確實(shí)是非常必要的 。下面就非常簡(jiǎn)潔明了地談?wù)勵(lì)^文件(.h)和源文件(.cpp)應(yīng)該怎么寫。

               頭文件(.h):
                寫類的聲明(包括類里面的成員和方法的聲明)、函數(shù)原型、#define常數(shù)等,但一般來(lái)說(shuō)不寫出具體的實(shí)現(xiàn)。

                在寫頭文件時(shí)需要注意,在開頭和結(jié)尾處必須按照如下樣式加上預(yù)編譯語(yǔ)句(如下):

            #ifndef CIRCLE_H
            #define CIRCLE_H

            //你的代碼寫在這里

            #endif
                這樣做是為了防止重復(fù)編譯,不這樣做就有可能出錯(cuò)。

                至于CIRCLE_H這個(gè)名字實(shí)際上是無(wú)所謂的,你叫什么都行,只要符合規(guī)范都行。原則上來(lái)說(shuō),非常建議把它寫成這種形式,因?yàn)楸容^容易和頭文件的名字對(duì)應(yīng)。

               源文件(.cpp):

                源文件主要寫實(shí)現(xiàn)頭文件中已經(jīng)聲明的那些函數(shù)的具體代碼。需要注意的是,開頭必須#include一下實(shí)現(xiàn)的頭文件,以及要用到的頭文件。那么當(dāng)你需要用到自己寫的頭文件中的類時(shí),只需要#include進(jìn)來(lái)就行了。

                下面舉個(gè)最簡(jiǎn)單的例子來(lái)描述一下,咱就求個(gè)圓面積。

                 第1步,建立一個(gè)空工程(以在VS2003環(huán)境下為例)。

                 第2步,在頭文件的文件夾里新建一個(gè)名為Circle.h的頭文件,它的內(nèi)容如下:

            #ifndef CIRCLE_H
            #define CIRCLE_H

            class Circle
            ...{
            private:
                double r;//半徑
            public:
                Circle();//構(gòu)造函數(shù)
                Circle(double R);//構(gòu)造函數(shù)
                double Area();//求面積函數(shù)
            };

            #endif
               注意到開頭結(jié)尾的預(yù)編譯語(yǔ)句。在頭文件里,并不寫出函數(shù)的具體實(shí)現(xiàn)。

                第3步,要給出Circle類的具體實(shí)現(xiàn),因此,在源文件夾里新建一個(gè)Circle.cpp的文件,它的內(nèi)容如下:

            #include "Circle.h"

            Circle::Circle()
            ...{
                this->r=5.0;
            }

            Circle::Circle(double R)
            ...{
                this->r=R;
            }

            double Circle:: Area()
            ...{
                return 3.14*r*r;
            }
                需要注意的是:開頭處包含了Circle.h,事實(shí)上,只要此cpp文件用到的文件,都要包含進(jìn)來(lái)!這個(gè)文件的名字其實(shí)不一定要叫Circle.cpp,但非常建議cpp文件與頭文件相對(duì)應(yīng)。

                最后,我們建一個(gè)main.cpp來(lái)測(cè)試我們寫的Circle類,它的內(nèi)容如下:

            #include <iostream>
            #include "Circle.h"
            using namespace std;

            int main()
            ...{
                Circle c(3);
                cout<<"Area="<<c.Area()<<endl;
                return 1;
            }
                注意到開頭時(shí)有#include "Circle.h"的聲明,證明我們使用到了我們剛才寫的Circle類。

               至此,我們工程的結(jié)構(gòu)為:

             

                運(yùn)行一下,輸出結(jié)果為:

             

               說(shuō)明我們寫的Circle類確實(shí)可以用了。

            posted @ 2010-05-28 10:34 lhking 閱讀(25029) | 評(píng)論 (1)編輯 收藏

            作用域運(yùn)算符::是用來(lái)標(biāo)識(shí)某個(gè)成員函數(shù)是屬于哪個(gè)類的。

            在C++中,有一個(gè)stream這個(gè)類,所有的I/O都以這個(gè)“流”類為基礎(chǔ)的,包括我們要認(rèn)識(shí)的文件I/O,stream這個(gè)類有兩個(gè)重要的運(yùn)算符:

            1、插入器(<<)
              向流輸出數(shù)據(jù)。比如說(shuō)系統(tǒng)有一個(gè)默認(rèn)的標(biāo)準(zhǔn)輸出流(cout),一般情況下就是指的顯示器,所以,cout<<"Write Stdout"<<' ';就表示把字符串"Write Stdout"和換行字符(' ')輸出到標(biāo)準(zhǔn)輸出流。

            2、析取器(>>)
              從流中輸入數(shù)據(jù)。比如說(shuō)系統(tǒng)有一個(gè)默認(rèn)的標(biāo)準(zhǔn)輸入流(cin),一般情況下就是指的鍵盤,所以,cin>>x;就表示從標(biāo)準(zhǔn)輸入流中讀取一個(gè)指定類型(即變量x的類型)的數(shù)據(jù)。

              在C++中,對(duì)文件的操作是通過(guò)stream的子類fstream(file stream)來(lái)實(shí)現(xiàn)的,所以,要用這種方式操作文件,就必須加入頭文件fstream.h。


            A.cpp要引用B.cpp的函數(shù)。
            最干凈的方法是,為B.cpp建立一個(gè)頭文件B.h,將A.cpp要調(diào)用的函數(shù)聲明寫進(jìn)去。
            然后在A.cpp里#include這個(gè)B.h。

            很C的方法是。在A.cpp里面直接extern 那個(gè)B.cpp里的函數(shù),就是在extern后面寫上函數(shù)聲明。然后B.cpp里的那個(gè)函數(shù)要是static的。


            附加說(shuō)明
            使用命名空間
            2008要求較嚴(yán)格 .h是C語(yǔ)言里的東西,所以包含頭文件時(shí)應(yīng)該用
            #include <iostream>
            using namespace std;


            c++中的STL和MFC
            c++是一門編程語(yǔ)言,這門語(yǔ)言有它自己的標(biāo)準(zhǔn)和規(guī)范(比如有自己的語(yǔ)法)。
            同樣,針對(duì)C++這門語(yǔ)言,標(biāo)準(zhǔn)化組織又規(guī)定了相關(guān)的“程序庫(kù)”,程序庫(kù)中有各式各樣的工具(都是由高手編寫的,所以可用性極佳)供編程人員使用,而STL(standard   template   library,標(biāo)準(zhǔn)模板庫(kù))就是C++“程序庫(kù)”的一部分。
            至于MFC,它只不過(guò)是“利用C++的語(yǔ)法對(duì)windows   API進(jìn)行的面向?qū)ο蟮姆庋b”而已,也就是說(shuō),有了mfc,我們不用“直接”調(diào)用windows   API,而是可以通過(guò)C++的語(yǔ)法、以面向?qū)ο蟮姆绞绞褂脀indows   API。

            C++   是一種編程語(yǔ)言,可以支持成面向過(guò)程,或者基于過(guò)程,或者面向?qū)ο笤O(shè)計(jì)方法
            STL   是C++標(biāo)準(zhǔn)程序庫(kù),提供處了基本的數(shù)據(jù)類型int   char,還有擴(kuò)展的用類實(shí)現(xiàn)的容器類型如vector,list等標(biāo)準(zhǔn)泛型容器類型,以及一些通用的泛型算法
            MFC,一個(gè)framework,   用面向?qū)ο蟮姆椒?,?lái)封裝win32   api來(lái)進(jìn)行windows   平臺(tái)上的程序開發(fā)

            這是因?yàn)樵诤瘮?shù)結(jié)束之后要釋放臨時(shí)變量。對(duì)指針賦值,一定要采用“指針的指針”。 
            我改過(guò)的程序如下: 

            void   init(int   **base,int   **top) 

            int   *temp   =   NULL; 
            temp   
            =   (int*)   malloc(sizeof(int)*50); 
            *base   =   temp; 
            *top     =   temp; 
            }
             

            void   main() 

            int   *base   =   NULL,   *top   =   NULL; 
            init(
            &base,   &top); 
            printf( 
            "%X\t%X\n ",   base,   top); 
            }
             
            最后不要忘了調(diào)用free()去釋放你分配的內(nèi)存。

            vs2008下cannot convert parameter 1 from 'LPCTSTR' to 'const char *'的解決方法:
            1. 使用_T()實(shí)現(xiàn)ASCII與UNICODE自動(dòng)轉(zhuǎn)換
            2. 在使用字符串的使用 T"Hello world"或者L"hello world"
            3. 設(shè)置Character Set為Use Multi-Byte Character Set
            posted @ 2010-05-28 09:46 lhking 閱讀(280) | 評(píng)論 (0)編輯 收藏

             

            #include <iostream>
            #include 
            <fstream>
            #include 
            <string>

            using namespace std;

            int main()
            {
                
            const char filename[] = "mytext.txt";
                ofstream o_file;
                ifstream i_file;
                
            string out_text;

                
            //
                o_file.open(filename);
                
            for (int i = 1; i <= 10; i++)
                
            {
                    o_file 
            << "" << i << ""<<endl; //將內(nèi)容寫入到文本文件中
                }

                o_file.close();

                
            //
                i_file.open(filename);
                
            if (i_file.is_open())
                
            {
                    
            while (i_file.good())
                    
            {
                        i_file
            >> out_text; //將讀取的內(nèi)容存儲(chǔ)到變量out_text中
                        cout << out_text << endl; //在控制臺(tái)輸出讀取的內(nèi)容。為什么最后一行的內(nèi)容會(huì)出現(xiàn)兩次
                    }

                }

                
            else
                    cout 
            << "打開文件:" << filename << " 時(shí)出錯(cuò)!";
                i_file.close();

                system(
            "PAUSE");
                
            return 0;
            }



            preheader:
            #include "stdafx.h"
            #include 
            <iostream>
            #include 
            <fstream>
            #include 
            <string>
            using namespace std;

            int _tmain(int argc, _TCHAR* argv[])
            {
                
            const char filename[]="test.doc";
                ofstream o_file;
            /* 輸出流:將數(shù)據(jù)從內(nèi)存輸出其中ofstream是將數(shù)據(jù)輸出到文件,因此對(duì)于文件來(lái)說(shuō)是“寫”*/
                ifstream i_file;
            /*將數(shù)據(jù)輸入到內(nèi)存,其中ifstream是說(shuō)輸入的數(shù)據(jù)在文件中,因此對(duì)于文件來(lái)說(shuō)是“讀”*/
                
            string out_text;

                
            //
                o_file.open(filename);
                
            for(int i =0;i<=12;i++)
                
            {
                    o_file
            <<""<<i<<"行\(zhòng)n";//將內(nèi)容寫入文本
                }

                o_file.close();
                
            //
                i_file.open(filename);
                
            if(i_file.is_open())
                
            {
                    
            while(i_file>>out_text)
                    
            {
                        cout 
            << out_text << endl;
                    }

                }

                
            else
                    cout
            <<"打開文件:"<<filename<<"時(shí)出錯(cuò)!";
                i_file.close();
                system(
            "PAUSE");

                
            return 0;
            }
             
            posted @ 2010-05-28 09:46 lhking 閱讀(258) | 評(píng)論 (0)編輯 收藏
            今天注冊(cè)c++博客了
            posted @ 2010-05-28 08:42 lhking 閱讀(369) | 評(píng)論 (0)編輯 收藏
            僅列出標(biāo)題
            共3頁(yè): 1 2 3 

            導(dǎo)航

            <2025年8月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            統(tǒng)計(jì)

            常用鏈接

            留言簿

            隨筆檔案

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久国产美女免费观看精品| 午夜精品久久久内射近拍高清| 亚洲日韩欧美一区久久久久我| 日本亚洲色大成网站WWW久久 | 久久久久人妻精品一区二区三区| 色综合久久综合中文综合网| 成人久久精品一区二区三区| 久久人人爽人爽人人爽av| 亚洲∧v久久久无码精品| 久久精品国产99久久久香蕉| 亚洲成色www久久网站夜月| 久久99国产精品成人欧美| 97精品依人久久久大香线蕉97| 久久青青草原国产精品免费| 久久亚洲春色中文字幕久久久| 人人狠狠综合久久亚洲| 97超级碰碰碰久久久久| 久久精品国产乱子伦| 99久久国产综合精品五月天喷水| 一本色道久久88精品综合 | 女同久久| 18岁日韩内射颜射午夜久久成人| 久久久久免费精品国产| 久久亚洲AV永久无码精品| 久久精品成人免费看| 欧洲精品久久久av无码电影| 亚洲国产欧洲综合997久久| 人妻无码αv中文字幕久久琪琪布| 国产ww久久久久久久久久| 久久久久国产精品| 99久久99久久精品国产| 国产精品免费久久久久久久久| 99久久久精品| 青青青国产精品国产精品久久久久 | 亚洲国产另类久久久精品| 久久中文字幕人妻熟av女| 波多野结衣久久一区二区| 久久久久亚洲精品日久生情| 亚洲AV日韩精品久久久久| 久久久久AV综合网成人| 国产精品无码久久综合|