小議C 中函式的引數的傳遞

2021-06-19 13:40:18 字數 1450 閱讀 6394

c++中為每乙個函式都維護了乙個執行棧(活動記錄),這個棧儲存了與該函式相關的一系列資訊,包括函式中宣告的變數,傳遞給函式的實際引數,以及該函式的返回位址等,使用gdb偵錯程式可以清楚的看到這一切。當呼叫發生時,該函式會將實際引數的值copy到執行棧,也就是常說的值傳遞。那麼很顯然的就是,如果我們在函式中改變的只是實際引數的值的拷貝,所以實際引數的值並沒有發生變化。

另外指標和引用還有乙個共同的優點就是它們都可以提高程式的效率。雖然對於引數為簡單的變數的函式來說,提高的效率可能杯水車薪,微不足道。但是對於那種引數為巨大的類等的東西,當函式將實際引數的值複製到執行棧的時間代價和空間代價是任何乙個真正的程式設計師所不能容忍的。採用指標和引用時,函式操作的就是實際引數,所以不用將它複製到自己的執行棧。當然,有的哥們會擔心如果採用這種方式,我們不小心將實際引數的值改變了,但實際上並不想讓實際引數的值改變怎麼辦?這個不用擔心,因為c++的設計者早就想到了這一點,他們引入了const這個關鍵字(貌似是從c語言繼承過來的,那就不是c++設計者的創意啦)。通過用const修飾的指標和引用,使得使用者不能夠通過這個指標或引用修改它們所指向的記憶體單元。

既然指標和引用都有這兩個優點,它們兩個又有什麼區別呢?從表面上看,指標可以不用被初始化,可以為空,可以隨便亂指,當然這都是在符合語法規則的前提下。而引用必須被初始化為乙個變數,並且永遠不允許再改變。另外引用有乙個重要的優點就是看著「好看」,又有效率。我說的「好看」,那可是真的好看,比如說,在過載運算子中:

matrix a,b,c;    //matrix是個巨大的類

matrix operator+(const matrix &m1,const matrix &m2)

c=a+b //是不是很好看

但是如果使用指標的話,那可真就是慘不忍睹了:

matrix a,b,c;    //matrix是個巨大的類

matrix operator+(const matrix *m1,const matrix *m2)

c=&a+&b //是不是很慘啊

&(&a+&b)+&c //這是更慘的

引用還真是個好東西啊。

當c++的函式傳遞的引數是個陣列時,編譯器會將其看作乙個指標,也就是陣列首元素的位址。編譯器不知道陣列到底有多少個元素,其實我們最常使用的main函式就已經向我們所名了這個道理,當使用命令列引數的時候,傳遞的兩個引數分別是argc和argv,這個argc就是用來專門告訴編譯器引數個數的。連main函式都得這樣,其他函式就更不用說了。所以就算你在定義時像這樣void sort(int a),但這是沒用的,編譯器只會將它看成 void sort(int* a)。要想讓函式知道陣列有幾個元素怎麼辦呢,當然上面個已經說明了一種方法。還有一種方法就是陣列引用,呵,又是引用,沒錯,可以寫成這個樣子 void sort(int (&a) [10]),就是著個樣子,看起來有點**。但是千萬不要把那個(&a)中的括號去掉,否則就真**了。

就寫到這裡吧,該回去了。

C 函式中引數的傳遞

2 34 include stdafx.h 5 include 6 7using namespace std 89 值傳遞 10void swap1 int p,int q 11 1718 指標傳遞,函式體內只有指標值的變化 19void swap2 int p,int q 2026 27 指標傳遞...

C 函式的引數傳遞

一 函式未被呼叫前,函式的形參並不占有實際的記憶體空間,也沒有被賦值。只有在被呼叫的時候,才被賦值。函式引數傳遞指的就是形參和實參想結合的過程。二 函式引數傳遞存在兩種形式 1 值傳遞 即函式在發生呼叫時,給形參分配記憶體空間,直接以實參的值初始化形參。函式被賦值後,實參和形參即沒有關係,形參的改變...

C 函式的引數傳遞

所有的函式都使用 在程式執行棧中分配的儲存區。該儲存區一直保持與該函式相關聯,直到函式結束為止。那時,儲存區將自動釋放以便重新使用。該函式的整個儲存區稱為活動記錄。系統在函式的活動記錄中為函式的每個引數都提供了儲存區,引數的儲存長度由它的型別來決定。引數傳遞是指用函式呼叫的實參值來初始化函式引數儲存...