Kullanmanın avantajı nedir uint8_t
üzerine unsigned char
C?
Neredeyse her sistemde uint8_t
sadece bir typedef olduğunu biliyorum, unsigned char
neden kullanıyorsunuz?
Kullanmanın avantajı nedir uint8_t
üzerine unsigned char
C?
Neredeyse her sistemde uint8_t
sadece bir typedef olduğunu biliyorum, unsigned char
neden kullanıyorsunuz?
Yanıtlar:
Niyetinizi belgeliyor - bir karakter yerine küçük sayılar depolayacaksınız.
Ayrıca uint16_t
veya gibi diğer typedef'ler kullanıyorsanız daha güzel görünüyor int32_t
.
unsigned char
veya signed char
belgelendirdiğiniz için, süslenmemiş char
karakterler ile çalıştığınızı gösterir.
unsigned
idi unsigned int
tanım gereği?
char
bir 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_t
olduğ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 char
tü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_t
sağlanan C99 standart typedef) demek istediğinizi varsayıyorum .stdint.h
uint_8
uint8_t
(veya buna buna typedef). Bunun nedeni, 8 bit türünün depolama gösteriminde kullanılmaması gereken bitlere uint8_t
sahip 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 char
8 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".
char
muhtemelen değişme olasılığı daha azdır, ancak kullanmaya başladığınızda uint16_t
ve arkadaşlarınızla uint8_t
karışı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, char
8 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 typedef
hilesi 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 char
0 ile 255 arasında değerleri tutabilmesi gerekir . Bunu 4 bitte yapabiliyorsanız şapkam size kapalıdır.
uint8_t
uygulamaya ekleme yapmalarını sağlayın . Merak ediyorum, 16 bit karakterli DSP'ler için derleyiciler genellikle uygulanıyor uint8_t
mu 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 char
olduğunda her zaman aralığını ve boyutunu ve dolgu (hiçbiri) ile eşleşir unsigned char
. Ne zaman unsigned char
8 bit değil, uint8_t
yok.
unsigned char
8-bit edilir uint8_t
bir olmasını garanti typedef
bunların bir typedef
bir bölgesinin genişletilmiş tamsayı türü ?
unsigned char/signed char/char
küçük tipte olduğu gibi kolayca çıkarılır - 8 bitten daha az olmamalıdır. unsigned char
dolgu yok. For uint8_t
olması 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.