指標作為形參進行傳遞注意事項

2021-07-28 10:57:59 字數 3560 閱讀 9921

參考:

#include

using

namespace

std;

int m_value = 1;

void func(int *p)

int main(int argc, char *argv)

執行結果: 2 2

修改func函式如下

void func(int *p)

執行結果: 2 3

修改func函式如下:

void func(int *p)

依然是2,3

修改func函式如下:

void func(int *p)

結果是2,2

解釋:

編譯器總是要為函式的每個引數製作臨時副本,指標引數p的副本是 _p,編譯器使 _p = p

如果函式體內的程式修改了_p所指向的內容,就導致引數p的內容作相應的修改。把_p所指的記憶體位址改變了,那麼 _p指向的記憶體塊,和p指向的記憶體塊就不一樣了。所以對p毫無影響。只要程式裡不改變 _p的指向, _p和p就是一樣的,操作 _p內容,就是操作p的內容。

下面常用的交換程式:

#include 

int*swap(int

*px, int

*py)

int main(void)

結果:

now i=20

j=10 *p=20

函式裡面分配記憶體

void mymalloc(char *s) //我想在函式中分配記憶體,再返回  

void main()

else

cout

<< "p為空"

<< endl;

}

結果

p為空
看另乙個例子:

void mymalloc(char **s) //我想在函式中分配記憶體,再返回  

void main()

else

cout

<< "p為空"

<< endl;

}

結果:

p不為空

hello

解釋:

1.被分配記憶體的是形參s,p沒有分配記憶體

2.被分配記憶體的是形參s指向的指標p,所以分配了記憶體

第三個小例子:

void getmemory(char *p, int num)  

void test(void)

道理一樣。

所以要想借助函式進行分配記憶體,需要傳遞的是「指標的指標」,就是第乙個例子。

void getmemory2(char **p, int num)  

另外還可以:用函式返回值來傳遞動態記憶體

char *getmemory3(int num)  

void test3(void)

輸出結果:hello

注意這裡函式返回值傳遞的動態記憶體,必須是在「堆上」申請的記憶體!!!

不要用return語句返回指向「棧記憶體」的指標,因為該內存在函式結束時自動消亡

char *getstring(void)  

void test4(void)

但是下面的又會讓人疑惑:

char *getstring2(void)  

void test5(void)

這個能執行,輸出:hello world

函式test5執行雖然不會出錯,但是函式getstring2的設計概念卻是錯誤的。因為getstring2內的「hello world」是常量字串,位於靜態儲存區,它在程式生命期內恆定不變。無論什麼時候呼叫getstring2,它返回的始終是同乙個「唯讀」的記憶體塊。

char *pp = "wocao!";

pp[0] = '1';//這樣賦值是錯誤的。

所以上述測試時:

多加一句是會報錯的

void main(void)

《高質量c c++程式設計指南》這本書上說: 指標p 指向常量字串(位於常量儲存區),常量字串的內容是不可以被修改的,企圖修改常量字串的內容而導致執行錯誤。所以這個問題出現的原因是char*p=」abcdefghi」,賦值的是字串常量,儲存在常量儲存區,而常量儲存區的內容是無法修改的。

如果使用陣列來代替的話,資料就儲存在堆疊空間,堆疊空間的內容是可以修改的,就不會出現執行時錯誤。

另外再加乙個小總結:

程式1:

void mymalloc(char *s) //我想在函式中分配記憶體,再返回

這個和呼叫 void func (int i) ; 一樣,退出函式體,i指復原的

程式2:void mymalloc(char **s)

等價於void

int func(int * pi) pi指標不變,指標指向的資料內容是變化的

值參本身不變,但是值參指向的記憶體的內容發生了變化。

程式3:

void fun(int *p)

程式4:

void fun(int *p)

結論:1.函式的返回值是指標型別的,檢查是靜態記憶體指標還是堆記憶體指標還是棧記憶體指標,棧記憶體指標是絕對要不得滴!

2.函式需要使用指標引數進行傳入傳出的,在函式中只能對指標的指向的值(*p)進行修改,而不能修改指標指向,也就是指標位址!(函式中不得修改指標引數的位址,否則請使用指標的指標!)

推薦好的總結:

其中總結非常棒:

一般在函式中定義乙個物件有兩種方法:   

1、在棧上建立區域性變數。注意,在棧上時!棧用於函式是為了返回時找得到呼叫點(在呼叫時壓入棧的)

,那麼,返回時要pop才能得到。函式體中建立的任何東西都消失了(返回值除外),你返回的指標指向的內

容現在不知被用作什麼用途了,如果你還要修改的話,那麼後果不能確定。

2、在堆中分配。返回時不會摧毀,因為堆是全域性存在的。但函式的呼叫者要記得delete回來的指標。

void func(int

*&p)

int main(int argc, char *argv)

結果是:2,1

此時傳遞過去就是指標p,因為引用!

看一下func(int *&p)方法

p: 是指標的引用,main()方法裡的 *pn

*p:是main()方法裡的pn指向的內容。

python函式形參傳遞注意事項

說到這個問題,我們先來看一段 coding utf 8 author 15025 time 2021 3 12 10 19 software pycharm description def max if a b print a b a 5b 3max a b 此時有輸出結果,輸出為print函式中定...

C C 指標作為函式形參注意點

函式形參是指標變數,直接對其賦值 指標相互賦值 只是改變了它的指向,原先傳入的指標指向的內容並沒改變 若要想改動其指向的值,需要通過memcpy或通過指標呼叫賦值 include include include include include include include using namesp...

指標作為函式形參

先來看兩個程式 程式1 include void fun int p int main void 輸出為 程式2 include void fun int p int main void 輸出為 對於程式2,不難理解 程式1,明明改變了p的指向了,為什麼還是輸出1呢?其實問題的關鍵不是指標作為形參的...