ナビゲーションリンクをスキップ | |
印刷ビューの終了 | |
Oracle Solaris Studio 12.3: C ユーザーガイド Oracle Solaris Studio 12.3 Information Library (日本語) |
最初に、ISO C の国際化はライブラリ関数だけに影響がありました。しかし、国際化の最終段階 (複数バイト文字とワイド文字) は言語属性にも影響します。
1990 ISO/IEC C 規格では、複数バイト文字とワイド文字を管理するために、5 つのライブラリ関数を規定しています。1999 ISO/IEC C 規格では、さらに多くのこうした関数を規定しています。
アジア言語のコンピュータ環境における基本的な難しさは、入出力する必要のある膨大な数の表意文字にあります。通常のコンピュータアーキテクチャーの制約内で機能するよう、これらの表意文字はバイトシーケンスに符号化されます。関連するオペレーティングシステム、アプリケーションプログラム、および端末は、このようなバイトシーケンスを個々の表意文字として認識します。さらに、すべてのこのような符号化によって、通常の 1 バイト文字を表意文字のバイトシーケンスと混合できます。個々の表意文字を認識する際の難易度は、使用される符号化方式に依存します。
「複数バイト文字」は、ISO C の定義では、使用する符号化方式の種類に関係なく、表意文字を符号化するバイトシーケンスを示します。すべての複数バイト文字は「拡張文字セット」に属します。通常の 1 バイト文字は、単に複数バイト文字の特別なケースです。符号化に必要な唯一の条件は、どの複数バイト文字もヌル文字を符号化の一部として使用できないということです。
ISO C では、プログラムのコメント、文字列リテラル、文字定数、およびヘッダー名がすべて複数バイト文字のシーケンスであると規定されています。
符号化方式は 2 つの種類に分けることができます。1 つは、各複数バイト文字が自己識別性を持つ方式です。つまり、どの複数バイト文字も簡単に 2 つの複数バイト文字の間に挿入できます。
もう 1 つは、特別なシフトバイトの存在が後続のバイトの解釈を変更する方式です。例は、あるキャラクタ端末で行描画モードに入ったり出たりするために使用する方式です。このシフト状態依存符号化による複数バイト文字で書かれたプログラムの場合、ISO C では、コメント、文字列リテラル、文字定数、およびヘッダー名の始まりと終わりがすべてシフトなし状態でなければならないと規定しています。
複数バイト文字の処理で不都合が発生した場合は、すべての文字を一定のバイト数またはビット数にすることで解決できることがあります。そのような文字セットには数千または数万の表意文字が含まれている可能性があるため、すべてのメンバーを保持できるように 16 ビットまたは 32 ビットサイズの整数値を使用すべきです。(完全な中国語には 65,000 以上もの表意文字がある)。ISO C には、拡張文字セットのすべてのメンバーを保持するために十分な大きさを持つ実装定義の整数型として、typedef 名 wchar_t が含まれています。
各ワイド文字にはそれぞれ対応する複数バイト文字があり、またその逆も成り立ちます。通常の単一バイト文字に対応するワイド文字は、ヌル文字も含め、その単一バイトの値と同じ値を持つ必要があります。ただし、マクロ EOF が char として表現できない場合があるのとまったく同様に、EOF は必ずしも wchar_t に格納されない可能性があります。
アジア言語環境においてプログラマがより柔軟にプログラムを組むために、ISO C では、ワイド文字定数とワイド文字列リテラルを提供しています。この 2 つの形式は、直前に文字「L」の接頭辞が付くことを除き、通常の (ワイドでない) バージョンと同じです。
「x」 通常の文字定数
「¥」 通常の文字定数
L'x' ワイド文字定数
L'¥' ワイド文字定数
"abc¥xyz" 通常の文字列リテラル
L"abcxyz" ワイド文字列リテラル
複数バイト文字は、通常とワイドの両方のバージョンで有効です。表意文字 ¥ を生成するために必要なバイトシーケンスは、符号化に固有です。それが複数のバイトから構成されている場合、’ab’ の値が実装定義されるのとまったく同様に、文字定数 ’¥’ の値も実装定義されます。エスケープシーケンスを除き、通常の文字列リテラルには、引用符の間に指定されたものと同じバイト数 (指定したすべての複数バイト文字のバイト数も含む) が含まれます。
コンパイルシステムがワイド文字定数またはワイド文字列リテラルを検出したとき、各複数バイト文字は (mbtowc() 関数を呼び出したように) ワイド文字に変換されます。したがって、L'¥' の型は wchar_t です。abc¥xyz の型は長さが 8 の wchar_t の配列です。通常の文字列リテラルと同様に、各ワイド文字列リテラルは、値がゼロの余分な要素が追加されます。しかし、この要素は、ゼロの値を持つ wchar_t です。
通常の文字列リテラルが文字配列初期化の簡単な方法として使用できるのと同様に、ワイド文字列リテラルも wchar_t 配列を初期化するために使用できます。
wchar_t *wp = L"a¥z"; wchar_t x[] = L"a¥z"; wchar_t y[] = {L’a’, L’¥’, L’z’, 0}; wchar_t z[] = {’a’, L’¥’, ’z’, ’\0’};
この例では、3 つの配列 x、y、および z と、wp が指す配列の長さは同じです。すべての配列は同じ値で初期化されます。
最後に、通常の文字列リテラルと同様に、隣接するワイド文字列リテラルは連結されます。しかし、1990 ISO/IEC C 規格では、通常の文字列リテラルとワイド文字列リテラルが隣接する場合、その動作は定義されていません。また、1990 ISO/IEC C 規格では、このような連結が受け付けられない場合、コンパイラはエラーを発行する必要はありません。