SORU
12 Kasım 2008, ÇARŞAMBA


Bir C için C# geliştirici

Bir ben varım .NET geliştirici, ve daha önce VB6 ile çalıştı. Bu ortamlarda çok aşina oldum ve çöp toplama diller bağlamında çalışma. Ancak, ben şimdi yerel C ile benim skillset desteklemek ve kendimi biraz bunalmış bulmak istiyor. İronik bir şekilde, oldukça iyi işaretçiler ve bellek yönetimi kavramak var hissediyorum gibi yeni başlayanlar için her zamanki engellerden hayal ederdim şey değil. Bu benim için biraz kafa karıştırıcı bir şey çizgisinde daha fazla

  • Başvuran/diğer kütüphaneleri kullanarak
  • Açığabenimdiğerleri için kütüphaneleri kullanmak
  • Dize işleme
  • Veri türü dönüştürme
  • İyi bir proje yapısı
  • Kullanmak için yapılar (örn. veri # List<T> çok kullanılan C, çalışır C simiarly ne kullanabilirim?)

Neredeyse kullandığınız IDE bağlı gibi hissediyorum, kurallar farklı, belki de biraz daha evrensel bir şey arıyordum. Ya da en kötüsü, Microsoft derleyici/IDE kullanarak üzerinde duruldu. Ayrıca, açık olmak gerekirse, genel programlama uygulamaları hakkında hiçbir şey (Tasarım Desenleri, Kod Tamamlama, vb.) aramıyorum çok iyi bu konularda tecrübeli olduğumu hissediyorum.

CEVAP
12 Kasım 2008, ÇARŞAMBA


İşaretçiler ve bellek yönetimi iyi kavramak var diyorsun biliyorum, ama yine de önemli bir numara açıklamak istiyorum. Başparmak genel bir kural olarak,aslayeni/kullanıcı kodu silmek.

Her kaynak alma (ister bir senkronizasyon kilit, bir veritabanı bağlantısı veya bir yığın bellek veya başka bir şey olmalı alınan ve serbest) olmalıdır sarılı bir nesne, böylece yapıcı gerçekleştirir edinimi ve yıkıcı bültenleri kaynak. Tekniği RAII olarak bilinen ve temeldebellek sızıntıları önlemek için. Buna alış. C standart kütüphane açıkçası bu yoğun kullanır, orada nasıl çalıştığını bir fikir elde edebilirsiniz. Sorularınızı biraz atlama, List<T> eşdeğer DEMİRYOLU bellek yönetmek için kullanır std::vector<T>, ve. Böyle bir şey kullanmak istiyorum:

void foo() {

  // declare a vector *without* using new. We want it allocated on the stack, not
  // the heap. The vector can allocate data on the heap if and when it feels like
  // it internally. We just don't need to see it in our user code
  std::vector<int> v;
  v.push_back(4);
  v.push_back(42); // Add a few numbers to it

  // And that is all. When we leave the scope of this function, the destructors 
  // of all local variables, in this case our vector, are called - regardless of
  // *how* we leave the function. Even if an exception is thrown, v still goes 
  // out of scope, so its destructor is called, and it cleans up nicely. That's 
  // also why C   doesn't have a finally clause for exception handling, but only 
  // try/catch. Anything that would otherwise go in the finally clause can be put
  // in the destructor of a local object.
} 

Eğer bir C programcısı öğrenmesi ve benimsemesi gereken bir tek ilke seçmek zorunda kalsaydım, yukarıda. Ölçüm kuralları ve yıkıcılar sizin için çalışmasına izin verin. Güvenli kod yazmak için gerekli tüm garantiler sunuyoruz.

İşleme dize:

std::string arkadaşın var. C, char dizileri kullanmak istiyorum (veya char işaretçiler), ama bu dizeleri gibi davranmaları yok çünkü kötü. C , bir std::beklediğiniz gibi davranan string sınıfı. Akılda tutulması gereken tek şey "hello world" tür char[12] ve std::string. (C uyumluluk), bu yüzden bazen senin için açıkça dönüştürme dize (bir şey tırnak içinde, "Merhaba Dünya") için bir std::string almak için davranış. Hala yazabilirsiniz

std::string s = "hello world";

C-stil dizeleri (çünkü rakamları, gibi gibi "Merhaba Dünya") std örtük olarak dönüştürülebilir::string, ama bu her zaman işe yaramaz: "" "dünya" operatörü iki işaretçiler için tanımlı değil çünkü derleme, olmaz.selam "" 'd' ancak . Merhaba Dünya ^em>derleme, ama bir şey mantıklı olmaz. Bir dize bir karakter eklemek yerine, char int ' e terfi edecek olan ayrılmaz bir değer almak ve bu değişkenin değerini ekleyin.

std::string("Merhaba Dünya") "d" gibi bir şey kalmamış ancak, çünkü Sol tarafta zaten bir std::string, ve ayrıca operatör aşırı yüklenmesi için std::string gibi bir şey kalmamış, hatta zaman sağ tarafına bir char* ya da tek bir karakter.

Dizeleri son bir not: ::standart bir dize tek baytlık bir veri türü olan char, kullanır. Yani, unicode metin için uygun değildir. C sağlar geniş karakter türü wchar_t olan 2 veya 4 bayt bağlı olarak, platform, ve tipik olarak kullanılan unicode metin (gerçi ne davası mı C standart gerçekten belirttiğiniz karakter kümesi). Ve wchar_t bir dize denir std::wstring.

Kitaplıkları:

, Temelde yok. C dili kütüphaneleri kavramı vardır, ve buna alışmak biraz vakit alır. Size sağlar #başka bir dosya (genellikle uzantısı .ile bir başlık dosyası vardır h ya .hes), ama bu sadece yapıştır/birebir kopyası. Bu kadar basit sadece iki dosya çeviri bir birim olarak adlandırılır ne sonuçlanan birleştirir. Birden fazla kaynak dosyaları genelde aynı başlıklar yer alacak, bu yüzden bu biraz herkesin bildiği ilginç olan C derleme modeli, anlamanın anahtarıdır bu yüzden bazı belirli koşullar altında çalışır. Yerine derleme bir grup ayrı bir modül ve exhanging bir çeşit meta arasında, bir C# derleyicisi, her çeviri birimidir derlenmiş izolasyon ve oluşturulan nesne dosyaları geçirilen bir linker sonra çalışır birleştirmek için ortak bit tekrar bir araya (eğer birden fazla çeviri birimleri dahil aynı başlık, aslında var kodunu kopyaladım arasında çeviri birimi, yani linker birleştirir onları geri içine bir tek tanımı) ;)

Tabii özel platform kütüphaneler yazmak için yolu vardır. Windows, yapabilirsiniz .dll veya .libs, bir fark ile .lib bir süre uygulamanıza bağlı .dll gibi uygulama ile paket var ayrı bir dosya .NET. Linux üzerinde, eşdeğer dan .böylece ve .bir, ve her durumda, insanlar kütüphaneler karşı geliştirebilmek için ilgili başlık dosyaları da temin etmeniz gerekmektedir.

Veri türü dönüştürme:

Tam olarak aradığınız, ama önemli olduğunu düşünüyorum bir nokta olan "geleneksel aşağıda kötü" olarak koyun . ne olduğundan emin değilim

int i = (int)42.0f; 

Bunun birçok sebebi vardır. İlk olarak, sırayla atmalarını birkaç farklı türde gerçekleştirmek için çalışır, ve derleyici uygulama sona erer tarafından sürpriz olabilir. İkinci olarak, sabit bir arama bulmak ve üçüncüsü, yeterince çirkin değil. Atmalarını genellikle iyi kaçınılır, C , biraz çirkin bunu hatırlatmak için yapılmışlar. ;)

// The most common cast, when the types are known at compile-time. That is, if 
// inheritance isn't involved, this is generally the one to use
static_cast<U>(T); 

// The equivalent for polymorphic types. Does the same as above, but performs a 
// runtime typecheck to ensure that the cast is actually valid
dynamic_cast<U>(T); 

// Is mainly used for converting pointer types. Basically, it says "don't perform
// an actual conversion of the data (like from 42.0f to 42), but simply take the
// same bit pattern and reinterpret it as if it had been something else). It is
// usually not portable, and in fact, guarantees less than I just said.
reinterpret_cast<U>(T); 

// For adding or removing const-ness. You can't call a non-const member function
// of a const object, but with a const-cast you can remove the const-ness from 
// the object. Generally a bad idea, but can be necessary.
const_cast<U>(T);

Gibi olacak unutmayın, bu yayınları çok daha özel, yani derleyici mı bir hata varsa bu atama geçersiz (aksine geleneksel sözdizimi, nerede olacağını sadece denemek yukarıdaki atmalarını bulana kadar işe yarayacak bir tane), ve büyük ve ayrıntılı, bu sayede size arama için, ve hatırlatıyor ... onlar kaçınılmalıdır mümkün. ;)

Standart kütüphane:

Son olarak, geri veri yapıları, standart kütüphane anlamak için çabalamalısın. Küçük, ama şaşırtıcı derecede çok yönlü ve nasıl kullanılacağını öğrenmek kez, çok daha iyi bir konumda olacak.

Standart kütüphane birkaç blok (kütüphane biraz zamanla birikmiş. bina oldukça farklı oluşur Parça olsaydı taşıdık gelen C. G/Ç akışları kitaplıkta kabul edilen bir yer ve konteyner sınıfları ve onların ilişkili işlevleri vardır kabul dan tamamen farklı bir kütüphane ve bir şekilde belirgin bir şekilde farklı. İkincisi genellikle STL (Standart Şablon Kütüphanesi) olarak bilinen bir parçası vardır. Açık konuşmak gerekirse, bu, biraz değiştirilmiş, C Standart Kütüphane içine sahiplenildi bu kütüphanenin adıdır.

STL anlamanın anahtarı "modern C ". Üç ayağı, kaplar, kullanımına ve algoritmaları oluşmaktadır. Özetle, konteyner kullanımına maruz ve yineleyici çift çalışma algoritmaları.

Aşağıdaki örnekte int bir vektör, bir bağlantılı liste, sadece örnek: uğruna ekler 1. Her element, ve kopyalar alır

int add1(int i) { return i 1; } // The function we wish to apply

void foo() {
  std::vector<int> v;
  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  v.push_back(5); // Add the numbers 1-5 to the vector

  std::list<int> l;

  // Transform is an algorithm which applies some transformation to every element
  // in an iterator range, and stores the output to a separate iterator
  std::transform ( 
  v.begin(),
  v.end(), // Get an iterator range spanning the entire vector
  // Create a special iterator which, when you move it forward, adds a new 
  // element to the container it points to. The output will be assigned to this
  std::back_inserter(l) 
  add1); // And finally, the function we wish to apply to each element
}

Yukarıdaki stil alışmak biraz zaman alıyor, ama son derece güçlü ve özlü. Dönüştürme işlevi şablon olduğu için, kabul edebilirherhangi birgiriş türleri olarak, sürece onlar yineleyicisi olarak davranır. Bunun anlamı, işlevi kullanılabilir için bir araya herhangi bir tür kaplar, hatta akarsu veya başka bir şey olabilir yineledi aracılığıyla sürece yineleyici için tasarlanmıştır ile uyumlu STL. Biz de başlangıç-bitiş çifti kullanmak zorunda değilsiniz. Sonunda yineleyici yerine, bir üçüncü unsuru işaret geçti ve algoritma sonra orada durur. Ya da tüm diğer öğeleri atlanır, ya da başka bir şeyi özel kullanımına yazılı yapabiliriz sevdik. Yukarıdaki üç ayağı her temel bir örnektir. Verilerimizi saklamak için bir kap kullanıyoruz, ama bu işlem için kullandığımız algoritma aslında konteyner bilmek zorunda değil. Sadece hangi işe yaramalı yineleyici aralığı bilmesine gerek yok. Ve elbette bu üç ayağı her zaman sorunsuz birlikte STL geri kalanı ile çalışacak olan yeni sınıflar, yazarak uzatılabilir.

Bir anlamda, bu işten geliyorsun beri çok benzer ETMENİZ için .NET, muhtemelen bazı benzerlikler görebilirsiniz. STL mevkidaşı biraz daha esnek olsa, biraz garip sözdizimi pahasına. :) Yorumlarda da belirtildiği gibi, aynı zamanda daha verimlidir. Genel olarak, varsıfırSTL algoritmaları Tepegöz, el-kodlu döngüler kadar verimli olabilir. Bu genellikle şaşırtıcı, ama tüm ilgili türleri derleme zamanında bilinen olduğundan, bu mümkündür şablonları çalışmak için bir gereklilik olan () ve C derleyicileri agresif satır içi eğilimindedir.)

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:
C++

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • cyriak

    cyriak

    29 Mart 2006
  • FrameCityJackal

    FrameCityJac

    4 Aralık 2010
  • Metheud

    Metheud

    9 EYLÜL 2006