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

浙公网安备 33010602011771号