[英]forward declaration of a struct in C?
#include <stdio.h>
struct context;
struct funcptrs{
void (*func0)(context *ctx);
void (*func1)(void);
};
struct context{
funcptrs fps;
};
void func1 (void) { printf( "1\n" ); }
void func0 (context *ctx) { printf( "0\n" ); }
void getContext(context *con){
con=?; // please fill this with a dummy example so that I can get this working. Thanks.
}
int main(int argc, char *argv[]){
funcptrs funcs = { func0, func1 };
context *c;
getContext(c);
c->fps.func0(c);
getchar();
return 0;
}
我在这里遗漏了一些东西。 请帮我解决这个问题。 谢谢。
结构体(没有 typedef)在使用时通常需要(或应该)与关键字 struct 一起使用。
struct A; // forward declaration
void function( struct A *a ); // using the 'incomplete' type only as pointer
如果您对结构进行 typedef,则可以省略 struct 关键字。
typedef struct A A; // forward declaration *and* typedef
void function( A *a );
请注意,重用结构名称是合法的
尝试将代码中的前向声明更改为:
typedef struct context context;
添加一个后缀来指示结构名称和类型名称可能更具可读性:
typedef struct context_s context_t;
尝试这个
#include <stdio.h>
struct context;
struct funcptrs{
void (*func0)(struct context *ctx);
void (*func1)(void);
};
struct context{
struct funcptrs fps;
};
void func1 (void) { printf( "1\n" ); }
void func0 (struct context *ctx) { printf( "0\n" ); }
void getContext(struct context *con){
con->fps.func0 = func0;
con->fps.func1 = func1;
}
int main(int argc, char *argv[]){
struct context c;
c.fps.func0 = func0;
c.fps.func1 = func1;
getContext(&c);
c.fps.func0(&c);
getchar();
return 0;
}
#include <stdio.h>
struct b; // not needed because:
struct a {
struct b * pb; //this member definition also forward declares struct b
int c;
};
typedef struct a a // needed for a but not struct a because:
struct b {
struct a* pa; //this member definition also forward declares struct a
a * pa1;
void * c;
};
int main() {
printf("Hello, world!");
return 0;
}
基本上,您永远不需要自己转发声明struct b
,因为当您使用它执行纯声明时,它总是在行本身上声明部分类型,因此这是多余的代码。 这种类型的前向声明的唯一好处是它可以与 typedef 一起使用。 在 C++ 中,您不需要 typedef,因为 struct 和 typedefs 在同一个标识符命名空间中,因此struct b
变得有用,因为它现在声明了b
,因此您将在 C++ 中看到它。
重点是如果该类型在您使用它来声明实际上是暂定定义而不是不是指针的声明(因此在文件/块范围内没有extern
struct ef
)之前没有完成,或者如果您如果它是一个指针,则尝试取消引用该指针,那么您将得到一个不完整的类型错误。
所以它更像是允许您使用不完整的类型。 忘记前向声明,因为这不是一个单独的动作。 它是struct g* h
行的一部分。 您永远不需要使用其他东西实际需要的前向声明(除非它是 typedef),因为它有自己行的前向声明部分。
能够使用不完整的类型允许稍后在使用之前完成该类型。 您通常会看到前向声明的好处被解释为在使用指向类型的指针时不必在 C++ 中包含包含完整定义的标头,只需要执行class bar
然后bar *
,或者当然只使用class bar*
而没有class bar
线,如果从未使用过此特定成员。
它也不允许您使用大小不完整的类型作为结构成员(如果大小未知,直到包含此类代码),即使该结构从未用于声明/定义变量。 我认为这是因为结构是一种类型,当你提供一个类型的完整定义时,你只能做一次,它必须是完整的大小,而不是不完整的(具有未知大小的成员),所以该类型将无法使用。 含从来没有完整的结构这个结构被引用,而你可以用,而不是一个完整的类型与尺码不全(只要你不定义与它的任何东西)尺码不全引用一个不完整的类型,你可以参考,但不尊重,(一个地址可以存储在)一个不完整类型的指针,因为它有完整的大小。 您可以引用内存,只要其不完整的类型不包含不完整的大小。 允许在文件/块范围内使用extern struct ij
,因为除非在代码中引用j
,否则永远不需要它,此时类型必须完整。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.