Kullanmanın avantajı nedir uint8_tüzerine unsigned charC?
Neredeyse her sistemde uint8_tsadece bir typedef olduğunu biliyorum, unsigned charneden kullanıyorsunuz?
Kullanmanın avantajı nedir uint8_tüzerine unsigned charC?
Neredeyse her sistemde uint8_tsadece bir typedef olduğunu biliyorum, unsigned charneden kullanıyorsunuz?
Yanıtlar:
Niyetinizi belgeliyor - bir karakter yerine küçük sayılar depolayacaksınız.
Ayrıca uint16_tveya gibi diğer typedef'ler kullanıyorsanız daha güzel görünüyor int32_t.
unsigned charveya signed charbelgelendirdiğiniz için, süslenmemiş charkarakterler ile çalıştığınızı gösterir.
unsignedidi unsigned inttanım gereği?
charbir karakter anlamına gelirken, UTF8 dizesi bağlamında, çok baytlı bir karakterin sadece bir baytı olabilir. Uint8_t kullanmak, her konumda bir karakter beklememesi gerektiğini açıkça ifade edebilir - diğer bir deyişle, string / dizinin her elemanının herhangi bir anlamsal varsayım yapmaması gereken keyfi bir tamsayı olduğu anlaşılabilir. Elbette tüm C programcıları bunu biliyor, ancak yeni başlayanları doğru soruları sormaya zorlayabilir.
Sadece bilgiçlikçi olmak için, bazı sistemlerde 8 bitlik bir tip olmayabilir. Wikipedia'ya göre :
N = 8, 16, 32 veya 64 için tam genişlikli tamsayı türlerini tanımlamak ve yalnızca gereksinimleri karşılayan herhangi bir türü varsa bir uygulama gereklidir. Uygun tipleri desteklese bile bunları başka N için tanımlamanız gerekmez.
Bu nedenle var uint8_tolduğu garanti edilmez, ancak 8 bit = 1 bayt olan tüm platformlar için geçerli olacaktır. Bazı gömülü platformlar farklı olabilir, ancak bu çok nadir görülür. Bazı sistemler chartürleri 16 bit olarak tanımlayabilir , bu durumda muhtemelen 8 bitlik bir tür olmayacaktır.
Bu (küçük) sorun dışında, @Mark Ransom'un cevabı bence en iyisidir. Verileri ne için kullandığınızı en açık şekilde göstereni kullanın.
Ayrıca, (herhangi bir standardın parçası değil ) yerine ( başlıkta uint8_tsağlanan C99 standart typedef) demek istediğinizi varsayıyorum .stdint.huint_8
uint8_t(veya buna buna typedef). Bunun nedeni, 8 bit türünün depolama gösteriminde kullanılmaması gereken bitlere uint8_tsahip olmasıdır.
typedef unsigned integer type uint8_t; // optional Yani, aslında, uint8_t'yi tanımlamak için C ++ standart uygun bir kütüphaneye hiç gerek yok (açıklamaya bakınız // isteğe bağlı )
Bütün mesele, uygulamadan bağımsız kod yazmaktır. unsigned char8 bitlik bir tip olduğu garanti edilmez. uint8_t(varsa).
sizeof(unsigned char)dönecektir 1. ancak eğer bir sistem karakteri ve int aynı boyutta, örneğin 16 bit ise, o sizeof(int)zaman geri dönecektir1
Dediğiniz gibi, " neredeyse her sistem".
charmuhtemelen değişme olasılığı daha azdır, ancak kullanmaya başladığınızda uint16_tve arkadaşlarınızla uint8_tkarışımları daha iyi kullanmak ve hatta bir kodlama standardının parçası olabilir.
Deneyimlerime göre uint8_t'yi 8 bit (ve uint16_t, vb.) Olarak kullanmak istediğimiz ve 8 bit'ten daha küçük alanlara sahip olabileceğimiz iki yer var. Her iki yer de alanın önemli olduğu yerlerdir ve hata ayıklama sırasında genellikle verilerin ham bir dökümünden bakmamız ve neyi temsil ettiğini hızlı bir şekilde belirleyebilmemiz gerekir.
Birincisi RF protokollerinde, özellikle dar bant sistemlerinde. Bu ortamda tek bir mesajda olabildiğince fazla bilgi toplamamız gerekebilir. İkincisi, çok sınırlı alana sahip olabileceğimiz flash depolamadadır (gömülü sistemlerde olduğu gibi). Her iki durumda da, derleyicinin bizim için paketleme ve ambalajı açacağı paketlenmiş bir veri yapısı kullanabiliriz:
#pragma pack(1)
typedef struct {
uint8_t flag1:1;
uint8_t flag2:1;
padding1 reserved:6; /* not necessary but makes this struct more readable */
uint32_t sequence_no;
uint8_t data[8];
uint32_t crc32;
} s_mypacket __attribute__((packed));
#pragma pack()
Hangi yöntemi kullandığınız derleyicinize bağlıdır. Aynı başlık dosyalarına sahip birkaç farklı derleyiciyi de desteklemeniz gerekebilir. Bu, cihazların ve sunucuların tamamen farklı olabileceği gömülü sistemlerde olur - örneğin, bir x86 Linux sunucusuyla iletişim kuran bir ARM cihazınız olabilir.
Paketlenmiş yapıları kullanan birkaç uyarı vardır. En büyük sorun, bir üyenin adresini kayıttan çıkarmaktan kaçınmanızdır. Mutibyte hizalanmış kelimelere sahip sistemlerde, bu yanlış hizalanmış bir istisna ve bir coredump ile sonuçlanabilir.
Bazı insanlar da performans konusunda endişelenecek ve bu paketlenmiş yapıları kullanmanın sisteminizi yavaşlatacağını savunacaklardır. Sahne arkasında, derleyicinin hizalanmamış veri üyelerine erişmek için kod eklediği doğrudur. Bunu IDE'nizdeki montaj koduna bakarak görebilirsiniz.
Ancak, paketlenmiş yapılar iletişim ve veri depolama için en yararlı olduğu için, veriler bellekte çalışırken paketlenmemiş bir gösterime çıkarılabilir. Normalde yine de bellekteki tüm veri paketiyle çalışmamız gerekmez.
İşte bazı ilgili tartışmalar:
pragma paketi (1) veya __attribute__ ((hizalanmış (1))) çalışır
Gcc'nin __attribute __ ((paketli)) / #pragma paketi güvensiz mi?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
Çok az. Taşınabilirlik bakış açısından, char8 bitten daha küçük olamaz ve hiçbir şey bundan daha küçük olamaz char, bu nedenle belirli bir C uygulaması işaretsiz 8 bitlik bir tamsayı türüne sahipse, öyle olacaktır char. Alternatif olarak, hiç bir typedefhilesi olmayabilir, bu noktada herhangi bir numara hiledir.
Kodunuzu orada 8 bit bayt ve başka bir şeye ihtiyacınız olmadığı açık bir şekilde daha iyi belgelemek için kullanılabilir. Ancak pratikte zaten neredeyse her yerde makul bir beklenti var (bunun doğru olmadığı DSP platformları var, ancak kodunuzun çalışma şansı zayıf ve programınızın üstünde statik bir iddia kullanarak hata yapabilirsiniz. böyle bir platform).
unsigned char0 ile 255 arasında değerleri tutabilmesi gerekir . Bunu 4 bitte yapabiliyorsanız şapkam size kapalıdır.
uint8_tuygulamaya ekleme yapmalarını sağlayın . Merak ediyorum, 16 bit karakterli DSP'ler için derleyiciler genellikle uygulanıyor uint8_tmu uygulanmıyor mu?
#include <stdint.h>ve kullanmanın belki de en basit yoludur uint8_t. Platformda varsa, size verecektir. Platformda yoksa, programınız derlenmeyecek ve nedeni açık ve anlaşılır olacaktır.
Bu, örneğin bir ağ analizörü yazarken gerçekten önemlidir. paket başlıkları, belirli bir platformun C derleyicisinin çalışma şekliyle değil, protokol belirtimi ile tanımlanır.
Hemen hemen her sistemde uint8_t == imzasız karakter ile tanıştım, ancak bu C standardı tarafından garanti edilmiyor. Taşınabilir kod yazmaya çalışıyorsanız ve belleğin tam olarak ne büyüklükte olduğu konusunda uint8_t kullanın. Aksi takdirde imzasız karakter kullanın.
uint8_t 8 bit unsigned charolduğunda her zaman aralığını ve boyutunu ve dolgu (hiçbiri) ile eşleşir unsigned char. Ne zaman unsigned char8 bit değil, uint8_tyok.
unsigned char8-bit edilir uint8_tbir olmasını garanti typedefbunların bir typedefbir bölgesinin genişletilmiş tamsayı türü ?
unsigned char/signed char/charküçük tipte olduğu gibi kolayca çıkarılır - 8 bitten daha az olmamalıdır. unsigned chardolgu yok. For uint8_tolması için, 8-bit, dolgu yok olmalı, çünkü bir uygulama sağlanan türü tamsayı bulunmaktadır: minimal şartları uyan unsigned char. "... bir typedef olması garanti ..." gelince göndermek için iyi bir soru gibi görünüyor.