Yanıtlar:
Doğru kullanıldığında bu yararlı bir teknik olabilir.
Oldukça küçük bir genel arabirime ve çok sayıda yeniden kullanılamaz uygulama koduna sahip karmaşık, performans açısından kritik bir alt sisteminiz olduğunu varsayalım. Kod birkaç bin satıra, yüz kadar özel işleve ve epeyce özel veriye kadar çalışır. Önemsiz olmayan gömülü sistemlerle çalışıyorsanız, muhtemelen bu durumla yeterince sık başa çıkarsınız.
Çözümünüz muhtemelen katmanlı, modüler ve ayrıştırılmış olacaktır ve bu yönler, alt sistemin farklı bölümlerini farklı dosyalarda kodlayarak yararlı bir şekilde temsil edilebilir ve güçlendirilebilir.
C ile bunu yaparak çok şey kaybedebilirsiniz. Hemen hemen tüm araç zincirleri, tek bir derleme birimi için yeterli optimizasyon sağlar, ancak extern olarak bildirilen herhangi bir şey hakkında çok kötümserdir.
Her şeyi tek bir C kaynak modülüne koyarsanız, şunu elde edersiniz -
Performans ve kod boyutu iyileştirmeleri - birçok durumda işlev çağrıları satır içi olacaktır. Satır içi olmadan bile derleyicinin daha verimli kod üretme fırsatları vardır.
Bağlantı düzeyinde veri ve işlev gizleme.
Ad alanı kirliliğinden ve bunun sonucundan kaçınma - daha az kullanışsız adlar kullanabilirsiniz.
Daha hızlı derleme ve bağlantı.
Ancak konu bu dosyayı düzenlemek olduğunda da kötü bir karmaşa yaşarsınız ve zımni modülerliği kaybedersiniz. Bu, kaynağı birkaç dosyaya bölerek ve bunları tek bir derleme birimi oluşturmak için dahil ederek aşılabilir.
Bununla birlikte, bunu doğru bir şekilde yönetmek için bazı kurallar koymanız gerekir. Bunlar bir dereceye kadar alet zincirinize bağlı olacaktır, ancak bazı genel işaretçiler şunlardır:
Genel arayüzü ayrı bir başlık dosyasına koyun - bunu yine de yapmalısınız.
Tüm yardımcı .c dosyalarını içeren bir ana .c dosyasına sahip olun. Bu, genel arabirim kodunu da içerebilir.
Özel üstbilgilerin ve kaynak modüllerin harici derleme birimleri tarafından dahil edilmediğinden emin olmak için derleyici korumalarını kullanın.
Tüm özel veriler ve işlevler statik olarak beyan edilmelidir.
.C ve .h dosyaları arasındaki kavramsal farkı koruyun. Bu, mevcut kurallardan yararlanır. Aradaki fark, başlıklarınızda çok fazla statik bildirim olacak olmasıdır.
Araç zinciriniz bunu yapmamak için herhangi bir sebep belirtmiyorsa, özel uygulama dosyalarını .c ve .h olarak adlandırın. İçerme korumalarını kullanırsanız, bunlar kod üretmez ve yeni adlar getirmez (bağlantı sırasında bazı boş bölümlerle karşılaşabilirsiniz). En büyük avantajı, diğer araçların (örn. IDE'ler) bu dosyaları uygun şekilde ele almasıdır.
tamam mı? evet, derlenecek
tavsiye edilir mi no - .c dosyaları, derlemeden sonra (bağlayıcı tarafından) yürütülebilir dosyaya (veya kitaplığa) bağlanan .obj dosyalarına derlenir; bu nedenle, bir .c dosyasını diğerine eklemeye gerek yoktur. Bunun yerine muhtemelen yapmak isteyeceğiniz şey, diğer .c dosyasında bulunan işlevleri / değişkenleri listeleyen ve .h dosyasını içeren bir .h dosyası oluşturmaktır.
Hayır.
Oluşturma ortamınıza bağlı olarak (belirtmezsiniz), tam olarak istediğiniz şekilde çalıştığını görebilirsiniz.
Ancak, * .c'yi derlemeyi bekleyen birçok ortam (hem IDE'ler hem de birçok el yapımı Makefile) vardır - bu durumda büyük olasılıkla yinelenen semboller nedeniyle bağlayıcı hatalarıyla karşılaşacaksınız.
Kural olarak bu uygulamadan kaçınılmalıdır.
Kaynağı #include etmeniz gerekiyorsa (ve genellikle bundan kaçınmanız gerekiyorsa), dosya için farklı bir dosya soneki kullanın.
Ekibimin .c dosyalarını eklemeye karar verdiği bir durumu paylaşacağımı düşündüm. Mimarimiz büyük ölçüde bir mesaj sistemiyle ayrıştırılan modüllerden oluşur. Bu ileti işleyicileri geneldir ve işlerini yapmak için birçok yerel statik işçi işlevini çağırır. Bu özel uygulama kodunu kullanmanın tek yolu dolaylı olarak genel mesaj arabirimi aracılığıyla olduğundan, sorun, birim test durumlarımızı kapsamaya çalışırken ortaya çıktı. Bazı işçi fonksiyonları dizinin derinliklerinde olduğu için, bu, uygun kapsama alanı elde etmek için bir kabusa dönüştü.
.C dosyalarının dahil edilmesi, test etmede ilginç olduğumuz makinedeki dişliye ulaşmamız için bize bir yol sağladı.
Linux'taki gcc derleyicisini iki c dosyasını bir çıktıda birbirine bağlamak için kullanabilirsiniz. İki c dosyanız olduğunu varsayalım; biri 'main.c' ve diğeri 'support.c'. Dolayısıyla, bu ikisini bağlama komutu
gcc main.c support.c -o main.out
Bununla iki dosya tek bir çıktıya bağlanacaktır main.out Çıkışı çalıştırmak için komut olacaktır
./main.out
Support.c dosyasında bildirilen main.c'de bir işlevi kullanıyorsanız, bunu main içinde ayrıca extern depolama sınıfını da kullanarak bildirmelisiniz.
.C veya .CPP dosyalarını diğer kaynak dosyalara düzgün bir şekilde dahil edebilirsiniz. IDE'nize bağlı olarak, genellikle dahil edilmesini istediğiniz kaynak dosya özelliklerine bakarak, genellikle üzerine sağ tıklayıp özellikleri tıklayarak ve derleme / bağlantı / derlemeden dışlama veya herhangi bir seçeneğin işaretini kaldırarak / kontrol ederek çift bağlantıyı önleyebilirsiniz. olabilir. Ya da dosyayı projenin kendisine dahil edemezsiniz, bu nedenle IDE onun varlığını bile bilmeyecek ve derlemeye çalışmayacaktır. Ve makefiles ile dosyayı derlemek ve bağlamak için içine koymazsınız.
DÜZENLEME: Üzgünüm, diğer cevaplara cevap vermek yerine cevap verdim :(
C dili bu tür bir #include'ı yasaklamaz, ancak ortaya çıkan çeviri biriminin yine de geçerli olması gerekir C.
.Prj dosyasıyla hangi programı kullandığınızı bilmiyorum. "Make" veya Visual Studio gibi bir şey kullanıyorsanız veya herhangi bir şey kullanıyorsanız, dosya listesini bağımsız olarak derlenemeyenler olmadan derlenecek şekilde ayarladığınızdan emin olun.
C dosyasını başka bir dosyaya eklemek yasaldır, ancak bunu neden yaptığınızı ve neyi başarmaya çalıştığınızı tam olarak bilmediğiniz sürece yapılması tavsiye edilmez.
Neredeyse eminim ki, sorunuzun ardında, topluluğun size hedefinize ulaşmak için daha uygun başka bir yol bulmasının nedenini burada yayınlarsanız (lütfen "neredeyse" kelimesine dikkat edin, çünkü bağlam dikkate alındığında çözüm bu olabilir. ).
Bu arada sorunun ikinci bölümünü kaçırdım. C dosyası başka bir dosyaya dahil edilirse ve aynı zamanda projeye dahil edilirse, muhtemelen nesnelerin bağlanmasının nedeninin yinelenen sembol problemiyle karşılaşacaksınız, yani aynı işlev iki kez tanımlanacaktır (hepsi statik olmadıkça).