Neden cpp dosyaları eklememeli ve bunun yerine bir başlık kullanmam gerekir?


147

Bu yüzden ilk C ++ programlama ödevimi bitirdim ve notumu aldım. Ama derecelendirmeye göre, için not kaybettim including cpp files instead of compiling and linking them. Bunun ne anlama geldiğinden çok açık değilim.

Koduma bir göz attığımda, sınıflarım için başlık dosyaları oluşturmamayı seçtim, ancak cpp dosyalarındaki her şeyi yaptım (başlık dosyaları olmadan iyi görünüyordu ...). Sınıflandırıcının '#include "mycppfile.cpp";' yazdığım anlamına geldiğini tahmin ediyorum. bazı dosyalarımda.

Benim #includecpp dosyaları için gerekçem şuydu: - Başlık dosyasına gitmek gerekiyordu her şey benim cpp dosyasında oldu, bu yüzden bir başlık dosyası gibi davrandı - maymun-görmek-maymun moda yapmak, diğer gördüm başlık dosyaları dosyalarda #include'd, bu yüzden aynı şeyi benim cpp dosyası için yaptım.

Peki tam olarak neyi yanlış yaptım ve neden kötü?


36
Bu gerçekten iyi bir soru. C ++ yeni başlayanlar bir sürü bu yardım alacak bekliyoruz.
Mia Clarke

Yanıtlar:


175

Bildiğim kadarıyla, C ++ standardı başlık dosyaları ve kaynak dosyaları arasında hiçbir fark bilmiyor. Dil ile ilgili olarak, yasal kod içeren herhangi bir metin dosyası diğerleriyle aynıdır. Ancak, yasadışı olmamakla birlikte, kaynak dosyaları programınıza dahil etmek, kaynak dosyalarınızı ilk etapta ayırmaktan elde edeceğiniz avantajları hemen hemen ortadan kaldıracaktır.

Temel olarak, ön işlemciye belirttiğiniz dosyanın tamamını almasını ve derleyici üzerine gelmeden önce onu etkin dosyanıza kopyalamasını #includesöyler . Bu nedenle, projenizdeki tüm kaynak dosyaları bir araya getirdiğinizde, yaptığınız şey ile temelde hiçbir ayırma olmadan büyük bir kaynak dosyası oluşturmak arasında temel bir fark yoktur.

"Ah, bu önemli değil. Eğer çalışırsa, sorun değil," Ağladığını duydum. Ve bir bakıma haklısın. Ama şu anda küçük bir küçük programla ve sizin için derlemek için hoş ve nispeten ipoteksiz bir CPU ile uğraşıyorsunuz. Her zaman çok şanslı olmayacaksın.

Ciddi bilgisayar programlama alanlarını araştırırsanız, düzinelerce değil milyonlarca kişiye ulaşabilecek hat sayıları olan projeler göreceksiniz. Bu çok fazla çizgi. Bunlardan birini modern bir masaüstü bilgisayarda derlemeye çalışırsanız, saniyeler yerine saatler sürebilir.

“Ah hayır! Bu kulağa korkunç geliyor! Ancak bu korkunç kaderi önleyebilir miyim ?!” Ne yazık ki, bu konuda yapabileceğiniz çok şey yok. Derlenmesi saatler sürüyorsa derlenmesi saatler sürüyor. Ama bu sadece ilk kez gerçekten önemli - bir kez derledikten sonra tekrar derlemek için bir neden yok.

Bir şey değiştirmedikçe.

Şimdi, dev bir devinimde birleştirilmiş iki milyon satırlık kodunuz varsa ve örneğin basit bir hata düzeltmesi yapmanız gerekiyorsa x = y + 1, bu, bunu test etmek için iki milyon satırın tümünü tekrar derlemeniz gerektiği anlamına gelir. Ve x = y - 1bunun yerine bir şey yapmak istediğinizi öğrenirseniz, yine, iki milyon satır derleme sizi bekliyor. Bu, başka bir şey yapmak için daha iyi harcanabilecek saatlerce harcanan zaman.

"Ama verimsiz olmaktan nefret ediyorum! Eğer kod tabanımın farklı kısımlarını tek tek derlemenin ve bir şekilde bunları bir şekilde bağlamanın bir yolu olsaydı !" Teoride mükemmel bir fikir. Ancak, programınızın farklı bir dosyada neler olduğunu bilmesi gerekiyorsa ne olur? Küçük minik .exe dosyalarını bir grup çalıştırmak istemiyorsanız kod tabanınızı tamamen ayırmak imkansızdır.

"Ama elbette mümkün olmalı! Aksi halde saf işkence gibi programlama geliyor! Ya arayüzü uygulamadan ayırmanın bir yolunu bulursam ? Bunları programın geri kalanına tanımlamak için bu farklı kod segmentlerinden yeterli bilgi alarak ve bunları bir tür başlık dosyasında mı? Ve bu şekilde, #include ön işlemci direktifini yalnızca derlemek için gerekli bilgileri getirmek için kullanabilirim ! "

Hmm. Orada bir şey üzerinde olabilirsiniz. Bunun sizin için nasıl çalıştığını bana bildirin.


13
Güzel cevap efendim. Eğlenceli bir okumaydı ve anlaşılması kolaydı. Keşke ders kitabım böyle yazılmış olsaydı.
06:09

@veol İlk kitap dizisini ara - C ++ sürümüne sahip olup olmadıklarını bilmiyorum. headfirstlabs.com
Amarghosh

2
Bu (kesin) duyduğum veya düşündüğüm en iyi ifade. Başarılı bir yeni başlayan Justin Case, henüz gönderilmemiş bir milyon tuş vuruşuyla bir projeye ulaştı ve gerçek bir kullanıcı tabanındaki uygulama ışığını gören övgüye değer bir "ilk proje", kapanışların ele aldığı bir sorun fark etti. OP'nin orijinal sorun tanımının ileri düzeylerine oldukça benzer sesler eksi "bunu yaklaşık yüz kez kodladı ve istisnalar ile programlama kullanmadan null (nesne olarak) ile null (yeğen gibi) için ne yapılacağını anlayamıyor."
Nicholas Jordan

Tabii ki bu, şablonlar için ayrı düşüyor çünkü çoğu derleyici 'dışa aktar' anahtar kelimesini desteklemiyor / uygulamıyor.
KitsuneYMG

1
Başka bir nokta sadece üstbilgi sınıfları kullanan birçok sanat kütüphaneleri (BOOST düşünürseniz) olması ... Ho, bekle? Deneyimli programcı arayüzü neden uygulamadan ayırmıyor? Cevabın bir kısmı Körü körünün söylediği şey olabilir, başka bir kısım mümkün olduğunda bir dosyanın ikiden daha iyi olması ve başka bir bölüm ise bağlantılamanın oldukça yüksek bir maliyete sahip olmasıdır. Programların doğrudan kaynak ve derleyici optimizasyonu ile on kat daha hızlı çalıştığını gördüm. Çünkü bağlantı çoğunlukla optimizasyonu engeller.
kriss

45

Bu muhtemelen istediğinizden daha ayrıntılı bir cevaptır, ancak bence iyi bir açıklama haklı.

C ve C ++ 'da, bir kaynak dosya bir çeviri birimi olarak tanımlanır . Kural olarak, başlık dosyaları işlev bildirimlerini, tür tanımlarını ve sınıf tanımlarını içerir. Gerçek işlev uygulamaları çeviri birimlerinde, yani .cpp dosyalarında bulunur.

Bunun arkasındaki fikir, işlevlerin ve sınıf / yapı üyesi işlevlerinin bir kez derlenip birleştirilmesidir, daha sonra diğer işlevler, bu kodu tek bir yerden yinelemeden çağırabilir. Fonksiyonlarınız dolaylı olarak "extern" olarak ilan edilir.

/* Function declaration, usually found in headers. */
/* Implicitly 'extern', i.e the symbol is visible everywhere, not just locally.*/
int add(int, int);

/* function body, or function definition. */
int add(int a, int b) 
{
   return a + b;
}

Bir işlevin çeviri birimi için yerel olmasını istiyorsanız, işlevi 'statik' olarak tanımlarsınız. Ne anlama geliyor? Bu, extern işlevlerine sahip kaynak dosyaları eklerseniz, derleyici aynı uygulamaya birden fazla kez rastladığından yeniden tanımlama hataları alırsınız. Böylece, tüm çeviri birimlerinizin işlev bildirimini görmesini istiyorsunuz, ancak işlev gövdesini görmüyorsunuz .

Peki sonunda bunların hepsi nasıl eziliyor? Bağlayıcının işi budur. Bir bağlayıcı, birleştirici aşaması tarafından oluşturulan tüm nesne dosyalarını okur ve sembolleri çözer. Daha önce söylediğim gibi, bir sembol sadece bir isimdir. Örneğin, bir değişkenin veya işlevin adı. İşlevleri çağıran veya tür bildiren çeviri birimleri bu işlevler veya türler için uygulamayı bilmiyorsa, bu sembollerin çözülmediği söylenir. Bağlayıcı, tanımlanmamış sembolü tutan çeviri birimini uygulamayı içeren çeviri birimiyle birleştirerek çözülmemiş sembolü çözer. Uf. Bu, kodunuzda uygulanmış veya ek bir kütüphane tarafından sağlanmış olsun, harici olarak görünen tüm semboller için geçerlidir. Bir kütüphane gerçekten sadece yeniden kullanılabilir kodlu bir arşivdir.

İki önemli istisna vardır. İlk olarak, küçük bir fonksiyonunuz varsa, bunu satır içinde yapabilirsiniz. Bu, üretilen makine kodunun harici bir işlev çağrısı üretmediği, ancak tam anlamıyla yerinde birleştirildiği anlamına gelir. Genellikle küçük olduklarından, havai boyut önemli değildir. Onların çalışma biçiminde statik olduklarını hayal edebilirsiniz. Böylece satır içi işlevlerin başlıklara uygulanması güvenlidir. Bir sınıf veya yapı tanımı içindeki işlev uygulamaları da derleyici tarafından otomatik olarak satır içine alınır.

Diğer istisna şablonlardır. Derleyicinin örnek oluştururken tüm şablon türü tanımını görmesi gerektiğinden, uygulamayı bağımsız işlevlerde veya normal sınıflarda olduğu gibi tanımdan ayırmak mümkün değildir. Belki şu anda bu mümkün, ancak "export" anahtar kelimesi için yaygın derleyici desteği almak uzun, uzun sürdü. Dolayısıyla, 'dışa aktarma' desteği olmadan çeviri birimleri, satır içi işlevlerin nasıl çalıştığına benzer şekilde, örneklenmiş şablonlanmış türlerin ve işlevlerin kendi yerel kopyalarını alır. 'İhracat' desteği ile durum böyle değil.

İki istisna dışında, bazı kullanıcılar satır içi işlevlerin, geçici işlevlerin ve geçici türlerin uygulamalarını .cpp dosyalarına koymayı "daha hoş" bulurlar ve sonra # .cpp dosyasını ekler. Bunun bir başlık veya kaynak dosya olması gerçekten önemli değildir; önişlemci umursamaz ve sadece bir sözleşmedir.

C ++ kodundan (birkaç dosya) ve son yürütülebilir dosyaya kadar tüm sürecin hızlı bir özeti:

  • Önişlemci bir '#' ile başlayan tüm direktifleri ayrıştırır, hangi çalıştırılır. #İnclude yönergesi, dahil edilen dosyayı daha düşük bir değerle birleştirir. Ayrıca makro değiştirme ve belirteç yapıştırma yapar.
  • Gerçek derleyici , önişlemci aşamasından sonra ara metin dosyasında çalışır ve derleyici kodunu yayar.
  • Montajcı montaj dosyası ve yayar makine koduna çalışır, bu genellikle bir denir nesne dosyası ve söz konusu ameliyat sisteminin ikili yürütülebilir biçimine uygundur. Örneğin, Windows PE'yi (taşınabilir yürütülebilir biçim) kullanırken Linux GNU uzantılarıyla birlikte Unix System V ELF biçimini kullanır. Bu aşamada, semboller hala tanımsız olarak işaretlenir.
  • Son olarak, bağlayıcı çalıştırılır. Önceki tüm aşamalar sırayla her çeviri biriminde yürütülmüştür. Ancak, bağlayıcı aşaması, birleştirici tarafından oluşturulan tüm oluşturulan nesne dosyalarında çalışır. Bağlayıcı, sembolleri çözer ve hedef platforma ve ikili formata bağlı olan bölümler ve segmentler oluşturmak gibi bir sürü sihir yapar. Programcıların bunu genel olarak bilmeleri gerekmez, ancak bazı durumlarda kesinlikle yardımcı olur.

Yine, bu kesinlikle istediğinizden daha fazlaydı, ama umarım incelikli ayrıntılar daha büyük resmi görmenize yardımcı olur.


2
Açıklamanız için teşekkür ederiz. İtiraf ediyorum, hepsi henüz benim için anlamlı değil ve sanırım cevabını tekrar tekrar okumam gerekecek.
ialm

1
Mükemmel bir açıklama için +1. çok kötü muhtemelen tüm C ++ yeni başlayanlar korkutmak olacaktır. :)
goldPseudo

1
Heh, kötü hissetme. Stack Overflow'da en uzun cevap nadiren en iyi cevaptır.

int add(int, int);bir işlev bildirimidir . Prototip bunun bir parçası adildir int, int. Bununla birlikte, C ++ 'daki tüm işlevlerin bir prototipi vardır, bu nedenle terim C'de gerçekten mantıklıdır.
Melpomene

exportiçin şablonlar 2011 yılında dilden kaldırılmıştır. Derleyiciler tarafından hiçbir zaman gerçekten desteklenmemiştir.
Melpomene

10

Tipik çözüm, .hdosyaları yalnızca bildirimler için ve .cppdosyaları uygulama için kullanmaktır. Uygulamayı yeniden kullanmanız gerekiyorsa, karşılık gelen .hdosyayı .cppgerekli sınıf / işlev / her ne olursa olsun dosyaya dahil edersiniz ve zaten derlenmiş bir .cppdosyaya ( .objgenellikle bir proje içinde kullanılan bir dosya - veya .lib dosyası - bağlantı) birden fazla projeden yeniden kullanım için). Bu şekilde, yalnızca uygulama değişirse her şeyi yeniden derlemenize gerek kalmaz.


6

Cpp dosyalarını bir kara kutu ve .h dosyalarını bu kara kutuların nasıl kullanılacağına dair kılavuzlar olarak düşünün.

Cpp dosyaları önceden derlenebilir. Bu kodu #include'da çalışmaz, çünkü kodu her derlediğinde programınıza gerçek "dahil etmek" gerekir. Yalnızca üstbilgiyi eklerseniz, önceden derlenmiş cpp dosyasının nasıl kullanılacağını belirlemek için üstbilgi dosyasını kullanabilir.

Bu, ilk projeniz için çok fazla fark yaratmasa da, büyük cpp programları yazmaya başlarsanız, insanlar sizden nefret edecekler, çünkü derleme zamanları patlayacak.

Ayrıca şunu da okuyun: Üstbilgi Dosyası İçerme Desenleri


Daha somut bir örnek için teşekkür ederim. Bağlantınızı okumaya çalıştım, ama şimdi kafam karıştı ... açıkça bir üstbilgi ve ileri bir bildirimi dahil etmek arasındaki fark nedir?
ialm

bu harika bir makale. Veol, burada derleyicinin sınıfın büyüklüğü hakkında bir bilgiye ihtiyaç duyduğu başlıkları içerir. İleri bildirimi yalnızca işaretçiler kullandığınızda kullanılır.
pankajt

ileri bildirimi: int someFunction (int neededValue); tip bilgilerinin kullanımına dikkat edin ve (genellikle) kıvırcık diş telleri kullanmayın. Bu, verildiği gibi, derleyiciye bir noktada int alan ve int döndüren bir işleve ihtiyaç duyacağınızı söyler, derleyici bu bilgiyi kullanarak bir çağrı ayırabilir. Buna ileri bir beyan denir. Daha ileri düzey derleyiciler, bir başlık ileri bildirimi bildirmenin kullanışlı bir yolu da dahil olmak üzere, buna ihtiyaç duymadan işlevi bulabileceklerdir.
Nicholas Jordan

6

Başlık dosyaları genellikle işlev / sınıf bildirimi içerirken, .cpp dosyaları gerçek uygulamaları içerir. Derleme zamanında, her .cpp dosyası bir nesne dosyasına (genellikle .o uzantısı) derlenir ve bağlayıcı çeşitli nesne dosyalarını son yürütülebilir dosyada birleştirir. Bağlama işlemi genellikle derlemeden çok daha hızlıdır.

Bu ayırmanın avantajları: Projenizdeki .cpp dosyalarından birini yeniden derliyorsanız, diğerlerini yeniden derlemenize gerek yoktur. Bu belirli .cpp dosyası için yeni nesne dosyasını oluşturursunuz. Derleyicinin diğer .cpp dosyalarına bakması gerekmez. Ancak, geçerli .cpp dosyanızdaki diğer .cpp dosyalarında uygulanan işlevleri çağırmak istiyorsanız, derleyiciye hangi bağımsız değişkenleri aldıklarını söylemeniz gerekir; başlık dosyalarını eklemenin amacı budur.

Dezavantajları: Belirli bir .cpp dosyasını derlerken, derleyici diğer .cpp dosyalarının içinde ne olduğunu 'göremez'. Bu nedenle, oradaki işlevlerin nasıl uygulandığını bilmiyor ve sonuç olarak agresif bir şekilde optimize edemiyor. Ama sanırım henüz bununla ilgilenmene gerek yok (:


5

Başlıklar sadece dahil edilir ve cpp dosyaları sadece derlenir. Bu, birçok cpp dosyanız olduğunda daha kullanışlı hale gelecektir ve bunlardan yalnızca birini değiştirdiğinizde tüm uygulamayı yeniden derlemek çok yavaş olacaktır. Veya dosyalardaki işlevler birbirine bağlı olarak ne zaman başlayacaktır. Bu nedenle, sınıf bildirimlerini başlık dosyalarınıza ayırmalı, cpp dosyalarında uygulama bırakmalı ve cpp dosyalarını derlemek ve ortaya çıkan nesne dosyalarını bir programa bağlamak için bir Makefile (veya kullandığınız araçlara bağlı olarak başka bir şey) yazmalısınız.


3

# Cpp dosyasını programınızdaki diğer birkaç dosyaya eklerseniz, derleyici cpp dosyasını birden çok kez derlemeye çalışır ve aynı yöntemlerin birden çok uygulaması olacağından bir hata oluşturur.

#İncluded cpp dosyalarında düzenlemeler yaparsanız derleme daha uzun sürer (bu büyük projelerde sorun haline gelir), bu da onları içeren # dosyaların yeniden derlenmesini zorlar.

Sadece bildirimlerinizi başlık dosyalarına koyun ve bunları (aslında kendi başına kod üretmedikleri için) ekleyin ve bağlayıcı, bildirimleri karşılık gelen cpp koduyla (daha sonra yalnızca bir kez derlenir) bağlar.


Daha uzun derleme sürelerine sahip olmanın yanı sıra, cpp dosyamı dahil edilen cpp dosyalarındaki işlevleri kullanan birçok farklı dosyaya dahil ettiğimde sorun yaşamaya başlayacağım?
ialm

Evet, buna isim alanı çarpışması denir. Burada ilgi çekici olan, kütüphanelere bağlamanın ad alanı sorunları getirip getirmediğidir. Genel olarak, derleyicilerin ad alanı sorunları tanıtan çeviri birimi kapsamı (hepsi tek bir dosyada) için daha iyi derleme süreleri ürettiğini görüyorum - bu da tekrar ayrılmaya neden oluyor .... her çeviri birimine dahil etme dosyasını dahil edebilirsiniz ( bunu zorlaması gereken bir pragma (#pragma) bile var, ama bu bir fitil. 32-bit bağlantıların uygulanmadığı yerlerde kütüphanelere (.O dosyaları) körü körüne güvenmemeye dikkat edin.
Nicholas Jordan

2

Yaptığınız gibi yapmak kesinlikle mümkün olsa da, standart uygulama, paylaşılan bildirimleri başlık dosyalarına (.h) ve işlevlerin ve değişkenlerin tanımlarını - uygulama - kaynak dosyalara (.cpp) koymaktır.

Bir kural olarak, bu her şeyin nerede olduğunu netleştirmeye yardımcı olur ve modüllerinizin arayüzü ve uygulaması arasında net bir ayrım yapar. Ayrıca, bir .cpp dosyasının başka bir dosyaya dahil edilip edilmediğini, birkaç farklı birimde tanımlanmışsa kırılabilecek bir şey eklemeden önce kontrol etmeniz gerekmediği anlamına gelir.


2

yeniden kullanılabilirlik, mimari ve veri kapsülleme

İşte bir örnek:

diyelim ki, bir sınıf gizeminde basit bir dize yordamı biçimi içeren bir cpp dosyası oluşturursanız, bunun için sınıf çıkartmasını mystring.cpp dosyasını bir .obj dosyasına derleyen bir mystring.h dosyasına yerleştirirsiniz.

şimdi ana programınıza (örn. main.cpp) üstbilgiyi ve mystring.obj bağlantısını ekleyin. mystring'i programınızda kullanmak için , üstbilginin ne yapabileceğini söylediği için mystring'in nasıl uygulandığı ile ilgilenmezsiniz.

şimdi bir arkadaşım mistik sınıfınızı kullanmak isterse ona mystring.h ve mystring.obj verirseniz, aynı zamanda çalıştığı sürece nasıl çalıştığını da bilmesine gerek yoktur.

daha sonra böyle daha fazla .obj dosyanız varsa, bunları bir .lib dosyasında birleştirebilir ve bunun yerine bağlantı oluşturabilirsiniz.

Ayrıca mystring.cpp dosyasını değiştirmeye ve daha etkili bir şekilde uygulamaya karar verebilirsiniz, bu main.cpp'nizi veya arkadaş programınızı etkilemez.


2

Eğer sizin için işe yarıyorsa, bununla ilgili yanlış bir şey yoktur - sadece bir şey yapmanın tek bir yolu olduğunu düşünen insanların tüylerini fırlatır.

Burada verilen cevapların çoğu büyük ölçekli yazılım projeleri için optimizasyonları ele almaktadır. Bunlar bilinmesi gereken iyi şeylerdir, ancak küçük bir projeyi büyük bir proje gibi optimize etmenin bir anlamı yoktur - "erken optimizasyon" olarak bilinen şey budur. Geliştirme ortamınıza bağlı olarak, program başına birden çok kaynak dosyasını desteklemek için bir yapı yapılandırması kurmada önemli bir karmaşıklık olabilir.

Zamanla proje geliştikçe, derleme işlemi çok uzun sürüyor fark ederseniz, o zaman yapabilirsiniz planı ayrı daha hızlı artan kurar için birden kaynak dosyaları kullanmak için kodunuzu.

Yanıtların birçoğu arayüzü uygulamadan ayırmayı tartışıyor. Bununla birlikte, bu, içerme dosyalarının doğasında olan bir özellik değildir ve uygulamalarını doğrudan içeren "başlık" dosyalarını dahil etmek oldukça yaygındır (C ++ Standart Kütüphanesi bile bunu önemli ölçüde yapar).

Yaptığınız şeyle ilgili "alışılmadık" tek şey, ".h" veya ".hpp" yerine ".cpp" dosyalarınızı adlandırmaktı.


1

Bir programı derleyip bağladığınızda, derleyici önce tek tek cpp dosyalarını derler ve sonra bunları bağlar (bağlar). İlk olarak bir cpp dosyasına dahil edilmedikçe başlıklar asla derlenmeyecektir.

Genellikle başlıklar bildirimlerdir ve cpp uygulama dosyalarıdır. Başlıklarda bir sınıf veya işlev için bir arabirim tanımlarsınız, ancak ayrıntıları gerçekte nasıl uyguladığınızı dışarıda bırakırsınız. Bu şekilde, bir değişiklik yaparsanız her cpp dosyasını yeniden derlemeniz gerekmez.


Uygulamayı başlık dosyasından çıkarırsanız özür dilerim ama bana Java arayüzü gibi geliyor değil mi?
gansub

1

John Lakos'un Büyük Ölçekli C ++ Yazılım Tasarımından geçmenizi öneririm . Üniversitede genellikle bu tür sorunlarla karşılaşmadığımız küçük projeler yazarız. Kitap arayüzlerin ve uygulamaların ayrılmasının önemini vurgulamaktadır.

Başlık dosyaları genellikle çok sık değiştirilmemesi gereken arabirimlere sahiptir. Benzer şekilde Sanal Yapıcı deyimi gibi kalıplara bakmak, konsepti daha iyi kavramanıza yardımcı olacaktır.

Hala senin gibi öğreniyorum :)


Kitap önerisi için teşekkürler. Yine de büyük ölçekli C ++ programları yapma aşamasına gidip edemeyeceğimi bilmiyorum ...
ialm

büyük ölçekli programları kodlamak ve birçoğu için bir meydan okuma eğlenceli.
Sevmeye başladım

1

Kitap yazmak gibi, bitmiş bölümleri sadece bir kez basmak istiyorsunuz

Diyelim ki bir kitap yazıyorsunuz. Bölümleri ayrı dosyalara koyarsanız, yalnızca bir bölümü değiştirdiyseniz yazdırmanız gerekir. Bir bölümde çalışmak diğerlerinden hiçbirini değiştirmez.

Ancak cpp dosyalarını dahil etmek, derleyicinin bakış açısından, kitabın tüm bölümlerini tek bir dosyada düzenlemek gibi. Daha sonra değiştirirseniz, gözden geçirilmiş bölümün yazdırılmasını sağlamak için kitabın tüm sayfalarını yazdırmanız gerekir. Nesne kodu oluşturmada "seçilen sayfaları yazdır" seçeneği yoktur.

Yazılıma geri dön: Linux ve Ruby src var. Kod satırlarının kabaca bir ölçüsü ...

     Linux       Ruby
   100,000    100,000   core functionality (just kernel/*, ruby top level dir)
10,000,000    200,000   everything 

Bu dört kategoriden herhangi birinin çok fazla kodu vardır, bu nedenle modülerliğe ihtiyaç vardır. Bu tür bir kod tabanı şaşırtıcı bir şekilde gerçek dünya sistemleri için tipiktir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.