2010-08-14 24 views
33

C'nin kaynağında ve başlık dosyalarında şeylerin nasıl ayrılması gerektiğini anlamıyorum. Çoğu kez aynı ada sahip iki dosya grubuyla çok sayıda proje görüyorum (uzantıyı belirten kaynak ve başlık dosyalarını sans). Ben kütüphaneleri yazdım zamanC kaynak ve üstbilgi dosyaları arasındaki herhangi bir temel fark?

Şimdiye kadar, anlayış bu eksikliğinden, ben dosya uzantısı seçerek olarak kararsızlık ile bir dosya içine tüm sınıf ve sınıf yöntemi kodunu fırlatmış ettik.

başlıklarında nasıl olmalı ve kaynak dosyaları içinde neler olmalı? Bu ayrılığı nasıl uygularım?

cevap

43

hiçbir teknik fark yoktur. Derleyici, .c dosyasını eklemenize veya isterseniz .h dosyasını doğrudan derlemenize izin verir.

Bununla birlikte, büyük bir kültürel farkı:

  • Beyannameler (prototip) .h dosyalarına yazılır. .h dosya, ilgili .c dosyasında uygulanan ne olursa olsun arabirimi arabirimidir.

  • Tanımlar.c dosyalarına yazılır..h dosyasında belirtilen arabirimi uygularlar.

fark .h dosya (ve genellikle olacaktır) çoklu derleme birimlerine (.c dosyaları) içine #include d olabilir olmasıdır., .h dosyasındaki bir işlevi tanımladığınızda, birden çok .o dosyasında sona erer ve bağlayıcı, çok tanımlı bir simge hakkında şikayette bulunur. Bu nedenle, tanımların .h dosyalarında olmaması gerekir. Bir işlev bir .c dosyada tanımlanırsa

(Inline fonksiyonları. istisnadır) ve diğer .c dosyalarından kullanmak istiyorum, bu işlevin bir deklarasyon bu diğer .c dosyaların her biri mevcut olması gerekir. Bu yüzden bildirimi, her birinde .h ve #include'da bulabilirsiniz. Her bir .c dosyasındaki bildirimi de yineleyebilirsiniz, ancak bu çok sayıda kod çoğaltmasına ve sürdürülemez bir karışıklığa yol açar. Bir işlev bir .c dosyasında tanımlanır ama sen diğer .c dosyalarından bunu kullanmak istiyorsunuz Eğer

, başlığında beyan etmek gerek yoktur. Esasen bu .c dosyasının bir uygulama detayıdır. Bu durumda, static işlevini de yapın, böylece diğer dosyalarda aynı adlı işlevlerle çakışma olmaz.

+0

Ne yazık ki, standart hiçbir şey için yetki vermese de, kullandığım çoğu derleyici dosya uzantısına bir dereceye kadar bağımlıdır. Bunu deneyin: "header.c" ve "header.h" olarak adlandırılan ('int main() {return 0;} ') içeren iki dosya oluşturun ve bunları gcc ile derlemeye çalışın.(VS'ye yakın bir yere bile gitmiyorum!) – dirkgently

+0

Programcıların çoğunun .h dosyasındaki statik işlevlerin bildirimlerini koymadığından şüpheleniyorum. .h ve .c arasındaki temel fark, arayüz ve uygulama arasındadır. – Dipstick

+0

@dirkgently: Tamam, ancak derleyiciniz doğru dosya uzantısını almazsa bir C derleyicisi olarak davranmıyor. Standart, C derleyicileri olmayan programlar hakkında bir şey söylemez :) – Thomas

1

Genellikle başlık dosyaları deklarasyonlar, kaynak dosyaları kod içerir içermez. kaynak dosyada A.c size kaynak dosyada B.c uygulanan bir işlev gerekiyorsa

Yani, sadece kendi beyanı var B.h sayılabilir.

14

Başlıklarda ne olmalı ve kaynak dosyalarında ne olması gerekir? (Statik hariç)

  • Fonksiyon tanımlama (tipik olarak küresel)
  • Değişken bildiriminde
  • Kullanıcı tanımlı tür bildirimi (struct, union vb okuyun:

Tipik olarak başlık bir veya daha fazlasını ihtiva eden .)

  • Makro tanımlaması
  • Öte yandan

    Kaynak dosyalar vardır:

    • Fonksiyon/değişken tanımı
    • Statik fonksiyon beyanı ve tanımlı (müşterilerinize bu ortaya çıkarmak istemiyorum)
    • Değişken tanımı
    • Bazı bir başlık ben bu ayrılığı uygulamak nasıl

    satır içi işlevleri (C99) tanımlamak için tercih?

    One Definition Rule, arkadaşınızdır.

    Unutmayın, bir kitaplık yazıyorsanız, istemcinizin göreceği şey budur. Bu nedenle, kitaplığınızı kullanmaları için yardımcı olabilecekleri ve verebilecekleri tüm bilgileri sağlayın. Kaynak dosyalar tipik olarak ikili biçimde derlenir ve sunulur. Bu arada, C sınıf kavramlarına sahip değildir.

    +0

    'struct' benim için yeterince yakın :) –

    +2

    " Bir Tanımlama Kuralı "altın ise," Anlatma "gümüş. Bununla demek istediğim, özel ayrıntıları başlık dosyalarına koyma. Üçüncü taraf kitaplığı yaparsanız, gelecekte başlık dosyasında koyduğunuz her şeyi desteklemeniz gerekir. Büyük dosyalarda çalışırsanız, başlık dosyalarını en aza indirirseniz, başlık dosyalarını değiştirmeniz gerektiğinde derleme süresini kısaltacağından, refactoring'i artırır. (Merkezi başlık dosyalarını değiştirdiyseniz yeniden oluşturmanın 12 saat sürdüğü bir projede bulundum. 12hoursx # numberofdevelopers = money.) – FuleSnabel

    1

    .c ve .h dosyaları arasında çok az temel fark vardır (bazı derleyiciler bir raw .h dosyasını derlemeyi reddedebilir). Aradaki fark daha çok kongre.

    Genellikle .h dosyası API sağlar ve .c uygulamasını sağlar. Bu nedenle, .h dosyası .c dosyanızın sağladığı olanaklara erişmek için yalnızca diğer kaynak dosyalarının ihtiyaç duyduğu şeyleri içerecektir. Bu yüzden .h dosyaları, global işlevlerin prototiplerini, küresel değişkenlerin beyanlarını (gerçekten sahip olmanız gerekiyorsa) ve bunların kullandığı yapıları ve diğer türleri sağlayacaktır. (Yapı tarafından yalnızca bir işaretçi API tarafından isteniyorsa bir yapıya neden olmayın.)

    Hat içi işlevler genellikle .h dosyalarında da bulunur ancak bazı kodlama yönergeleri ayrı bir uzantının kullanımını tercih eder (örn .inl)

    Diğer tüm işlev uygulamaları, değişkenlerin tanımı ve başlatılması ve yerel (statik) değişkenlerin ve işlevlerin bildirimleri .c dosyasında yer alır.

    İlgili konular