c/c++ 结构体嵌套
2023-06-02
3 min read
在写图的邻接表实现的时候,发现这个数据结构的实现实在是有点复杂,看得头晕,最主要还是因为有很多的结构体嵌套,并且在看的时候没有感觉出来,但实际上实现操作的时候,多层的嵌套还是有一点让我迷糊的。
part.1
最开始遇到的就是嵌套结构体的声明,在我写初始化函数的时候就想到,如果只是声明分配最外层结构体的指针,那么内部的结构体是否正确的被创建属于它的内存地址?
#include<iostream>
typedef struct aaa{
int a, b;
}*apointer;
typedef struct bbb{
apointer a;
int c,d;
}*bpointer,b;
int main(){
using namespace std;
bpointer btest;
btest = new b;
btest -> c = 1;
cout<<(btest->c);
cout<<endl;
btest -> a -> a = 3;
cout<<(btest -> a -> a);
}
//输出
1
3
输出结果一如我所料,这一步就说明,如果结构体嵌套的是另一个结构体指针,那么外部结构体创建内存的时候,内部的也就被包含进去了。
part.2
但如果内部嵌套的是一个结构体声明而不是指针呢?
将上面的代码微调,将apointer类型定义为结构体而不是结构体指针,结果如下:
#include<iostream>
typedef struct aaa{
int a, b;
}apointer;
typedef struct bbb{
apointer a;
int c,d;
}*bpointer,b;
int main(){
using namespace std;
bpointer btest;
btest = new b;
btest -> c = 1;
cout<<(btest->c);
cout<<endl;
//1.
// btest -> a -> a = 3;
// cout<<(btest -> a -> a);
//2.
//btest -> a = new apointer;
//3.
(btest -> a). a = 3;
cout<<((btest -> a). a);
}
//输出
1
3
1会报错error: base operand of '->' has non-pointer type 'apointer' {aka 'aaa'}
,这是因为btest结构体中的a并不是一个指向结构体的指针,所以使用箭头->
访问成员会产生错误,因此修改使用点.
来访问,那么就没有问题(第三种情况);第二钟情况会报错error: base operand of '->' has non-pointer type 'apointer' {aka 'aaa'}
,同样是因为btest的a不是指针,因此new会产生类型不匹配的错误。
part.3
结论:结构体内的结构体,无论是指针还是结构体声明,都会在外部的结构体声明并创建对应内存这一过程中包含在内,因此没有必要再在结构体内new/malloc申请内存。
不过要注意的是,根据结构体内的结构体的引用方式的不同,访问的方式也需要更改成为对应的合法方式:如果是指针,那么使用箭头访问;如果是声明,那么使用点操作符进行访问。