bu yapı başka bir dosya tarafından kullanılacaksa func.c nasıl yapılır?
Bir dosyada (yani func.c dosyasında) bir tür kullanıldığında, görünür olması gerekir. Bunu yapmanın en kötü yolu, onu ihtiyaç duyulan her kaynak dosyaya kopyalayıp yapıştırmaktır.
Doğru yol, onu bir başlık dosyasına koymak ve gerektiğinde bu başlık dosyasını dahil etmektir.
yeni bir başlık dosyası açıp buradaki yapıyı bildirip bu başlığı func.c'ye ekleyelim mi?
Bu, daha çok sevdiğim çözüm, çünkü kodu oldukça modüler hale getiriyor. Yapınızı şu şekilde kodlardım:
#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME
struct a
{
int i;
struct b
{
int j;
}
};
#endif
Bu yapıyı kullanan işlevleri aynı başlığa koyardım ("arayüzünün" anlamsal olarak parçası olan işlev).
Ve genellikle, dosyayı yapı adından sonra adlandırabilir ve bu adı yeniden tanımlayıcı başlık korumalarını seçmek için kullanabilirim.
Yapıya bir işaretçi kullanarak bir işlev bildirmeniz gerekiyorsa, tam yapı tanımına ihtiyacınız olmayacaktır. Şunun gibi basit bir ileriye dönük beyan:
struct a ;
Yeter ve kuplajı azaltır.
veya başlık dosyasında toplam yapıyı tanımlayabilir ve bunu hem source.c hem de func.c'ye ekleyebilir miyiz?
Bu başka bir yoldur, biraz daha kolaydır, ancak daha az modülerdir: Çalışması için yalnızca sizin yapınıza ihtiyaç duyan bazı kodların yine de tüm türleri içermesi gerekir.
C ++ 'da, bu ilginç bir karmaşıklığa yol açabilir, ancak bu konu dışı (C ++ etiketi yok), bu yüzden ayrıntıya girmeyeceğim.
sonra bu yapının her iki dosyada da extern olarak nasıl ilan edileceği. ?
Belki konuyu göremedim ama Greg Hewgill'in gönderisinde çok iyi bir cevabı var. C'de birden fazla dosya tarafından kullanılacak bir başlıktaki bir yapı nasıl ilan edilir? .
daktiloyla yazalım o zaman nasıl?
- C ++ kullanıyorsanız, kullanmayın.
- C kullanıyorsanız, kullanmalısınız.
C struct yönetiminin bir acı olmasının nedeni: struct anahtar sözcüğünü kullanıldığı her yerde bildirmeniz gerekir:
struct MyStruct ; /* Forward declaration */
struct MyStruct
{
/* etc. */
} ;
void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}
Typedef ise struct anahtar sözcüğü olmadan yazmanızı sağlar.
struct MyStructTag ; /* Forward declaration */
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}
Yapı için hala bir isim tutmanız önemlidir . Yazı:
typedef struct
{
/* etc. */
} MyStruct ;
sadece yazılı bir adla anonim bir yapı oluşturacak ve bunu ileri-bildiremeyeceksiniz. Bu nedenle, aşağıdaki biçimi koruyun:
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
Böylece, struct anahtar sözcüğünü eklemekten kaçınmak istediğiniz her yerde MyStruct'ı kullanabilir ve bir typedef çalışmadığında (yani ileriye dönük bildirim) MyStructTag'i kullanmaya devam edebilirsiniz.
Düzenle:
Jonathan Leffler'ın haklı olarak belirttiği gibi, C99 yapı bildirimi hakkındaki yanlış varsayım düzeltildi .
2018-06-01'i düzenleyin:
Craig Barnes yorumunda bize yapı "etiket" adı ve "typedef" adı için ayrı adlar tutmanıza gerek olmadığını hatırlatır, yukarıda açıklık uğruna yaptığım gibi.
Aslında, yukarıdaki kod şu şekilde yazılabilir:
typedef struct MyStruct
{
/* etc. */
} MyStruct ;
IIRC, bu aslında C ++ 'nın C ile uyumlu kalmasını sağlamak için perde arkasında daha basit yapı bildirimiyle yaptığı şeydir:
// C++ explicit declaration by the user
struct MyStruct
{
/* etc. */
} ;
// C++ standard then implicitly adds the following line
typedef MyStruct MyStruct;
C'ye dönersek, her iki kullanımı da gördüm (ayrı isimler ve aynı isimler) ve hiçbirinin bildiğim dezavantajları yok, bu yüzden aynı ismi kullanmak , yapılar ve diğer semboller için C ayrı "isim alanları" kullanmıyorsanız okumayı kolaylaştırır .
struct b
ama sonra yapıa
kullanılmayan bir tür bildirir (muhtemelen belki bir üye adı tanımlamalıdırk
iç yakın ayracı sonra ve noktalı virgülden önce.