C++'ta Tipler Neden Önemlidir
Değişkenler sayfasında değerleri int age = 30; gibi açık bir tiple bildirdiniz. Bu tip yalnızca bir etiket değildir - derleyiciye kaç bayt ayıracağını, o baytları nasıl yorumlayacağını ve hangi işlemlerin geçerli olduğunu söyler. Tipi yanlış seçerseniz sessizce hassasiyet kaybedebilir, taşma yaşayabilir veya tanımsız davranışı tetikleyebilirsiniz.
C++ yerleşik tiplerini birkaç aileye ayırır: tam sayılar, kayan noktalı sayılar, bir karakter tipi ve bir boolean. Her birine bakalım, ardından insanların ayağını kaydıran kurallara değinelim.
Temel Tipler
İşte tek bir programda her temel tipten birer örnek. Literal son eklerine (L, f, u) ve char'daki tek tırnaklara dikkat edin:
Bir bool varsayılan olarak true/false değil, 1 veya 0 olarak yazdırılır. Bir char tek tırnak kullanır - 'A' tek bir karakterdir, oysa "A" (çift tırnak) bir string literalidir, tamamen farklı bir tiptir. Bu iki hata başlangıçta son derece yaygındır.
Boyutlar Sabit Değildir
Java gibi dillerden gelenler için en büyük sürpriz budur. C++ standardı yalnızca minimum boyutları ve göreceli bir sıralamayı (short ≤ int ≤ long ≤ long long) garanti eder. Gerçek boyut derleyicinize ve platformunuza bağlıdır. Her zaman sizeof ile kontrol edin:
Tipik bir 64 bit Linux derlemesinde int = 4, long = 8 görürsünüz. Ancak 64 bit Windows'ta long yalnızca 4 bayttır. Bu taşınabilirlik açığı, long'un 64 bit olduğunu varsayan kod yazmamanızın tam nedenidir.
Tam bir genişliğe ihtiyaç duyduğunuzda, <cstdint> içindeki sabit genişlikli tam sayı tiplerine başvurun:
Dosya biçimleri, ağ protokolleri veya tüm makinelerde aynı davranması gereken her şey için int32_t/int64_t kullanın. (int)a dönüşümüne dikkat edin - 8 bitlik bir tipi akışa göndermek onu sayı değil karakter olarak yazdırır, bu yüzden önce dönüştürün.
Signed ve Unsigned
Her tam sayı tipi iki çeşitte gelir. signed bir tip negatif değer tutabilir; unsigned bir tip tutamaz, negatif aralığı daha yüksek bir pozitif maksimumla takas eder. Düz int varsayılan olarak signed'dır.
İşaretsiz bir 0'dan çıkarma yapmak negatife gitmek yerine devasa bir pozitif sayıya döner. Bu insanları sürekli yakalar - özellikle .size() tarafından döndürülen size_t (unsigned bir tip) ile:
vector<int> v = {1, 2, 3};
// TEHLİKE: v.size() unsigned'dır. v boşsa, v.size() - 1 devasa bir sayıya
// döner ve döngü neredeyse sonsuza dek çalışır.
for (size_t i = 0; i <= v.size() - 1; i++) { /* ... */ }
i < v.size() tercih edin (asla <= size() - 1 değil) ya da bir aralık tabanlı for döngüsü ile sorunun tamamından kurtulun.
Tam Sayı Taşması Tanımsız Davranıştır
Unsigned sarmalamanın (iyi tanımlanmış) aksine, işaretli tam sayı taşması C++'ta tanımsız davranıştır. Derleyici her şeyi yapabilir - çöp döndürebilir, kontrolü optimize ederek kaldırabilir veya çökebilir:
Çözüm her dildeki taşma tuzağıyla aynıdır: aritmetiği daha geniş bir tipte yapın. Toplama 64 bitte gerçekleşsin diye +'dan önce bir işleneni long long'a dönüştürün. Sonucu sonradan dönüştürmek çok geçtir - taşma çoktan olmuştur.
Doğru Tipi Seçmek
Çoğu kod için varsayılanlar yeterlidir: tam sayılar için int, ondalıklar için double. Yalnızca bir nedeniniz olduğunda başka bir şeye başvurun.
| Tip | Tipik boyut | Şu durumda kullanın |
|---|---|---|
int | 32 bit | Tam sayılar için varsayılan |
long long | 64 bit | ~2 milyarın üzerindeki değerler: zaman damgaları, büyük sayaçlar |
double | 64 bit | Ondalıklar için varsayılan - iyi hassasiyet |
float | 32 bit | Hassasiyetin feda edilebileceği belleği kısıtlı diziler |
bool | 1 bayt | Bir true/false bayrağı |
int32_t / int64_t | tam | Platformlar arası biçimler, protokoller, bit işleme |
Akılda tutulması gereken birkaç tuzak. float'ın yalnızca yaklaşık 7 anlamlı ondalık basamağı vardır, bu yüzden 0.1f + 0.2f tam olarak 0.3 değildir - gerçekten bellek tasarrufu yapmanız gerekmiyorsa double tercih edin. Ayrıca char platforma bağlı olarak signed veya unsigned olabilir, bu yüzden ham baytlar üzerinde aritmetik yapıyorsanız signed char veya unsigned char olarak açıkça belirtin.
Sırada: auto Anahtar Sözcüğü
Tipi her seferinde yazmak yorucu olur ve bazen tip uzun ya da adlandırması zordur. C++ auto anahtar sözcüğüyle bunu sizin yerinize derleyicinin çıkarmasına izin verir - auto x = 42; x'i bir int yapar ve auto it = v.begin(); ayrıntılı bir yineleyici tipi yazmaktan sizi kurtarır. Sonraki sayfa auto'nun kodu ne zaman daha net hale getirdiğini, ne zaman fazlasını gizlediğini ele alıyor.
Sıkça Sorulan Sorular
C++'taki temel veri tipleri nelerdir?
Temel tipler tam sayılar (short, int, long, long long), kayan noktalılar (float, double, long double), karakter tipi char ve boolean tipi bool'dur. Her tam sayı tipi ayrıca signed veya unsigned olabilir. Geri kalan her şey - std::string, diziler, kendi sınıflarınız - bunların üzerine inşa edilir.
C++'ta int ile long arasındaki fark nedir?
İkisi de tam sayı saklar, ancak long'un en az int kadar geniş olması garanti edilir (64 bit platformlarda çoğunlukla 64 bit, ama Windows'ta yalnızca 32 bit). Standart yalnızca minimum boyutları sabitler, bu yüzden garanti bir genişlik için <cstdint> içindeki int32_t ve int64_t gibi sabit genişlikli tipleri kullanın.
C++'ta bir int kaç bittir?
Standart yalnızca int'in en az 16 bit olduğunu garanti eder, ancak hemen hemen her modern masaüstü ve sunucuda 32 bittir. Boyutlar platforma bağlı olduğundan asla varsayımda bulunmayın - kontrol etmek için sizeof(int) yazdırın veya tam bir genişliğe ihtiyacınız olduğunda int32_t gibi <cstdint> tiplerini kullanın.