Menu

C'de Veri Tipleri: int, float, char, double ve Daha Fazlası

Her C değişkeninin, boyutunu ve neyi tutabileceğini belirleyen bir tipi vardır. İşte tüm temel tipler, gerçek boyutları, işaretli ile işaretsiz, sizeof, limits.h ve taşmada ne olduğu.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

C'deki her değişkenin, onu bildirdiğinizde seçilen ve ömrü boyunca sabit kalan bir tipi vardır. Tip üç şeye karar verir: değişkenin kaç bayt kapladığına, o baytların nasıl yorumlanacağına ve onun üzerinde hangi işlemlerin anlamlı olduğuna.

C'nin tip listesi kısadır. Karmaşıklık değiştiricilerdedir.

Dört Temel Tip

  • char bir bayt tutar. Tek karakterler ('A'), bir metnin baytları ve bazen minik bir tam sayı olarak kullanılır.
  • int işçi atı tam sayı tipidir. Döngü sayaçları, boyutlar, kimlikler.
  • float ve double gerçel sayıları tutar. double'ın hassasiyeti kabaca iki katıdır.
  • void bir anlamda dördüncü tiptir, ama "değer yok" anlamına gelir - void bir değişken bildiremezsiniz; yalnızca fonksiyon dönüş tipi, boş parametre listesi ya da tipsiz gösterici olarak kullanabilirsiniz.

3.14f'teki f sonekine dikkat edin. Onsuz sabit bir double'dır ve onu bir float'a atamak hassasiyeti sessizce kaybeder. Bazı derleyiciler bunun için uyarır.

Değiştiriciler: short, long, unsigned

Temel tam sayı tipleri, boyutu ya da işareti değiştiren değiştiricilerle gelir.

Her tam sayı tipinin kendi biçim belirtecine ihtiyacı vardır: short için %hd, int için %d, long için %ld, long long için %lld, unsigned için %u. Yanlışını kullanmak bir yuvarlama hatası değil, tanımsız davranıştır.

unsigned işaret bitini kaldırır ve pozitif aralığı ikiye katlar. Bir unsigned int, -2,1 ile +2,1 milyar yerine 0 ile yaklaşık 4,3 milyar arasını tutar. Gerçekten negatif olamayacak şeyler için doğru seçimdir - boyutlar, bayt sayıları, bit örüntüleri - ve sıfırın altına çıkarılabilecek her şey için bir tuzaktır.

signed; int, short, long ve long long için varsayılandır, dolayısıyla neredeyse hiç yazmazsınız. Önemli olduğu tek yer char'dır: düz char'ın işaretli mi işaretsiz mi olduğu gerçekleştirime bağlıdır, o yüzden işaret önemliyse signed char ya da unsigned char yazın.

Boyutlar: Gerçekte Ne Elde Edersiniz

C standardı kesin boyutları değil asgari değerleri belirtir. Modern 64 bitlik herhangi bir Linux, macOS ya da Windows makinesinde şunu görürsünüz:

TipTipik boyutTipik aralık
char1 bayt-128 ile 127 (ya da 0 ile 255)
short2 bayt-32.768 ile 32.767
int4 bayt-2.147.483.648 ile 2.147.483.647
long8 bayt (Windows'ta 4)kabaca ±9,2 kentilyon
long long8 baytkabaca ±9,2 kentilyon
float4 bayt~7 anlamlı basamak
double8 bayt~15 anlamlı basamak
long double16 bayt (değişir)double'dan fazla

long satırı insanları yakalayanıdır: Linux ve macOS'ta 8 bayt, 64 bitlik Windows'ta 4 bayttır. long'un 64 bitlik bir değer tutabileceğini varsayan kod taşınabilir değildir. Boyut gereksinimin bir parçasıysa long long ya da stdint.h'deki kesin genişlikli tipleri (int32_t, uint64_t) kullanın.

sizeof: Derleyiciye Sorun

Bir boyutu asla tahmin etmeyin - ölçün:

sizeof bir fonksiyon değil, bir operatördür ve derleme zamanında değerlendirilir. Değeri %zu ile yazdırılan size_t tipindedir.

sizeof(char)'ın tam olarak 1 olması garantidir - C'de bir baytın tanımı budur. Diğer her şey ona göre ölçülür.

limits.h ve float.h

Derleyiciniz için kesin aralıklar adlandırılmış sabitler olarak mevcuttur:

Bir işlemin taşıp taşmayacağını bilmeniz gerektiğinde karşılaştıracağınız değerler bunlardır. a + b'yi hesaplamadan önce if (a > INT_MAX - b) kontrolü, taşmayı olmadan önce saptama yolunuzdur - ki bu önemlidir, çünkü işaretli taşmayı sonradan saptayamazsınız.

Tam Sayı Taşması

Bir değer tipinin aralığını aştığında ne olacağı tamamen işarete bağlıdır.

İşaretsiz taşma tanımlıdır: değer 2^N'e göre sarar.

O ikinci durum gerçek bir hata kaynağıdır. for (unsigned i = n - 1; i >= 0; i--) gibi bir döngü asla bitmez, çünkü işaretsiz bir değer her zaman >= 0'dır.

İşaretli taşma tanımsız davranıştır. "Sarar" değil - tanımsız. Derleyicinin bunun asla olmadığını varsayıp buna göre iyileştirme yapmasına izin verilir; bu da sonradan yazılmış bir taşma denetiminin silinebileceği anlamına gelir:

int sum = a + b;
if (sum < a) { /* derleyici bunu tamamen kaldırabilir */ }

Sınırları kullanarak önceden kontrol edin:

if (b > 0 && a > INT_MAX - b) {
    /* a + b taşardı - ele alın */
}

Kayan Nokta Hassasiyeti

float ve double sayıları ikili olarak saklar ve çoğu ondalık kesrin tam bir ikili biçimi yoktur - 1/3'ün tam bir ondalık biçiminin olmadığı gibi.

Bundan çıkan kural: kayan noktalı değerleri asla == ile karşılaştırmayın. Bunun yerine mutlak farkı küçük bir toleransla karşılaştırın.

Ve para için asla kayan nokta kullanmayın. Kuruşları tam sayı olarak saklayın; kuruş cinsinden bir long long, dolar cinsinden bir double'ın olmadığı şekilde kesindir.

Bir Tip Seçmek

Kodun çoğunu kapsayan kısa bir karar listesi:

  • Tam sayılar: bir sebebiniz yoksa int. CPU'nun en verimli şekilde işlediği ve tüm aritmetik kuralların etrafında kurulduğu tiptir.
  • 2 milyardan büyük her şey: long long ya da stdint.h'deki int64_t.
  • Boyutlar, uzunluklar, sizeof ya da strlen'den gelen dizi indeksleri: size_t. İşaretsizdir ve her nesne için yeterince büyük olması garantidir.
  • Ondalıklar: double. float'ı yalnızca büyük dizilerde belleği yarıya indirmek ya da çift duyarlık birimi olmayan gömülü donanımda kullanın.
  • Tek karakterler ve ham baytlar: metin için char, ikili veri için unsigned char.
  • Doğru/yanlış: stdbool.h'deki bool - bkz. C'de booleanlar.
  • Kesin bit genişlikleri (dosya biçimleri, ağ protokolleri, donanım yazmaçları): stdint.h - uint8_t, int16_t, uint32_t vb.

Tipleri Karıştırmak

Tek bir ifadede iki farklı tipi birleştirdiğinizde C, aritmetiği yapmadan önce onları arkanızdan dönüştürür. Bu genellikle yardımcıdır ve zaman zaman felakettir:

Birincisi tam sayı bölmesidir: her iki işlenen de int'tir, dolayısıyla sonuç bir int'tir ve kesir atılır. Üçüncüsü daha kötüdür - işaretli bir değeri işaretsiz biriyle karşılaştırmak işaretliyi işaretsize dönüştürür ve -1'i devasa bir pozitif sayıya çevirir.

Bu dönüşüm kuralları ve onları açık dönüşümlerle nasıl denetleyeceğiniz, C'de tür dönüşümü sayfasının konusudur.

Sıkça Sorulan Sorular

C'deki temel veri tipleri nelerdir?

Dört temel tip: tek karakterler ve baytlar için char, tam sayılar için int, ondalıklar için float ve double. Değiştiriciler boyutlarını ve işaretlerini değiştirir - short, long, long long, signed ve unsigned - böylece tüm küme oluşur.

C'de bir int kaç bayttır?

Modern masaüstü ve sunucu sistemlerinde neredeyse her zaman 4 bayt (32 bit); bu yaklaşık -2,1 milyar ile 2,1 milyar aralığı verir. Standart yalnızca en az 2 bayt garanti eder ve 16 bitlik mikrodenetleyiciler gerçekten 2 kullanır. Kesin bilmeniz gerekiyorsa sizeof(int) kullanın.

C'de float ile double arasındaki fark nedir?

float 4 bayttır ve yaklaşık 7 anlamlı ondalık basamağa sahiptir; double 8 bayttır ve yaklaşık 15'e. Double, kayan noktalı sabitler ve matematik fonksiyonları için varsayılandır ve milyonlarca değer saklamıyor ya da gömülü bir yonga hedeflemiyorsanız doğru seçim double'dır.

C'de bir int taştığında ne olur?

İşaretli bir int için taşma tanımsız davranıştır - derleyici sarabilir, doyurabilir ya da denetimi tamamen kaldırabilir. İşaretsiz bir int için tamamen tanımlıdır: değer 2^N'e göre sarar, dolayısıyla UINT_MAX + 1 sonucu 0'dır. Asla işaretli taşmaya güvenmeyin.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA