C ++ 'da size_t ve int arasındaki fark nedir?


Yanıtlar:


153

Gönderen dostu Vikipedi :

Stdlib.h ve stddef.h başlık dosyaları , bir nesnenin boyutunu temsil etmek için kullanılan size_t adlı bir veri türü tanımlar . Boyut alan kütüphane işlevleri, bunların size_t türünde olmasını bekler ve sizeof operatörü size_t olarak değerlendirir.

Size_t öğesinin gerçek türü platforma bağlıdır; yaygın bir hata, size_t öğesinin işaretsiz int ile aynı olduğunu varsaymaktır, bu da özellikle 64 bit mimariler daha yaygın hale geldikçe programlama hatalarına yol açabilir.

Ayrıca, size_t öğesinin neden önemli olduğunu kontrol edin


76
Ve böylece, size_t nedir?
NDEthos

8
@NDEthos Bağlıdır! Burada, Linux /usr/include/stdlib.h, tanımı başka bir başlık dosyası aksini /usr/lib/gcc/x86_64-redhat-linux/5.3.1/include/stddef.hbelirtmedikçe varsayılan değer long unsigned intolarak alır.
David Tonhofer

1
Ben inttuncation için size_t tehlikeli olduğunu onaylamak . Bu konu dışı olabilir, ancak linux çekirdeğinde binlerce kez meydana geldiğinde bu tür hataları düzeltmek için tek başına bir yama nasıl yazılır?
user2284570

36

size_t, boyutları temsil etmek için kullanılan türdür (adından da anlaşılacağı gibi). Platformu (ve hatta potansiyel olarak uygulanması) bağımlıdır ve sadece bu amaçla kullanılmalıdır. Açıkçası, bir boyutu temsil eden size_t imzasızdır. Malloc, sizeof ve çeşitli dize işlemi işlevleri gibi birçok stdlib işlevi, veri türü olarak size_t işlevini kullanır.

Bir int varsayılan olarak imzalanmıştır ve boyutu da platforma bağlı olsa da, çoğu modern makinede sabit bir 32 bit olacaktır (ve 64 bit mimaride size_t 64 bit olsa da, int bu mimarilerde 32 bit uzunluğunda kalır).

Özetlemek gerekirse: bir nesnenin boyutunu temsil etmek için size_t, diğer durumlarda int (veya long) kullanın.


12

size_tTipi işaretsiz entegre tip olarak tanımlanır sizeofoperatör. Gerçek dünyada, 64 bit intplatformlarda genellikle 32 bit (geriye dönük uyumluluk için) size_tolarak tanımlanmış ancak 64 bit olarak tanımlanmış (böylece dizileri ve yapıları 4 GiB'den büyük boyutlarda bildirebilirsiniz ) olarak görürsünüz. A long intda 64 bit ise, buna LP64 kuralı denir; eğer long int32 bit ama long long intve işaretçileri LLP64 var 64 bit vardır. Hız için 64 bit talimatları, ancak bellek tasarrufu için 32 bit işaretçileri kullanan bir program olan tersi de alabilirsiniz. Ayrıca, intimzalı ve size_timzasız.

Tarihsel olarak, adreslerin yerel boyutundan daha geniş veya daha kısa olduğu başka platformlar da vardı int. Aslında, 70'lerde ve 80'lerin başında, bu daha yaygın değildi: tüm popüler 8-bit mikrobilgisayarlar 8-bit kayıtlara ve 16-bit adreslere sahipti ve 16 ve 32 bit arasındaki geçiş de birçok makineyi üretti. adresleri kayıtlarından daha genişti. Bazen hala burada Büyük bellek modu 16 bit CPU'da 32 bit depolanmış 20 bit adresleri olan (ancak 80386 32 bit komut setini destekleyebilir) MS-DOS için Borland Turbo C hakkında sorular görüyorum; Motorola 68000'de 32 bit kayıt ve adresleri olan 16 bitlik bir ALU vardı; 15 bit, 24 bit veya 31 bit adresli IBM ana çerçeveleri vardı. Ayrıca gömülü sistemlerde farklı ALU ve adres-veri yolu boyutları da görüyorsunuz.

Her zaman intdaha küçüktür size_tve boyutu depolamak deneyin veya çok büyük bir dosya veya nesnenin ofset unsigned int, bu taşması ve bir hata neden olabilir olasılığı vardır. Bir ile int, negatif bir sayı alma olasılığı da vardır. Bir intveya unsigned intdaha genişse, program düzgün çalışır ancak belleği boşa harcar.

Taşınabilirlik istiyorsanız, genellikle amaç için doğru türü kullanmalısınız. Birçok kişi imzasız yerine imzalı matematik kullanmanızı tavsiye eder (kötü, ince hataları önlemek için 1U < -3). Bu amaçla, standart kütüphane tanımlar ptrdiff_tiçinde <stddef.h>bir bir işaretçi çıkartma işleminin sonucunun imza türü.

Yani karşı tüm adresleri ve uzaklıklar sınırlarla kontrol etmek için bir geçici çözüm olabilir dedi INT_MAXve ya 0ya INT_MINuygun olarak ve herhangi bir kaçırma durumunda derleyici imzalı karşılaştıran hakkında uyarı ve imzasız miktarlarda açın. Her zaman, her zaman, her zaman dizi erişimlerinizi zaten C'de taşma açısından kontrol etmelisiniz.


8

Çünkü size_t bir int (belki bir yapı) dışında herhangi bir şey olabilir. Fikir, işini altta yatan türden ayırmasıdır.


8
Size_t aslında imzasız bir tamsayı için bir takma olarak garanti edilir, bu yüzden bir yapı olamaz. Yine de bunu desteklemek için kullanışlı bir referansım yok.
açma

9
@unwind: C99: TC3, 7.17 §2
Christoph

1
@danio Neden böyle? Açıklayabilir misin?
Rüppell'in Akbabası

2
Ben olsaydım cplusplus'a bağlanmazdım! Bölüm, ayet, paragraf ve satır alıntı yapamıyorsanız, o zaman hepsi sadece kulaktan doludur! :-)
graham.reeds

1
size_timzasız bir tamsayı türü olarak belirtilir . C11 §6.5.3.4 5 "Her iki işleç ( sizeof _Alignof) sonucunun değeri uygulama tanımlıdır ve türü (işaretsiz bir tamsayı türü) size_t,".
chux - Monica'yı geri yükle

-1

Tanımı SIZE_T: https://msdn.microsoft.com/en-us/library/cc441980.aspx ve https://msdn.microsoft.com/en-us/library/cc230394.aspx

Gerekli bilgileri buraya yapıştırarak:

SIZE_Ta, ULONG_PTRbir işaretçi işaret hangi bayt sayısını temsil eder.

Bu tür şu şekilde beyan edilir:

typedef ULONG_PTR SIZE_T;

A ULONG_PTRişaretçi hassasiyeti için kullanılan imzasız uzun bir tiptir. İşaretçi aritmetiği gerçekleştirmek için bir işaretçiyi uzun bir türe çevirirken kullanılır.

Bu tür şu şekilde beyan edilir:

typedef unsigned __int3264 ULONG_PTR;

2
SIZE_Tdeğil size_t, OP ne sordu.
ikegami

2
Bu bir Microsoft uzantısı, standart dilin bir parçası değil.
Davislor

SIZE_Ttamamen farklı size_t. Bir tür değişkeni bildiremezsiniz SIZE_T.
calocedrus
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.