3

私は今、プログラムを理解しているようですが、重要なことには実際には使用されない文字配列にすべての戻り値をgetlineコピーするように見えるため、関数はあまり直感的ではありません。getchar()s[]

int getline(char s[], int lim)
{
    int c, i;
    for(i=0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if(c == '\n')
    {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;
}

関数が実際に行っているのは、到達または復帰するs[i] = c;までの文字数をカウントすることだけであるため、関数はその行を簡単に無視できます。EOF'\n'getchar()

私が本当に理解していないのは、メインループが次のようにプログラムが前進した理由です。

main()
{
    int len; /* current line length */
    int max; /* maximum length seen so far */
    char line[MAXLINE]; /* current input line */
    char longest[MAXLINE]; /* longest line saved here */

    max = 0;
    while ((len = getline(line, MAXLINE)) > 0)
        if (len > max)
        {
            max = len;
            copy(longest, line);
        }
    if (max > 0) /* there was a line */
        printf("%s", longest);
    return 0;
}

唯一の説明はgetchar()、ユーザーがテキストの全行を入力し、enterキーを押した後に、関数がその魔法を実行するということです。したがって、実行時に動作するように見えると思います。

番組進行はこんな感じ?プログラムは最初に while ループに入り、次にユーザーがテキスト行を入力するのを待ち、ユーザーが Enter キーを押すと、getline関数の for ループが繰り返されますか? ユーザーは入力中に入力できるので、これが当てはまるように感じbackspaceます。

私の質問は、プログラムはどのように正確に前進するのですか? それはすべてgetchar()機能のためですか?

ctrlターミナルで-Dを押すと、他にも紛らわしいことが起こります。改行の先頭でctrl-Dを押すと、プログラムは終了します。ctrlあるテキストで満たされた行の最後で-を打った場合D、それは終了せず、 を打ったのと同じように動作しませんenterctrl-をDテキスト行で数回押すと、プログラムは最終的に終了します。

これは私の端末がセッションを処理している方法ですか、それとも単に C を学びたいのであれば心配する必要はありませんか?

私が尋ねる理由は、プログラムをよく理解するためにトレースするのが好きだからですが、getchar()関数がそれを難し​​くしています。

4

4 に答える 4

3

getchar標準入力から文字を読み取ります。端末に座っている場合は、入力した文字を受け取るまでプログラムをブロックし、それで完了です。ただし、標準入力は対話時に行バッファーされるため、入力した内容は、Enter キーを押すまでプログラムによって処理されません。つまりgetchar、入力したすべての文字をバッファから読み取られるため、引き続き読み取ることができます。

関数を間違えています。配列は関数*に渡され、読み取られた各文字getchar(EOF または改行を除く) が連続する要素に格納されます。文字を数えるのではなく、配列に格納することがポイントです。

(*実際にはポインタが渡されますが、ここの関数は配列のように扱うことができます。)

于 2013-03-28T23:57:14.730 に答える
3

パラメーター宣言 (およびそのコンテキストでのみchar s[]) では、実際には を意味しchar *sます。C 標準がこれを説明する方法は次のとおりです。

「型の配列」としてのパラメーターの宣言は、「への修飾ポインター」に調整されます 。

は実際sには 型のポインタでありchar*、関数が変更されると、 の番目の要素がs[i]変更されます。iline

通話中:

getline(line, MAXLINE)

lineは配列ですが、ほとんどのコンテキストでは、配列式は配列の最初の要素へのポインターに暗黙的に変換されます。

これら 2 つの規則は、C では配列とポインターが実際には同じものであるかのように見せるための陰謀の一部のように見えますが、間違いなくそうではありません。ポインター オブジェクトには、何らかのオブジェクト (または、どのオブジェクトも指していない null ポインター) のアドレスが含まれます。配列オブジェクトには、要素の順序付けられたシーケンスが含まれます。しかし、C での配列のほとんどの操作は、配列の要素へのポインターを介して行われ、ポインター演算を使用して 1 つの要素から次の要素に進みます。

推奨される読書 (私はこれをよく言います): comp.lang.c FAQのセクション 6 。

于 2013-03-29T00:03:59.220 に答える
1

配列重要なことに使用されます。配列は呼び出し元によって提供され、新しいコンテンツで変更されて返されます。合理的な観点からは、配列を埋めることが関数を呼び出す目的です。

于 2013-03-28T23:53:48.063 に答える
0

その配列 (配列参照) は実際にはポインターであり、char s[] は char *s と同じです。したがって、その結果をその配列に構築しているため、後でメインにコピーされます。K&R に「魔法」があることはめったにありません。

于 2013-03-28T23:50:26.580 に答える