C/C++前置声明

C/C++前置声明

1. 为什么需要前置声明

考虑如下的场景,当我们需要进行一个嵌套包含的结构体的时候,由于我们并没有先给出A或者B的完整定义,这样编译器会报错,因为A中包含了BB中又包含了A

typedef struct _A {
    int val,
    B b,			// 此时B还没定义,所以A定义不完全
} A;

typedef struct _B {
    int val,
    A a,			// A的定义不完全,导致B定义也不完全			
} B;

2. 前置声明

解决方法就是本文提到的前向声明。C语言中,结构体类型在声明之后,未正式定义之前是一个不完全类型(incomplete type),即只知道其是一个类型,但不知道包含哪些成员。不完全类型只能用于定义指向该类型的指针,或声明使用该类型作为形参指针类型或返回指针类型的函数。指针类型对编译器而言大小固定(如32位机上为四字节),就不会出现编译错误。另外,声明使用该类型作为形参或返回类型的函数也是可以的,因为函数名本身也是地址。

前向声明允许你在不需要完整定义结构体的情况下,声明结构体指针或结构体成员。只要你不需要访问该结构体的具体成员,前向声明就足够了。这也是 C 语言中一种常见的技术,用来减少头文件之间的依赖关系。

需要注意的是,在使用前置声明的时候,我们只能定义为指针,因为前置声明只是告诉编译器有这种类型,并没有给出具体的定义,所以当我们进行实例化的时候,需要为其分配内存空间,由于还不知道类型大小,这样一样会报错,使用指针就能避免这个问题

typedef struct _B B;	// 前置声明
 
typedef struct _A
{
    int a;
    int b;
    B c;		// 实例化,为其分配内存空间,报错
}A;
 
struct _B
{
    int a;
    int b;
    A c;
};

正确的用法应该如下:

#include <stdio.h>
typedef struct _B B;  // 前置声明 B

typedef struct _A {
    int val;
    B *b;             // 修改为指向 B 的指针
} A;

struct _B {            // 这里不再使用 typedef
    int val;
    A a;
};

int main(){
    A a;
    B b;

    a.val = 10;
    a.b = &b;
    b.val = 20;
    b.a.val = 30;

    printf("A.val: %d\n", a.val);
    printf("B.val: %d\n", b.val);
    printf("B.a.val: %d\n", b.a.val);
    return 0;
}

编译通过后输出:

A.val: 10
B.val: 20
B.a.val: 30

Reference

[1]C语言前向声明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值