//定義順序表L的結構體 2 typedef struct 3 { 4 Elemtype data[MaxSize]; 5 int length; 6 }SqList; 7 8 //建立順序表 9 void CreateList(SqList * &L,ElemType a[ ],int n) 10 { 11 int i; 12 L = (SqList * )malloc(sizeof(SqList)); 13 for(i = 0 ; i < n ; i++) 14 L->data[i] = a[i]; 15 L->length = n; 16 } 17 //輸出線性表: 18 void DispList(SqList *L) 19 { 20 int i; 21 for(i = 0; i < L ->length; i++) 22 printf(“%d”,L->data[i]); 23 printf(“\n”); 24 }
思考這個形參為什么要寫成這兩種形式,即SqList *L和SqList * &L的區別。
*L是指針,全稱是指針變量,是一個用來保存內存地址的變量。在這里是一個指向順序表,存儲順序表的地址的變量。
* &L是指針類型的引用,引用(reference)是c++對c語言的重要擴充。引用就是原變量的另外一個名稱(別名),引用變量本身沒有自己的實際存儲空間,對引用變量的操作,就是在操作原變量。這里的* &L代表原指針。
這兩個有着一個共同點,都指向順序表 L ,如果在函數中修改L 的內容,都影響到 L 的內容。
不同點則是,在函數中修改指針本身所指向的地址,*L 不會發生改變,而* &L會發生改變。
若要改變形參中的內容並且使用它則需要用引用,如果不需要改變子函數體中形參旳值,則不需要用引用。
首先,* &L是引用類型的指針,代表的是原指針,我們在函數中對指針的操作,都是直接對原指針的操作,無論是指針的內容,還是指針指向的地址,都會發生改變。
那么,*L為什么在函數中會改變不了所指向的地址呢?
其實,這里我們要延伸到函數形式參數和實際參數的很基礎,也很重要的知識點了。
形參出現在函數定義中,在整個函數體內都可以使用。實參出現在主調函數中,進入被調函數后,實參也不能使用。在函數調用的時候,主函數把實參的值傳送給被調函數的形參,從而實現數據的傳送。
但是,在這個函數調用的過程中,數據傳送是單向的,即數據只能由實參傳到形參,而形參不會傳回實參。也就是說,我們在函數中改變形參的值,實參的值是不會發生改變的,這就是函數調用中的單向值傳遞。
那么,回到我們的 *L 來,*L其實就是一個變量,在這里是一個形式參數。形式參數在函數中其實是對實參的拷貝,也就是說,函數中形參其實是另一個變量,一個復制原變量的新變量,有不同於原變量的內存空間,存在於函數中,函數調用結束,即刻釋放內存空間。
也就是說,我們在函數中改變 *L 所指向的地址,不是在對原變量進行改變,而是對原變量的一個復制體進行改變,改變了復制體,卻沒有改變本體。
所以,在函數中 *L 不能改變所指向的地址。
#include<stdio.h> #include<stdlib.h> #define maxSize 10//定義整型變量值為10 typedef struct{ int data[maxSize]; int length; }Sqlist; void main(){ Sqlist L; int n; //&L表示實參,是一個變量的地址 initList(&L); // printf("請輸入元素個數"); scanf("%d",n); createList(&L,n); } - //初始化順序表,順序表本身需要發生改變 // *L是一個形參,參數類型是Sqlist類型的指針 void initList(Sqlist *L){ (*L).length = 0;//當前長度置零,空的 printf("初始化參數成功"); } //插入數據,p表示插入位置,e表示插入數值 int insertElem(Sqlist *L,int p,int e){ int i; // 越界,滿了 if(p<0||p>(*L).length||(*L).length==maxSize){ return 0; } // 位置p和p后面的元素往后移 for(i=(*L).length-1;i>=p;i--){ // 疑惑這里i+1,不會越界嗎? (*L).data[i+1] = (*L).data[i]; } // 騰出位置,賦值 (*L).data[p]=e; ++((*L).length); return 1; } //創建順序表 *L指針 void createList(Sqlist *L,int n){ int i,num; for(i =0;i<n;i++){ printf("請輸入第,%d,個整數",i+1); scanf("%d",&num); // *L取值 (*L).data[i]=num; (*L).length++; } }
