1. 程式人生 > 其它 >有關C++結構體定義和傳參的一些問題

有關C++結構體定義和傳參的一些問題

在做廣義表的題目時,在結構體的定義和傳參上出了一些問題,導致後續廣義表的實現上出錯,然後用了一個下午修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的地址傳入函式也能達到這個效果,但是我寫就會報錯,所以也算是一個遺留問題吧。