什么是'前向声明'以及'typedef struct X'和'struct X'之间的区别?

r_g*_*yal 50 c struct typedef

我是C编程的初学者,我知道struct type declaration和typedef struct declaration之间的区别.我遇到了一个答案,说如果我们定义一个结构,如:

typedef struct { 
    some members;
} struct_name;
Run Code Online (Sandbox Code Playgroud)

然后它就像为匿名结构提供别名(因为它没有标记名称).所以它不能用于前瞻性声明.我不知道"前瞻性宣言"是什么意思.

另外,我想知道以下代码:

typedef struct NAME { 
    some members;
} struct_alias;
Run Code Online (Sandbox Code Playgroud)

有什么区别structtypedef?或者两者都相等,因为struct_alias是struct NAME的别名?

此外,我们可以声明类似的变量struct:

struct_alias variable1;
Run Code Online (Sandbox Code Playgroud)

和/或喜欢:

struct NAME variable2;
Run Code Online (Sandbox Code Playgroud)

或者喜欢:

NAME variable3; 
Run Code Online (Sandbox Code Playgroud)

Ser*_* L. 55

struct当您需要循环结构声明时,前向声明可能很有用.例:

struct a {
    struct b * b_pointer;
    int c;
};

struct b {
    struct a * a_pointer;
    void * d;
};
Run Code Online (Sandbox Code Playgroud)

什么时候struct a宣布它还不知道规格struct b,但你可以转发参考它.

当你输入一个匿名结构时,编译器将不允许你在typedef之前使用它的名字.

这是非法的:

struct a {
    b * b_pointer;
    int c;
};

typedef struct {
    struct a * a_pointer;
    void * d;
} b;

// struct b was never declared or defined
Run Code Online (Sandbox Code Playgroud)

这虽然合法:

struct a {
    struct b * b_pointer;
    int c;
};

typedef struct b {
    struct a * a_pointer;
    void * d;
} b;

// struct b is defined and has an alias type called b
Run Code Online (Sandbox Code Playgroud)

这是这样的:

typedef struct b b;
// the type b referes to a yet undefined type struct b

struct a {
    b * struct_b_pointer;
    int c;
};

struct b {
    struct a * a_pointer;
    void * d;
};
Run Code Online (Sandbox Code Playgroud)

还有这个:

typedef int b;

struct a {
    struct b * struct_b_pointer;
    b b_integer_type;
    int c;
};

struct b {
    struct a * a_pointer;
    void * d;
};

// struct b and b are two different types all together. Note: this is not allowed in C++
Run Code Online (Sandbox Code Playgroud)


das*_*ght 23

Forward declaration is a promise to define something that you make to a compiler at the point where the definition cannot be made. The compiler can use your word to interpret other declarations that it would not be able to interpret otherwise.

A common example is a struct designed to be a node in a linked list: you need to put a pointer to a node into the struct, but the compiler would not let you do it without either a forward declaration or a tag:

// Forward declaration
struct element;
typedef struct {
    int value;
    // Use of the forward declaration
    struct element *next;
} element; // Complete definition
Run Code Online (Sandbox Code Playgroud)

and so it cant be used for forward declaration

I think that author's point was that giving your struct a tag would be equivalent to a forward declaration:

typedef struct element {
    int value;
    // No need for a forward declaration here
    struct element *next;
} element;
Run Code Online (Sandbox Code Playgroud)


Mar*_*Łoś 13

前向声明是实际定义之前的声明,通常用于在定义不可用时能够引用声明的类型.当然,并非所有事情都可以通过声明未定义的结构来完成,但在某些情况下可以使用它.这种类型称为不完整,并且对其使用有许多限制.例如:

struct X; // forward declaration

void f(struct X*) { }  // usage of the declared, undefined structure

// void f(struct X) { }         // ILLEGAL
// struct X x;                  // ILLEGAL
// int n =sizeof(struct X);     // ILLEGAL

// later, or somewhere else altogether
struct X { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

这可以用于例如打破循环依赖关系或减少编译时间,因为定义通常要大得多,因此需要更多资源来解析它.

在你的榜样,struct NAME并且struct_alias确实是等价的.

struct_alias variable1;
struct NAME variable2;
Run Code Online (Sandbox Code Playgroud)

是正确的;

NAME variable3;
Run Code Online (Sandbox Code Playgroud)

不是,因为在C struct中需要关键字.


Gan*_*har 8

struct_alias并且struct NAME是相同的,struct_alias是别名struct NAME

这些都是相同的并且允许

struct_alias variable1;  

struct NAME variable1; 
Run Code Online (Sandbox Code Playgroud)

这是非法的

NAME variable3;   
Run Code Online (Sandbox Code Playgroud)

请参阅有关前向声明的这篇文章