有关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的地址传入函数也能达到这个效果,但是我写就会报错,所以也算是一个遗留问题吧。

posted @ 2021-11-10 22:13  CYHei_mu  阅读(260)  评论(0)    收藏  举报