C語言指標引數陷阱

2021-09-30 13:04:30 字數 1429 閱讀 4326

本人是乙個剛開始學資料結構的大二學生,最近在學習鍊錶的時候出現了一些小問題,一下是這個問題的詳細分析,雖然是很簡單,很可笑的乙個小問題,卻也值得深究

#include

#include

/*這裡構造乙個結構體,用來表示鍊錶的乙個節點*/

typedef struct ysfysf,pysf;

/*建立乙個節點*/

void comp(pysf *p,int i)

int main()

else

}p->next = null;

printlist(p,l);

return 0;

}為什麼系統會報錯呢,我們來看一看這個錯誤資訊,段錯誤(核心已轉儲),這個錯誤相當於windows下的記憶體溢位,即訪問了不該訪問的記憶體區域,為什麼會這樣,我們來細細分解一下

在這之前,現舉個例子

#include

void fun(int *a,int *b)

int main()

這裡輸出的結果應該是多少呢,相信很多人會和我第一次看到它一樣,感覺完全懵逼了,不要急,我們乙個乙個分析

第乙個fun裡面,傳進去的是p和q的位址,錯誤的思想是覺得函式會通過指標直接操作,很遺憾我開始也是這麼想的,然而並不是這樣。把指標作為形參傳進乙個函式,相當於把實參的指標指向了形參所指的記憶體空間,即將a和b指向了x和y,函式內的操作只不過是把a和b換了,p和q是不受影響的。而第二個也是只改變a和b的指向,x和y的位址沒有變,p和q的指向也沒有變。

那麼有人就要問了,既然如此,那麼指標有何意義?指標不是號稱不需要返回值就可以改變原函式中的值麼,別急,是這樣的

#include

void fun(int *a,int *b)

int main()

這時候輸出的就是5,3了

拐個彎我們再回到一開始的問題,我的程式錯在**了呢?原來我用como(pysf *p)函式申請了一塊記憶體空間,並用這裡的形參p指向了它,然而實參p是在主函式中定義的,定義之後沒有進行初始化,所以它指向了記憶體上乙個任意的位址,函式comp執行結束之後從記憶體棧區退棧,形參p也隨之被釋放,然而實參q還是指向那個未知的位址。

到這裡一切都是沒問題的,然而接下來發生的事情就詭異了。我把實參p賦給了頭節點l的指標域,然後把q也指向p指向的這個位址,到這裡還是沒有問題的,但它們的行為已經脫離了我的控制。接下來進入第二次迴圈,這時候問題出現了,我要把下乙個節點的位址(假設它存在,其實p一直是指向那個未知位址的,並沒有指向什麼節點,那個節點早已迷失在記憶體空間)賦給q的指標域,前面說了,q和p一樣,都指向那個未知位址,我的程式並沒有操作那個未知位址的許可權,所以,兩個熱乎的野指標誕生了

在除錯的過程中,每次都可以進行到第二次迴圈,我以為是迴圈體**了什麼問題,在貼吧幫吧友解決問題的時候看到了上面那個例子,然後才明白了指標在函式呼叫方面的這些小道道,這個問題本質上是乙個野指標問題,其實在靈魂上,還是由於我對指標作為函式引數的特點不理解導致的

C語言陣列引數與指標引數

我們都知道引數分為形參和實參。形參是指宣告或定義函式時的引數,而實參是在呼叫函式時主調函式傳遞過來的實際值。1 能否向函式傳遞乙個陣列?看例子 void fun char a 10 intmain 先看上面的呼叫,fun b 10 將b 10 這個陣列傳遞到fun 函式。但這樣正確嗎?b 10 是代...

C語言 指標做函式引數

任務 include 改變上乙個章節,用氣泡排序法和指標來排序 void bubblesort int int 函式的宣告使用指標 int main 定義乙個無序陣列 bubblesort a,10 氣泡排序a陣列 int i for i 0 i 10 i printf n return 0 voi...

C語言指標做函式引數

指標型函式的作用是將主調函式中的變數位址傳遞到被調函式中,從而實現變數的跨函式引用。例 在主函式中輸入兩個整數並存入變數中,然後再被調函式中將這兩個數互換,最後在主函式中輸出結果。示例一 引數傳遞 include void swap int a,int b int main void 這種方法不能實...