0

ええと、私は数ヶ月前に別の「よく知っている」Cの本(私の言語で)を読んだことがあります、そして私はこれについて何も学びません。K&Rが20ページに3つの章を書く方法は、単純に驚くべきものであり、もちろん、私は膨大な説明を期待することはできませんが、それはまた疑問を投げかけます。

この点について質問があります1.5.1本には次のように書かれています(16ページ):

main(){
  int c;// <-- Here is the question
  c=getchar();
  while (c != EOF){
    putchar(c);
    c = getchar();
  }
}

[...]型charは、特にそのような文字データを格納するためのものですが、任意の整数型を使用できます。微妙ですが重要な理由でintを使用しました。問題は、入力の終わりと有効なデータを区別することです。解決策は、getcharは、入力がなくなると固有の値を返すことです。この値は、実際の文字と混同することはできません。この値は、「ファイルの終わり」を表すEOFと呼ばれます。getcharが返す値を保持するのに十分な大きさの型であるとcを宣言する必要があります。cは、可能なcharに加えてEOFを保持するのに十分な大きさでなければならないため、charを使用できません。したがって、intを使用します。[...]

別の説明のためにグーグルを検索した後:

EOFは、ファイルの終わりを表す特別なマクロです(Linux:キーボードでCTRL + dを使用してこれを作成し、Windowsコマンド:CTRL + zを使用します(改行の先頭にある必要があり、その後にRETURNが続く場合があります)):多くの場合EOF = -1、ただし実装に依存します。可能な文字に対して有効な値ではない値である必要があります。このため、cはint型です(予想どおりcharではありません)。

そこで、ソースをintからcharに変更して、EOF値の取得について、何が問題なのかを確認しました...しかし、問題はありません。同じように機能します。

また、getcharがどのように私が書いたすべての文字を取得し、すべてを印刷するのかを理解していませんでした。Int型は4バイト長であるため、変数内で4文字を取ることができます。しかし、私は任意の数の文字を入れることができます、それはすべてを同じように読み書きします。そしてcharで、同じことが起こります...実際に何が起こりますか?1〜4文字を超える場合、値はどこに保存されますか?

4

3 に答える 3

2

だから私はソースを int から char に変更して、EOF値の取得について何が問題なのかを確認しました...しかし問題はありません。同じように動作します

もたまたま同じように働いています。それはすべて の実際のタイプchar、つまり署名付きか未署名かによって異なります。この主題に関するC FAQもあります。charが署名されていない場合、バグが発生する可能性が高くなります。

ただし、文字が署名されていて、入力がすべて 7 ビット文字である場合、このバグは長期間検出されないことがあります。

編集

最後の質問は、char 型は 1 バイト長で、int 型は 4 バイト長です。したがって、char は 1 つの ASCII 文字のみを使用します。しかし、「スタック オーバーフローは 1 バイトを超えています」と入力すると、出力は「スタック オーバーフローは 1 バイトを超えています」となります。「tack overflow is over 1byte long」はどこに保存され、どのように putchar が文字列全体を配置しますか

各文字は順番に格納さcれます。そのため、初回はgetchar()を返しsputchar途中で送信します。それからt一緒に来ます。c複数の文字を保存することは決してありません。そのため、大きな文字列をフィードしても、一度に 1 文字ずつ食べて処理します。

于 2012-08-24T13:26:06.713 に答える
1

2つの答えに分ける:

なぜintではないかchar

簡潔で正式な答え:すべての実在の文字と別の非実在の文字 (EOF) を表現できるようにしたい場合は、実在の文字のみを保持するように設計されたデータ型を使用できません。

理解できるが完全に正確ではない答え: 関数getchar()は、読み取った文字の ASCII コード、または EOF を返します。

-1255 にキャストされるためchar、255 文字と EOF を区別できません。あれは、

char a = 255;
char b = EOF;
a == b // Evaluates to TRUE

しかし、

int a = 255;
int b = EOF;
a == b // Evaluates to FALSE

したがって、 を使用charすると、ASCII コードが 255 の文字 (ファイルからの読み取り時に発生する可能性があります) と EOF を区別できません。

putchar()なぜあなたはintで使うことができますか

この関数putchar()は、そのパラメーターを調べ、数値を確認し、ASCII テーブルに移動して、確認したグリフを描画します。を渡すと、int暗黙的に にキャストされcharます。の数字が にint収まる場合はchar、すべて問題なく、誰も何も気づきません。

于 2012-08-24T13:34:26.567 に答える
1

charの結果を保存するためにを使用している場合getchar()、2 つの潜在的な問題がありますchar

  • char署名されていない場合、真にc == EOFなることはなく、無限ループが発生します。

  • char署名されている場合c == EOF、文字を入力するとtrueになります。使用する文字セットによって異なります。ISO8859-1 または CP852 を使用するロケールでは、EOF が -1 (最も一般的な値) の場合は「ÿ」です。UTF-8 などの一部の文字セットは、(char)EOF有効なコードで値を使用しませんが、問題が signed char 実装にとどまり、問題のないロケールでのみ使用されることを保証できることはほとんどありません。

于 2012-08-24T13:38:10.647 に答える