2015-05-23 21 views
7

Hepimiz C bir yapı bildirmek için biliyorum:Bir yapının bildirilmesi: typedef struct name name;

struct Label1{ /* variables */ } Label2; // As I learned 

Ama bu kod 'struct adını' ilan olmadan çalışır neden bilmek istiyorum:

typedef struct name s_name; 

Ya aslında yazarak yapar

struct name; 

, "struct name" i boş bir yapı veya bunun gibi bir şey olarak bildirdiğimi mi? kod

Örnek:

İlk satır yapı Veri bir boşluk biri olarak ilan edilir varsa ben üyeleri ile redeclaring gibiyim
typedef struct Data Data; 
struct Data{ /*variables*/ }; 

ardından ikinci bu kadar.

Bu nokta için açıklama nedir?

+2

Cı yapıları nominal bir çeviri birimi içinde, yani tip kimlik adıyla belirlenir yazılır; 'struct name' yeni bir tür bildirmek için yeterlidir, ancak başka bir tam bildirim (aka tanımı) ile karşılaşılana kadar, bu tür eksik olacaktır; Tamamlanmamış türde nesneler için işaretçiler olabilir, ancak açıkça üyelere erişemez veya değişkenleri bildirmek için kullanamazsınız; eksik bir tip beyannamesi de ileri bir beyan olarak bilinir; bir tanesi opak isaretçilerdir – Christoph

+1

@Michael Heidelberg "Hepimiz C'deki bir yapının nasıl bildirileceğini biliyoruz" - sorunuzdan sonra bunun doğru olduğundan emin değilim. :) –

cevap

8

şey:

struct MyStruct; 

ileri referans denir. Tamamlanmamış bir tip oluşturur ve derleyiciye bu ismin bir türü olacağını söyler (ve bu bir yapı - aynı şekilde sendikalar için çalışır) ve detaylar "daha sonra takip et". Böyle bir türden, türü tamamlayana kadar değişkenleri tanımlayamazsınız.

typedef struct MyStruct MyType; 

Sadece bu yapı olacak tür adını tanımlar. Bu hala eksik bir tiptir.

MyType *my_t_pointer; 
struct MyStruct *my_s_pointer; 

tam deklarasyon sağladıklarında bir yapı aynı türden nesnelere işaretçileri olması için yararlıdır, "tamamlayarak" tipi:

Ancak, eksik bir türe bir işaretçi alabilir :

struct MyStruct { 
    struct MyStruct *next; 
}; 

Aslında bu liste, ağaç ve diğer tüm özyinelemeli veri yapıları için düğüm oluşturmak için tek yoldur. Bu C programlarının (bazen gizli) önemli bir parçasıdır. Ayrıca, bu mekanizma uygulama ayrıntılarını gizlemek için kullanılır. Üstbilgideki işlevlerin yalnızca yapının işaretçiyi almak/iletmek için var olduğunu bilmesi gerekir. Bu işlevlerin kullanılmasının yapının ayrıntılarını bilmesine gerek yoktur (ancak bu şekilde onu ayıramaz, böylece modül yapının ayrıntılarını bilmesi gereken tüm yönleri kapsamalıdır). Tam beyan sadece modülün uygulama dosyasında yer almaktadır.Onlar basit bir şekilde bilinmeyen olarak Bu işaretçileri yapının alanlarını erişmek yani tek "bakmak" olamaz gibi "opak" denir.

my_module.h:

struct MyStruct; 

extern void my_init(struct MyStruct *obj); 

my_module.c:

struct MyStruct { 
    int f1; 
    ... 
}; 

my_init(struct MyStruct *obj) 
{ 
    ... 
} 
+0

Anladım; Bu açıklama için teşekkür ederim. –

2

değişkenleri ilan edebilir, böylece typedef, yapı adı için bir takma ad olarak s_name beyan örn:

s_name *sptr; 

struct name; 

adı denilen bir yapı tipi tanımlayan olmadan orada olduğunu beyan çizgi bu içerik. Bu genellikle yapı türüne işaretçisi olarak değişkenler bildirebilmek için yapılır. Tanımlanana kadar gerçek yapı türünün değişkenlerini bildiremezsiniz. gibi

+1

Burada iki notasyon olduğunu anlıyorum: yapı; ve içeriğini tanımlamak? –

+0

Genellikle bunlar birleştirilir, ancak içeriğini tanımlamaksızın bir yapı tipi bildirmek mümkündür. Bu eksik bir deklarasyon, ayrıca Christoph'un yorumuna da bakınız. –