(1) Bayt dizisi, C'deki bir karakterin aksine ne anlama gelir? UTF-16 bir bayt dizisi mi, yoksa ne olacak? (2) Bir bayt dizisinin neden değişken uzunlukla ilgisi yoktur?
Endian sorunlarının ne olduğunu yanlış anlıyorsunuz. İşte kısa bir özet.
32 bit tam sayı 4 bayt alır. Şimdi, bu baytların mantıksal sırasını biliyoruz. 32 bitlik bir tam sayıya sahipseniz, bunun yüksek baytını aşağıdaki kodla alabilirsiniz:
uint32_t value = 0x8100FF32;
uint8_t highByte = (uint8_t)((value >> 24) & 0xFF); //Now contains 0x81
Hepsi iyi ve güzel. Sorunun başladığı yer, çeşitli donanımların tamsayıları bellekten nasıl sakladığı ve aldığı.
Big Endian düzeninde, 32 bit tam sayı olarak okuduğunuz 4 bayt bellek parçası ilk bayt yüksek bayt olacak şekilde okunacaktır:
[0][1][2][3]
Küçük Endian düzeninde, 32 bit tam sayı olarak okuduğunuz 4 bayt bellek parçası, ilk bayt düşük bayt olacak şekilde okunur :
[3][2][1][0]
32 bit değerine sahip bir işaretçiye işaretçiniz varsa, bunu yapabilirsiniz:
uint32_t value = 0x8100FF32;
uint32_t *pValue = &value;
uint8_t *pHighByte = (uint8_t*)pValue;
uint8_t highByte = pHighByte[0]; //Now contains... ?
C / C ++ 'a göre, bunun sonucu tanımlanmamıştır. 0x81 olabilir. Veya 0x32 olabilir. Teknik olarak, her şeyi döndürebilir, ancak gerçek sistemler için birini veya diğerini döndürür.
Bellek adresini gösteren bir işaretçiniz varsa, bu adresi 32 bit değeri, 16 bit değeri veya 8 bit değeri olarak okuyabilirsiniz. Büyük bir endian makinesinde, işaretçi yüksek baytı gösterir; küçük bir endian makinesinde, işaretçi düşük bayta işaret eder.
Bunun tamamen belleğe okuma ve bellekten yazma ile ilgili olduğunu unutmayın. It has bir şey dahili C / C ++ kodu ile yapmak. Kodun ilk sürümü, C / C ++ 'nin tanımsız olarak bildirmediği, her zaman yüksek bayt almak için çalışacaktır.
Sorun bayt akışlarını okumaya başladığınız zamandır. Örneğin bir dosyadan.
16 bitlik değerler 32 bitlik değerlerle aynı sorunlara sahiptir; 4 yerine 2 bayt kullanırlar. Bu nedenle, dosya büyük endian veya küçük endian düzeninde depolanan 16 bitlik değerler içerebilir.
UTF-16, 16 bitlik değerler dizisi olarak tanımlanır . Etkili, bu bir uint16_t[]
. Her bir kod birimi 16 bitlik bir değerdir. Bu nedenle, UTF-16'yı düzgün bir şekilde yüklemek için verilerin endianitesinin ne olduğunu bilmelisiniz.
UTF-8, 8 bitlik değerler dizisi olarak tanımlanır . Bu bir uint8_t[]
. Her bir kod birimi 8 bit boyutundadır: tek bir bayt.
Şimdi, hem UTF-16 hem de UTF-8, birden çok kod biriminin (16 bit veya 8 bit değerler) bir Unicode kod noktası (bir "karakter" oluşturmak için bir araya gelmesine izin veriyor, ancak bu doğru terim değil ; bu bir basitleştirme) ). Sipariş bir codepoint oluşturan bu kod birimi UTF-16 ve UTF-8 kodlaması ile belirlenir.
UTF-16 işlenirken 16 bit bir değer okursunuz ve gerekli endian dönüşümü yapılır. Sonra, bunun vekil bir çift olup olmadığını tespit edersiniz; öyleyse, başka bir 16 bit değer okur, ikisini birleştirirsiniz ve bundan Unicode kod noktası değerini alırsınız.
UTF-8'i işlerken 8 bitlik bir değer okursunuz. Yalnızca bir bayt olduğundan endian dönüşümü mümkün değildir. İlk bayt çok baytlı bir sekansı gösteriyorsa, çok baytlı sekans tarafından dikte edildiği gibi bir takım baytları okursunuz. Her ayrı bayt bir bayttır ve bu nedenle endian dönüşümü yoktur. Sipariş Bunların UTF-16 surrogate çiftlerinin sırası, UTF-8 ile tanımlanan gibi, sırayla bayt.
Dolayısıyla UTF-8 ile ilgili endian sorunları olamaz.