打印
[应用相关]

C语言前向声明

[复制链接]
302|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
renzheshengui|  楼主 | 2023-12-21 09:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.问题引入

我们在使用C语言编写代码过程中,有时会遇到想要使用嵌套定义的这种情况,如下例:

typedef struct _A
{
    int a;
    int b;
    B c;
}A;

typedef struct _B
{
    int a;
    int b;
    A c;
}B;
A中使用了B,B中又使用了A,这种情况下,编译器会报错:

error: unknown type name ‘B’

原因很好理解,因为定义A时并没有B的定义,自然会报错。

2.解决方法

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

如果仅使用前向声明,而未注意将此类型变量定义为指针类型,就会报错。

例如:

typedef struct _B B;

typedef struct _A
{
    int a;
    int b;
    B c;
}A;

struct _B
{
    int a;
    int b;
    A c;
};
这里,使用“typedef struct _B B”对B进行了声明,告诉编译器B是一种类型,但是包含哪些成员并不知道,在A中定义了B,如果不知道B包含哪些成员,就无法知道A类型占用多少空间,这个很重要,因为A在实例化时,编译器要为其分配内存空间。因此,编译器报错:

error: field has incomplete type 'B' (aka 'struct _B')

从错误中,我们知道B正是我们上文提到的不完全类型。

将其定义为指针类型即可。

例如:

typedef struct _B B;

typedef struct _A
{
    int a;
    int b;
    B *c;
}A;

struct _B
{
    int a;
    int b;
    A c;
};
这样,编译器就不会报错了。

另外,声明使用该类型作为形参或返回类型的函数,如:

typedef struct _A A;

void Fun1(A *a);  //指针
void Fun2(A a);  //形参
A Fun3(void);  //返回值

struct _A
{
    int a;
    int b;
};
编译器也不会报错。
————————————————
版权声明:本文为CSDN博主「propor」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/propor/article/details/131723586

使用特权

评论回复
沙发
coshi| | 2024-1-2 16:41 | 只看该作者
对于变量 我们可以先声明在定义吗?

使用特权

评论回复
板凳
tpgf| | 2024-1-2 17:02 | 只看该作者
前向声明是利用了编译器的特性,编译器在编译的过程中只需要知道各个元素的名称和相应的大小就可以

使用特权

评论回复
地板
wiba| | 2024-1-2 20:50 | 只看该作者
前向声明能显著缩短编译链接时间

使用特权

评论回复
5
kxsi| | 2024-1-2 21:29 | 只看该作者
前向声明是不是只在c++语言才有啊

使用特权

评论回复
6
drer| | 2024-1-2 22:01 | 只看该作者
嵌套定义的有效范围是有什么说法吗

使用特权

评论回复
7
qcliu| | 2024-1-2 22:33 | 只看该作者
能不能解释一下什么叫做前向声明啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

78

主题

4079

帖子

2

粉丝