c/c++ 结构体嵌套

在写图的邻接表实现的时候,发现这个数据结构的实现实在是有点复杂,看得头晕,最主要还是因为有很多的结构体嵌套,并且在看的时候没有感觉出来,但实际上实现操作的时候,多层的嵌套还是有一点让我迷糊的。

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申请内存。
不过要注意的是,根据结构体内的结构体的引用方式的不同,访问的方式也需要更改成为对应的合法方式:如果是指针,那么使用箭头访问;如果是声明,那么使用点操作符进行访问。