在數據結構線性表一章,對線性表有這些操作方法(Operation):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
/*Operation*/ Initlist(*L); /*初始化操作,建立一個空的線性表L*/ ListEmpty(L); /*判斷線性表是否為空表,若線性表為空,返回值為true,否則返回false*/ ClearList(*L); /*將線性表清空*/ GetElem(L,i,*e); /*性表L中的第i個位置元素值返回給e*/ LocateElem(L,e); /*在線性表L中查找與給定值e相等的元素,如果查找成功,返回該元素在表中序號;否則,返回0表示失敗*/ ListInsert(*L,i,e); /*在第i個位置插入元素e*/ ListDelete(*L,i,*e); /*刪除i個位置元素,并用e返回其值*/ ListLength(L); /*返回線性表L的元素個數*/ |
我們大致可以將上述函數分為兩類,一類參數列表中沒有*,例如:ListEmpty(L);
另一類在L或者e前面有個(*)號,究竟是為什么呢?
我們可以從下面這些代碼得到啟發
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <stdio.h> #include <stdlib.h> void test1( int a, int b) { int c=0; c=b; b=a; a=c; printf ( "%d\n" ,a); printf ( "%d\n" ,b); } int main() { int a=1; int b=2; test1(a,b); printf ( "%d\n" ,a); printf ( "%d\n" ,b); } |
運行結果如下,可見test1中a,b作為形參互相交換值對main函數中的實參并沒有影響
2
1
1
2
Process returned 0 (0x0) execution time : 0.118 s
Press any key to continue.
讓我們對上述代碼稍作改動來觀察結果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#include <stdio.h> #include <stdlib.h> void test1( int *a, int *b) { int c=0; c=*b; *b=*a; *a=c; printf ( "%d\n" ,&a); printf ( "%d\n" ,&b); } int main() { int a=1; int b=2; test1(&a,&b); printf ( "%d\n" ,a); printf ( "%d\n" ,b); return 0; } |
6422000
6422008
2
1
Process returned 0 (0x0) execution time : 0.033 s
Press any key to continue.
很顯然,此次的test1()方法對main函數的實參總算有了影響,因為現在的test()方法是直接對地址為6422000與6422008存儲單元數據域的修改。
我們繼續回到對線性表操作上來,就會恍然大悟。例如:ListInsert(*L,i,e),倘若不加*,那么L就永遠作為一個局部變量留在了函數:ListInsert(L,i,e)中,沒法發生實際的改變。加了*才能保證L被帶出來。我們只需要在方法定義時給形參加上'*',在方法調用時給形參加上'&'就能獲得預期的效果
思考:另一種解決思路:是不是可以定義一種List Insert()方法,使得返回值為已經修改好的鏈表L呢?
1
2
3
4
5
6
7
|
List Insert(List L, int i,ElememtType e) { /* 此處為對鏈表進行插入操作 */ return List; //要注意這個返回的List值已經被修改了 } |
不過這也有個弊病,當插入發生在表頭時,L就必須要指向新的節點,否則地址仍指向的是原來 的表頭結點。解決方法也有,就是在鏈表第一個節點a前再插一個無意義的頭節點b,這樣每次想要在表頭插入元素時只需插在a,b之間即可。
注:C語言中*a指向a的數據域,&則是讀取a的地址。
到此這篇關于C語言*與&在操作線性表的作用詳解的文章就介紹到這了,更多相關C語言線性表* &內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/weixin_53912595/article/details/120942749