有關C++結構體定義和傳參的一些問題
阿新 • • 發佈:2021-11-10
在做廣義表的題目時,在結構體的定義和傳參上出了一些問題,導致後續廣義表的實現上出錯,然後用了一個下午修BUG。在此記錄一下收穫。
結構體定義
使用typedef定義
typedef struct GLNode
{
int tag;
union
{
char atom;
struct
{
struct GLNode *hp,*tp;
}ptr;
};
}*GList;
GList A; //A是一個指標!
這種寫法可以理解為給結構體取了一個別名。(資料結構書上基本都是這樣使用的)
在這裡,我們給結構體GLNode取了一個別名:“GList”,前面加*的意思是創建出來的東西是指標,不過我覺得這種寫法很奇怪就是了,而且它還能做到一些struct做不到的事情(伏筆)
使用struct定義
struct GLNode
{
int tag;
union
{
char atom;
struct
{
struct GLNode *hp,*tp;
}ptr;
};
}*A;
創建出來的結構體名字就是GLNode,同時定義了一個A指標。
傳參和分配地址空間
想要達到的效果:把指標a傳入函式,並在函式內分配記憶體空間並讓指標a指向其地址,正確的輸出應為11。(這是建立廣義表時需要的操作)
struct ABC { int num; }*a; void dos(ABC *x) { x=(ABC *)malloc(sizeof(ABC)); x->num=1; printf("%d",x->num); } int main() { a=(ABC *)malloc(sizeof(ABC)); a->num=2; dos(a); printf("%d",a->num); return 0; }
這個程式的輸出為12。簡單解釋的話就是彷彿把指標傳了進去,但實則沒傳。具體原因如下:
1.把指標a所指的地方賦給指標x
2.分配記憶體空間並讓x指向其地址
發現沒,我們把a所指向的地址給了x,之後x又獲得了開闢空間後的新地址,也就覆蓋了a所指的地址,所以相當於根本沒把a傳入函式。
所以想要達到傳入的目的,就只能使用引用傳參了(這句話不完全對,看最後一句話)(話說個人感覺引用傳參是唯一一種真正把引數傳入函式的方法欸)
這個時候新的問題就出現了:引用傳遞好像傳遞不了指標...總不能ABC &*A這麼寫吧
但也不是完全傳不了,這時候就要請typedef出場了(伏筆回收)
typedef struct ABC { int num; }*NEWABC; NEWABC a; void dos(NEWABC &x) { x=(NEWABC)malloc(sizeof(ABC)); //注意malloc格式的改變 x->num=1; printf("%d",x->num); } int main() { a=(NEWABC)malloc(sizeof(ABC)); a->num=2; dos(a); printf("%d",a->num); return 0; }
這個程式的輸出就是11了。當我們使用NEWABC進行取別名之後,指標a便能很輕鬆的被引用傳遞了,因此也就真正的把指標a傳入了函式從而實現了效果。
理論上來說感覺利用指標傳參把指標a的地址傳入函式也能達到這個效果,但是我寫就會報錯,所以也算是一個遺留問題吧。