Bu tür ile tanımlanmış değişkenler görüyorum ama nereden geldiğini ve amacının ne olduğunu bilmiyorum. Neden int veya işaretsiz int kullanmıyorsunuz? (Ya diğer "benzer" türler? Void_t, vb.).
Bu tür ile tanımlanmış değişkenler görüyorum ama nereden geldiğini ve amacının ne olduğunu bilmiyorum. Neden int veya işaretsiz int kullanmıyorsunuz? (Ya diğer "benzer" türler? Void_t, vb.).
Yanıtlar:
Gönderen Wikipedia
stdlib.h
Vestddef.h
başlık dosyaları olarak adlandırılan bir veri türü tanımlayansize_t
1 bir nesnenin boyut temsil etmek için kullanılır. Boyutları alan kitaplık işlevleri, bunların türde olmalarını beklersize_t
ve sizeof işleci değerlendirirsize_t
.Gerçek türü
size_t
platforma bağlıdır; Yaygın bir hata,size_t
işaretsiz int ile aynı olduğunu varsaymaktır , bu da programlama hatalarına neden olabilir, 2, özellikle 64 bit mimariler daha yaygın hale geldikçe.
Gönderen C99 7.17.1 / 2
Aşağıdaki tipler ve makrolar standart başlıkta tanımlanmıştır
stddef.h
<Kesik>
size_t
sizeof operatörünün sonucunun işaretsiz tamsayı türüdür
int
ve unsigned int
size_t 64 bit ise tip 32 bit vardır.
En.cppreference.com'daki size_t açıklamasına göre size_t
aşağıdaki başlıklarda tanımlanmıştır:
std::size_t
...
Defined in header <cstddef>
Defined in header <cstdio>
Defined in header <cstring>
Defined in header <ctime>
Defined in header <cwchar>
size_t
sizeof operatörünün sonucunun işaretsiz tamsayı türüdür (ISO C99 Bölüm 7.17.)
sizeof
Operatör bir ekspresyon ya da bir tür parantez içinde adı olabilir onun işlenen (bayt) boyutu, elde edilir. Boyut, işlenenin türüne göre belirlenir. Sonuç bir tamsayıdır. Sonucun değeri uygulama tanımlıdır ve türü (işaretsiz tam sayı türü) size_t
(ISO C99 Bölüm 6.5.3.4.)
Pratik olarak size_t
, adresleyebileceğiniz bayt sayısını temsil eder. Son 10-15 yıldır çoğu modern mimaride, bu aynı zamanda işaretsiz bir int boyutunda olan 32 bittir. Bununla birlikte uint
, büyük olasılıkla 32 bitte kalırken 64 bit adreslemeye geçiyoruz (boyutu c ++ standardında garanti edilmemektedir). Mimariler arasında bellek boyutuna bağlı olan kodunuzu taşınabilir hale getirmek için bir size_t
. Örneğin, dizi boyutları gibi şeyler her zaman size_t
's kullanmalıdır . Standart kaplara bakarsanız, ::size()
her zaman bir size_t
.
Ayrıca, visual studio'nun "64-bit Taşınabilirlik Sorunlarını Algıla" adı verilen bu tür hataları kontrol edebilen bir derleme seçeneğine sahip olduğunu unutmayın.
Bu şekilde, her zaman boyutun ne olduğunu bilirsiniz, çünkü belirli bir tür, boyutlara adanmıştır. Kendi sorusu bunun bir sorun olabileceğini gösteriyor: bu int
bir unsigned int
mi yoksa bir mi? Ayrıca, büyüklüğü nedir ( short
, int
, long
vs.)?
Atanmış belirli bir tür olduğundan, uzunluk veya imzalılık konusunda endişelenmenize gerek yoktur.
Gerçek tanım C ++ Referans Kitaplığı'nda bulunabilir , şöyle ki:
Tür:
size_t
(İşaretsiz integral türü)Başlık:
<cstring>
size_t
dil operatörü tarafından döndürülen integral veri tipine karşılık gelirsizeof
ve<cstring>
başlık dosyasında (diğerleri arasında) işaretsiz integral tipi olarak tanımlanır.Olarak
<cstring>
, bu parametrenin türü olarak kullanıldığınum
fonksiyonlardamemchr
,memcmp
,memcpy
,memmove
,memset
,strncat
,strncmp
,strncpy
vestrxfrm
her durumda bayt veya işlev etkileyecek zorundadır maksimum karakter sayısını belirtmek için kullanılan.Ayrıca, dönüş türü olarak kullanılan
strcspn
,strlen
,strspn
vestrxfrm
geri dönüş boyutları ve uzunlukları.
size_t, standart kitaplığınızın başlıklarında tanımlanmalıdır. Tecrübelerime göre, genellikle unsigned int için bir typedef. Mesele şu ki, olması gerekmiyor. Size_t gibi türler, standart kitaplık satıcısına, platforma uygunsa temel veri türlerini değiştirme özgürlüğü sağlar. Size_t'nin her zaman işaretsiz int olduğunu varsayarsanız (çevrim yoluyla, vb.), Satıcınız size_t'yi örneğin 64 bitlik bir tür olarak değiştirirse gelecekte sorunlarla karşılaşabilirsiniz. Bu nedenle, bu veya başka bir kitaplık türü hakkında herhangi bir şey varsaymak tehlikelidir.
void_t
Bir Google araması dışında aşina değilim ( AT&T Research'te Kiem-Phong Vo tarafından bir vmalloc
kütüphanede kullanılıyor - eminim diğer kütüphanelerde de kullanılıyor).
Belirli şeyler için kullanılan somut türler bir platformdan diğerine farklılık gösterebileceğinden, çeşitli xxx_t typedef'leri bir türü belirli bir kesin uygulamadan soyutlamak için kullanılır. Örneğin:
Void_t
Anahtar kelimenin bulunmayabileceği vmalloc
ANSI / ISO C'yi önceden tarihlendiren sistemlerde çalışmak üzere yazıldığı için kütüphane rutinleri tarafından döndürülen işaretçi tipini özetler void
. En azından tahmin ettiğim buydu.wchar_t
Geniş karakterler için kullanılan türü özetler, çünkü bazı sistemlerde 16 bitlik bir tür, diğerlerinde ise 32 bitlik bir tür olacaktır.Bu nedenle, geniş karakter işleme kodunuzu wchar_t
, diyelim ki yerine türü kullanmak için yazarsanız unsigned short
, bu kod muhtemelen çeşitli platformlara daha taşınabilir olacaktır.
Bir size_t
tanımın "tesadüfen" yüklenmediği minimalist programlarda , bazıları içerir, ancak yine de bir bağlamda (örneğin erişim için std::vector<double>
) buna ihtiyacım var , sonra bu bağlamı doğru türü çıkarmak için kullanırım . Örneğin typedef std::vector<double>::size_type size_t
.
( namespace {...}
Gerekirse kapsamı sınırlandırmak için kuşatın .)
"Neden int veya işaretsiz int kullanılmasın?" Gelince, çünkü anlamsız olarak daha anlamlı olmadığı için. Olmasının pratik bir nedeni var, diyelim ki,typedef
kimsenin kodunu değiştirmesine gerek kalmadan, örneğin bir d olarak int
ve sonra daha sonra yükseltilebilmesininlong
, elbette, ama bundan daha temelde bir türün anlamlı olması gerekiyor. Büyük ölçüde basitleştirmek size_t
için, time_t
zaman değerlerini içermek için uygun olduğu gibi , nesnelerin boyutlarını içeren bir tür değişkeni uygundur ve bunlar için kullanılır . Bunların gerçekte nasıl uygulandığı, uygulamanın işi olmalıdır. Her şeyi int
aramakla karşılaştırıldığında , bunun gibi anlamlı tip adları kullanmak, programınızın anlamını ve amacını netleştirmeye yardımcı olur, tıpkı herhangi bir zengin tür kümesinin yaptığı gibi.