it-swarm-tr.com

İmzasız bir karakter nedir?

C/C++ 'da, unsigned char ne için kullanılır? Normal char 'den farkı nedir?

433
Landon Kuhn

C++ 'da üç distinct ​​karakter türü vardır:

  • charname__
  • signed char
  • unsigned char

text ​​için karakter türlerini kullanıyorsanız, nitelenmemiş charöğesini kullanın:

  • 'a' veya '0' gibi karakter değişmezleri türüdür.
  • "abcde" gibi C dizgelerini oluşturan türdür.

Ayrıca bir sayı değeri olarak da çalışır, ancak bu değerin imzalı veya imzasız olarak değerlendirilip belirtilmediği belirtilmez. Eşitsizlikler üzerinden karakter karşılaştırmalarına dikkat edin - ASCII (0-127) ile sınırlı olsanız da neredeyse güvende olursunuz.

Karakter türlerini numbers olarak kullanıyorsanız, şunu kullanın:

  • signed char, bu size en azından -127 ila 127 aralığını verir. (-128-127 yaygındır)
  • unsigned char, bu size en azından 0 - 255 aralığını verir.

"En azından", çünkü C++ standardı yalnızca her sayısal türün kapsaması gereken minimum değer aralığını verir. sizeof (char), 1 (yani bir bayt) olmalıdır, ancak teoride bir bayt, örneğin 32 bit olabilir. sizeofNAME__, BOYUTUNU HALA 1 olarak rapor eder - yani [olabilirsizeof (char) == sizeof (long) == 1 olabilir.

513
Fruny

Bu, C standardı char imzasını tanımlamaz, çünkü uygulamaya bağlıdır. Platforma bağlı olarak, char signed veya unsigned olabilir, bu nedenle uygulamanız buna bağlıysa açıkça signed char veya unsigned char istemeniz gerekir. Dizelerdeki karakterleri temsil etmeyi planlıyorsanız char işlevini kullanın, çünkü bu, platformunuzun dizeye koyduğu şeyle eşleşecektir.

signed char ve unsigned char arasındaki fark beklediğiniz gibi. Çoğu platformda, signed char, -128 ile 127 arasında değişen 8 bit ikilik bir tamamlayıcı numara olacak ve unsigned char, 8 bit işaretsiz bir tam sayı (0 - 255) olacaktır. Standart, char türlerinin 8 bit olmasını gerektirmediğini, yalnızca sizeof(char)__ 1 döndürdüğünü unutmayın. CHAR_BIT içinde limits.h ile bir karakterdeki bit sayısından alabilirsiniz. Bugün, bunun 8 dışında bir şey olacağı bir platform varsa, çok az var.

Bu konunun güzel bir özeti var burada .

Bunu gönderdiğimden beri başkalarının da söylediği gibi, eğer gerçekten küçük tamsayıları temsil etmek istiyorsanız, int8_t ve uint8_t işlevlerini kullanmanız daha iyi olur.

81
Todd Gamblin

Bunun gerçekten çağrıldığını düşündüğüm için, sadece bazı C ve C++ kurallarını belirtmek istiyorum (bu konuda aynıdır). Öncelikle, unsigned char 'nin tüm bitleri , işaretsiz karakter nesnesi olup olmadığının değerini belirlemeye katılır. İkincisi, unsigned char açıkça imzasız olarak belirtilmiştir.

Şimdi, int türündeki -1 değerini unsigned char biçimine dönüştürdüğünüzde ne olduğu hakkında bir tartışma yaptım. Elde edilen unsigned char öğesinin tüm bitlerinin 1 olarak ayarlandığı fikrini reddetti, çünkü işaret gösterimi konusunda endişeliydi. Ama yapmak zorunda değil. Bu kuralın hemen ardından dönüşümün amaçlandığı şeyi yapması gerekir:

Yeni tür imzasızsa, değer yeni türün aralığına gelinceye kadar, yeni türde temsil edilebilecek maksimum değerden daha fazla eklenip çıkarılarak değer dönüştürülür. (bir C99 taslağında 6.3.1.3p2)

Bu matematiksel bir tanımdır. C++, aynı kurala neden olan modulo hesabı cinsinden ifade eder. Her neyse, ne değildir garanti edilmez, -1 tamsayısındaki tüm bitlerin dönüşümden bir tanesi olması. Öyleyse, elimizde bulunan unsigned char öğesinin CHAR_BIT bitinin tümünün 1'e döndüğünü iddia edebiliriz?

  1. Tüm bitler, değerinin belirlenmesine katılır - yani, nesnede dolgu ucu oluşmaz.
  2. UCHAR_MAX+1 'a yalnızca bir kez -1' a eklemek, aralıkta bir değer verecektir, yani UCHAR_MAX

Aslında bu kadar yeter! Öyleyse, bir unsigned char 'a sahip olmak istediğinizde, tüm bitlerine sahip olan

unsigned char c = (unsigned char)-1;

Ayrıca bir dönüşümün değil sadece daha yüksek dereceli bitleri kesmesidir. two 'nin tamamlayıcısı için şanslı olay, bunun sadece bir kısaltması olduğu, ancak bunun diğer işaret gösterimleri için mutlaka doğru olmadığı anlamına gelir.

35

Örnek olarak imzasız karakter kullanımları:

imzasız karakter, genellikle her zaman renk bileşenine tek bir bayt atanan bilgisayar grafiklerinde kullanılır. Her biri bir imzasız karakter olarak 24 (veya 32) bit olarak temsil edilen bir RGB (veya RGBA) rengini görmek yaygındır. işaretsiz karakter değerler [0,255] aralığında olduğunda, değerler genellikle şöyle yorumlanır:

  • 0 verilen renk bileşeninin toplam eksikliğini ifade eder.
  • 255, verilen renk pigmentinin% 100'ünü ifade eder.

Böylece RGB kırmızı olarak (255,0,0) -> (% 100 kırmızı,% 0 yeşil,% 0 mavi) elde edersiniz.

Neden bir imzalı karakter kullanmıyorsunuz? Aritmetik ve bit kaydırma sorunlu hale gelir. Daha önce de açıklandığı gibi, imzalı char 's aralığı esasen -128 ile değiştirilir. RGB'yi gri tonlamaya dönüştürmek için çok basit ve naif (çoğunlukla kullanılmayan) bir yöntem, her üç renk bileşeninin ortalamasını almaktır, ancak renk bileşenlerinin değerleri negatif olduğunda bu sorunlara yol açar. Kırmızı (255, 0, 0), işaretsiz karakter aritmetik kullanılırken ortalama (85, 85, 85) olur. Ancak, eğer değerler işaretli karakter s (127, -128, -128) olsaydı, (29, 29,) olan (-99, -99, -99) ile sonuçlanırdı. 29) bizim imzasız karakter alan, yanlış.

24
Zachary Garrett

Bir karakteri küçük bir tamsayı olarak kullanmak istiyorsanız, bunu yapmanın en güvenli yolu int8_tand uint8_t türleriyledir.

12
jbleners

signed char aralığı -128 ila 127'dir; unsigned char, 0 ile 255 arasındadır.

char, derleyiciye bağlı olarak imzalı karaktere veya imzasız karaktere eşit olacaktır, ancak farklı bir türdür.

C tarzı dizeleri kullanıyorsanız, sadece char kullanın. Aritmetik için karakterleri kullanmanız gerekirse (oldukça nadir), taşınabilirlik için açıkça imzalı veya imzasız belirtin.

5
James Hopkin

char ve unsigned char, tüm platformlarda 8 bitlik türler olarak garanti edilmez; bunların 8 bitlik veya daha büyük olmaları garanti edilir. Bazı platformlarda 9 bit, 32 bit veya 64 bit bayt bulunur. Ancak, bugün en yaygın platformlarda (Windows, Mac, Linux x86, vb.) 8 bit bayt bulunur.

5
bk1e

Doğrudan değerler açısından, değerlerin CHAR_MIN ve CHAR_MAX arasında olduğu biliniyorsa normal bir karakter kullanılırken, işaretsiz bir karakter pozitif uçta iki kat sağlar. Örneğin, CHAR_BIT 8 ise, normal char aralığının yalnızca [0, 127] (imzalı veya imzasız olabilir) olması garanti edilirken, unsigned char [0, 255] ve signed char [-127, 127 olacak ].

Standartlar, POD nesnelerinin (düz eski veriler) doğrudan bir işaretsiz karakter dizisine dönüştürülmesine izin verir. Bu, nesnenin gösterimini ve bit desenlerini incelemenizi sağlar. Aynı tür güvenli kodlama garantisi, karakter veya imzalı karakter için mevcut değildir.

4
Julienne Walker

unsigned char sadece pozitif değerler alır .... gibi - 255

buna karşılık

signed char hem pozitif hem de negatif değerler alır .... like - 128 - + 127

4
munna

İmzasız bir karakter (işaretsiz) bayt değeridir (0-255). “Karakter” olarak “karakter” i düşünebilirsiniz, ancak bu gerçekten sayısal bir değerdir. Normal "char" imzalı, yani 128 değeriniz var ve bu değerler ASCII kodlamasını kullanan karakterlerle eşleşiyor. Ancak her iki durumda da, bellekte sakladığınız şey bir bayt değeridir.

3
Zac Gochenour

Çeşitli özel uzunluk ve imza türlerini kullanmayı seviyorsanız, muhtemelen söylediklerini yaptıkları için uint8_t, int8_t, uint16_t, vb. İle daha iyi durumdasınızdır.

2
Dark Shikari

İmzasız bir karakter normal bir karakterin işareti için ayrılmış biti başka bir sayı olarak kullanır. Bu, [-128 - 127] 'nin aksine aralığı [0 - 255] olarak değiştirir.

Genellikle imzasız karakterler, bir işaret istemediğinizde kullanılır. Bu, bit değiştirme (kayma işaretini uzatır) ve bir karakterle sayı olarak kullanmak yerine bir bayt olarak çalışırken diğer şeyleri yaparken bir fark yaratacaktır.

2
JasonOfEarth

imzasız karakter tüm hilelerin kalbidir. ALL platformu için neredeyse ALL derleyicide imzasız bir karakter yalnızca bir BYTE'dir. (Genellikle) 8 bitlik işaretsiz bir tam sayı. bu küçük bir tamsayı veya bir paket bit olarak ele alınabilir.

Bağımlılıkta, başkasının söylediği gibi, standart bir karakterin işaretini tanımlamaz. yani 3 farklı "char" türünüz var: char, imzalı char, imzasız char.

2
ugasoft

Bazı googling, insanların bu konuda tartıştıkları b bulundu.

İmzasız bir karakter temel olarak tek bir bayttır. Bu nedenle, bir bayt veriye ihtiyacınız varsa, bunu kullanırsınız (örneğin, genellikle Windows API'de olduğu gibi, bir işleve gönderilmek üzere bayrakları açık ve kapalı olarak ayarlamak istersiniz).

1
dbrien

işaretsiz karakter yalnızca pozitif değerleri alır: 0 - 255 arası işaretli karakter pozitif ve negatif değerleri alır: -128 - +127

0
NL628

"c programlama laugage" kitabından alıntı:

signed veya unsigned niteleyicisi, char veya herhangi bir tamsayıya uygulanabilir. işaretsiz sayılar her zaman pozitif veya sıfırdır ve aritmetik modulo 2 ^ n yasalarına uyun; burada n, türdeki bitlerin sayısıdır. Bu nedenle, örneğin, 8 bit ise, işaretsiz char değişkenleri 0 ile 255 arasında, imzalı karakterlerde -128 ile 127 arasında değerler bulunur (iki tamamlayıcı makinesinde). Düz karakterlerin imzalı veya imzasız olması makinedir. bağımlı, ancak yazdırılabilir karakterler her zaman pozitiftir.

0
ZhaoGang