本文介绍了可以在其作用域之前使用结构标记吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的例子中:

#include <stdio.h>
#include <stdlib.h>

struct B b;
struct B{int a;}; 

struct B;

int main()
{
    b.a=3;
    printf("%d\n", b.a);
    return 0;
}

结构标签B的文件范围从它的第一个定义/声明struct B{int a;};开始.struct B b;如何在B的作用域之前引用B而不会出错?

The file scope of structure tag B starts from its first definition/declaration struct B{int a;};. How can struct B b; refer to B before B's scope without error?

struct B; 是结构类型声明,还是结构类型定义?为什么不和同一个文件作用域内的另一个定义struct B{int a;};冲突?

Is struct B; a structure type declaration, or a structure type definition? Why does it not conflict with the other definition struct B{int a;}; in the same file scope?

推荐答案

struct B; 是一个结构声明.同一个对象可以有任意数量的声明.对于具有多个可能声明的对象类型,声明必须兼容——例如,您可以为同一个函数使用多个原型,但它们需要使用相同的参数和返回类型.对于一个结构,只有一种方法可以声明它而不定义它,它只是说有一个结构叫做B".所以可以根据需要重复 struct B; 多次.

struct B; is a structure declaration. There can be any number of declarations of the same object. For the kinds of objects that have multiple possible declarations, the declarations have to be compatible — for example you can have multiple prototypes for the same function, but they need to use the same argument and return types. For a structure, there's only one way to declare it without defining it, and it just says "there's a structure called B". So it's ok to repeat struct B; as many times as you want.

struct B{int a;}; 是一个结构定义.一个给定的对象只能有一个定义.对象的某些用途需要事先定义,其他用途只需要事先声明.例如,您可以定义一个变量,其类型是指向未定义结构的指针:

struct B{int a;}; is a structure definition. There can only be one definition of a given object. Certain uses of an object require a prior definition, others only require a prior declaration. For example, you can define a variable whose type is a pointer to an undefined structure:

struct S;
struct S *p = NULL;

但是你不能定义一个类型为未定义结构的变量:

But you can't define a variable whose type is an undefined structure:

struct S;
struct S s = {0};

这种差异的原因是尚未定义的结构是不完整类型——编译器没有大小的类型.这不是定义指针​​的问题,但定义不完整类型的对象是个问题:编译器不知道需要多少内存.

The reason for this difference is that a structure that hasn't been defined yet is an incomplete type — a type for which the compiler doesn't have a size. This isn't a problem to define a pointer, but it is a problem to define an object of the incomplete type: the compiler wouldn't know how much memory is required.

此时,您可能想知道为什么 struct B b; 是可以的.毕竟,struct B 甚至还没有被声明,更不用说定义了.

At this point, you may wonder why struct B b; is OK. After all, struct B hasn't even been declared, let alone defined.

为什么没问题的第一部分是 struct B b; 顺便声明了结构 B.所以当需要 struct Bb 做一些事情的时候,结构刚刚被声明.

The first part of why it's ok is that struct B b; declares the structure B in passing. So by the time struct B is needed to do something with b, the structure has just been declared.

为什么没问题的第二部分是 struct B b; 不完全是一个定义.如果是定义,那么编译器需要知道要保留多少空间,不完整的类型是不行的.如果在函数中定义变量会发生这种情况:

The second part of why it's ok is that struct B b; is not exactly a definition. If it was a definition, then the compiler would need to know how much space to reserve, and an incomplete type would not be ok. This is what would happen if the variable was defined in a function:

void f(void) {
    struct B b; // error: storage size of ‘b’ isn’t known
}

但是当 struct B b; 位于文件的顶层时,它是一个暂定定义.暂定定义是声明;为此,不需要定义结构.当编译器到达文件末尾时,任何没有正确定义且需要定义的暂定定义都将成为定义.此时,需要定义结构.在您的示例程序中,b 有一个暂定定义,该定义成为文件末尾的正确定义.

But when struct B b; is at the top level of a file, it's a tentative definition. A tentative definition is a declaration; for this, the structure doesn't need to have been defined. When the compiler gets to the end of the file, any tentative definition that hasn't had a proper definition, and for which a definition is needed, becomes a definition. At this point, the structure needs to have been defined. In your example program, b has a tentative definition, and that definition becomes a proper definition at the end of the file.

如果变量未使用,则不定义结构体是可以的,因为如果未使用该变量,则声明一个类型不完整的变量是可以的.

It's ok to not define the structure if the variable is unused, because it's ok to declare a variable with an incomplete type if the variable is not used.

struct B b;
// end of file

但是如果以需要完整类型的方式使用该变量,则该结构必须在该点定义.

But if the variable is used in a way that requires a complete type, then the structure must have been defined at that point.

struct B b;
void f(void) {
    sizeof(b); // error: invalid application of ‘sizeof’ to incomplete type ‘struct B’
}
struct B{int a;}; // too late

这篇关于可以在其作用域之前使用结构标记吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 04:38