1

こんにちは!次のコードについて疑問があります。

[1] for ループの中間条件はどういう意味ですか? ; *p;そして; *sval; - 入力文字列の終わりに達したか? はいの場合、それはどのように決定されますか?

[2] 複雑な for ループがわかりません。

条件が満たされない場合は、*p == %すぐに切り替えを行うとします。次に、反対のケースを考えてみましょう。%が満たされている場合でも、 1 つおきの文字を入力switchします。これらの2つのケースの違いは何ですか? 私はsthでひどく間違っているに違いありませんが、2時間以上間違いを見つけることができません...

#include <stdarg.h>
/* minprintf: minimal printf with variable argument list */
void minprintf(char *fmt, ...)
{
    va_list ap; /* points to each unnamed arg in turn */
    char *p, *sval;
    int ival;
    double dval;

    va_start(ap, fmt); /* make ap point to 1st unnamed arg */

    for (p = fmt; *p; p++) {         /* [1] */
        if (*p != '%') {
            putchar(*p);
            continue;                /* [2] */
        }
        switch (*++p) {
        case 'd':
            ival = va_arg(ap, int);
            printf("%d", ival);
            break;
        case 'f':
            dval = va_arg(ap, double);
            printf("%f", dval);
            break;
        case 's':
            for (sval = va_arg(ap, char *); *sval; sval++)
                putchar(*sval);
            break;
        default:
            putchar(*p);
            break;
        }
    }
    va_end(ap); /* clean up when done */
}

助けていただければ幸いです。

4

3 に答える 3

1

の場合continue、文字を出力するだけで、スイッチを完全にスキップします。ループは、(1) 終端のゼロ、または (2) パーセント記号を探してフォーマット行を通過します。

終端のゼロに達すると、ループが終了します。

for (p = fmt; *p; p++)
//            ^^^ Here is the condition: *p != 0 is implied

パーセント記号に達すると、次の記号がフォーマット文字として解釈され、次の vararg がそれに従って解釈されます。


このプログラムにはバグがあります。パーセント記号がフォーマット文字列の最後の文字である場合、フォーマット文字列の末尾を越えて読み取りが行われます (未定義の動作)。これを試して:

minprintf("%\0bug!bug!bug!");

シミュレートされた行末マーカー\0はスキップされ、bug!bug!bug!出力が生成されます。この理由はp、ステートメントのヘッダーにある無条件の pre_increment ですswitch。この問題を解決するには、次のケースを に追加しますswitch

 case '\0':
    p--; // reverse the ++p from the header of the switch
    break;
于 2012-08-17T13:02:25.910 に答える
1

*p *sval - 文字列内の char を指す逆参照ポインター。C では、文字列は "\0" 記号で終了します。したがって、p、sval ポイントがゼロの場所から取得した値が文字列の末尾に到達したことは明らかです。

2 in loop continue は、それに続くすべてのステートメントをスキップし、実行中のループヘッダーに戻るために使用されます (;;ステートメント)

于 2012-08-17T13:04:27.820 に答える
1
  • [1] は、文字列の null 終端文字が取得されなくなるまでループを続けること'\0'です。
  • [2] は、そうでない場合に文字を印刷すること'%'です。文字列内の次の文字が、リストから'%'次の文字を出力する方法を識別している場合。va_arg
于 2012-08-17T13:06:09.737 に答える