[英]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.