2

私はC11標準のセクション7.21を読みました<stdio.h>。この規格では、最初にストリームを次のように説明しています。

7.21.2.2:

テキストストリームは、文字の順序付けられたシーケンスです...

7.21.2.3:

バイナリストリームは、文字の順序付けられたシーケンスです...

これはストリーム文字のタイプを指定しません(これは方向に依存するため)。それは後で言います:

7.21.3.12:

...バイト出力関数は、fputc関数を連続して呼び出すかのように、文字をストリームに書き込みます。

fputc(7.21.7.3.2)から:

この関数は、で指定された(に変換された)文字を、 ..で示される出力ストリームにfputc書き込みます。cunsigned charstream

これは、のint c引数がストリームに書き込まれる前にfputc変換されることを示します。unsigned char同様の注意が:に与えられfgetcます

7.21.7.1.2:

関数は、その文字をに変換されたfgetcものとして取得しますunsigned charint

およびungetcfreadおよびfwrite

これはすべて、内部的にはバイト指向のストリームがsで表されることを示唆していますunsigned char

ただし、Linuxカーネルの内部を見ると、ファイルはのストリームと見なされているようですchar。私がこれを言っている理由の1つは、file_operations readwritecallbacksがそれぞれchar __user *とを取得することconst char __user *です。

の実装では、glibcはで定義されています。これでも、すべての読み取りおよび書き込みポインターはです。FILEtypedefstruct _IO_FILElibio/libio.hstructchar *

C ++では、basic_ostream::write関数はconst char *入力と同様に受け取りますbasic_istream::read(ただし、この質問ではC ++には興味がありません)。

私の質問は、上記の引用は、FILEストリームがのストリームとして脅威にさらされるべきであることを意味しますunsigned charか?もしそうなら、なぜglibcとLinuxカーネルはそれらを実装するのchar *ですか?そうでない場合、なぜ標準は文字をに変換することを主張するのunsigned charですか?

4

3 に答える 3

4

それは本当に重要ではありません。標準では、選択した場所でunsigned charを使用します。これは、それらの場所で正確な定式化が可能になるためです。

  • fgetcintに変換されたunsignedcharを返すように指定されているため、EOFの場合を除いて、結果が正またはnullであることがわかります(したがって、EOFと有効なcharの間に混乱はありません。混乱は、バグの原因となります。事前にEOFをチェックせずに、fgetcの結果をcharに直接格納します)。

  • fputcこの変換は適切に指定されているため、intを取得してunsignedcharに変換するように指定されています。注意しないと、unsigned charを使用しない定式化により、UBが次のようなシーケンスになる可能性があります。

    int c = fgetc(stdin);
    if (c != EOF)
        fputc(c, stdout);
    

負の文字には符号付き文字を使用します。

于 2012-09-23T18:11:09.377 に答える
2

それは本当に重要ではありません。Acharは、署名されているかどうかに関係なく、CHAR_BITビット長(通常は8ビット)です。limits.h

これらの関数はCHAR_BITビットチャンクで機能するため、書き込みまたは読み取りプロセスでは、ここでは符号に違いはありません。

次に、結果を適切にキャストすることにより、アプリケーションロジックに応じて、signedまたはunsignedcharを使用できます。人間の表現は記号によって異なりますが、プロセッサの場合、表現は変わりません。まだバイトです。

于 2012-09-23T17:52:41.833 に答える
1

(ソースをチェックせずに)直接観察できるのは、APIが返すものだけです。その背後にあるものはすべて、ブラックボックスの抽象化によって隠されており、心配する必要はありません。

あなたの質問の他の部分に関して:引数/戻り値はであり、ストリームは文字のシーケンスであるため、標準変換があることに注意する必要があります。int

于 2012-09-23T18:02:36.260 に答える