3

C11 では、ポータブルなワイド char 型のサポートがUTF-16 と UTF-32 にそれぞれchar16_t追加char32_tれました。

ただし、テクニカル レポートでは、これら 2 つのタイプのエンディアンについては言及されていません。

たとえばgcc-4.8.4、x86_64 コンピューターで次のスニペットをコンパイルすると、次のようになり-std=c11ます。

#include <stdio.h>
#include <uchar.h>

char16_t utf16_str[] = u"十六";  // U+5341 U+516D
unsigned char *chars = (unsigned char *) utf16_str;
printf("Bytes: %X %X %X %X\n", chars[0], chars[1], chars[2], chars[3]);

生産します

Bytes: 41 53 6D 51

つまり、リトルエンディアンです。

しかし、この動作はプラットフォーム/実装に依存していますか?それは常にプラットフォームのエンディアンに準拠してchar16_tchar32_tます?

4

3 に答える 3

3

ただし、テクニカル レポートでは、これら 2 つのタイプのエンディアンについては言及されていません。

それはそう。C 標準では、ソース ファイル内のマルチバイト文字の表現に関してあまり指定していません。

char16_t utf16_str[] = u"十六"; // U+5341 U+516D
printf("U+%X U+%X\n", utf_16_str[0], utf_16_str[1]);

U+5341 U+516D が生成されます。これは、リトルエンディアンであることを意味します。

しかし、この動作はプラットフォーム/実装に依存していますか?それは常にプラットフォームのエンディアンに準拠していますchar16_tchar32_t?

はい、あなたがそれを呼ぶように、動作は実装に依存します。C11§5.1.1.2 を参照:

物理ソース ファイルのマルチバイト文字は、必要に応じて、実装定義の方法でソース文字セットにマップされます (行末インジケーターに改行文字を導入します)。

つまり、ソース コード内のマルチバイト文字がビッグ エンディアンと見なされるかリトル エンディアンと見なされるかは、実装によって定義されます。u"\u5341\u516d"移植性が問題になる場合は、 のようなものを使用することをお勧めします。

于 2015-07-15T14:53:49.360 に答える
0

UTF-16 と UTF-32 にはエンディアンが定義されていません。これらは通常、ホストのネイティブ バイト順でエンコードされます。これが、UTF-16 または UTF-32 文字列のエンディアンを示すために文字列の先頭に挿入できるバイト オーダー マーカー (BOM) がある理由です。

于 2019-05-23T12:00:37.303 に答える