1

私はトリッキーなことに出くわしました。これは元のプログラムです:

#include <stdio.h>
int main(int argc, char *argv[])
{
    // go through each string in argv

    int i = 0;
    while(i < argc) {
        printf("arg %d: %s\n", i, argv[i]);
        i++;
    }

    // let's make our own array of strings
    char *states[] = {"cali","heo","arb","flu"};

    int num_states = 4;
    i = 0;  // watch for this
    while(i < num_states) {
        printf("state %d: %s\n", i, states[i]);
        i++;
    }

    return 0;
}

以下は、リンクで尋ねられた質問です: http://c.learncodethehardway.org/book/ex11.html

i-- を使用して argc から開始し、0 までカウントダウンすることにより、これらのループを逆方向にカウントします。配列インデックスが正しく機能するように、いくつかの計算を行う必要がある場合があります。

上記のこの質問については、上記のプログラムに修正を加えました。次のコードでは、while ループを 1 つしか実行できませんでした。両方のループを実行できません。私のコードを修正してください。

valgrindデバッグ用のツールを使用しました。

#include <stdio.h>
int main(int argc, char *argv[])
{
    int i = 2;
    while(i < argc) {
        printf("arg %d: %s\n", i, argv[i]);
        i--;
    }

    char *states[] = {
        "cali","heo","arb","flu"
    };

    int num_states = 4;
    i = 3;  // watch for this
    while(i < num_states) {
        printf("state %d: %s\n", i, states[i]);
        i--;
    }

    return 0;
}

出力:

$ make while
$ ./while hey how
2 how 
1 hey 
0 ./while 
Segmentation fault (core dumped)
$

そして、出力の別の方法については--

$ ./while
3 flu
2 arb 
1 heo 
0 cali 
Segmentation fault (core dumped)
$

したがって、「上記の方法で同時に両方の while ループを実行することはできない」という私の主張です。初期化i=2してデクリメントし、i値を 3 に再初期化しました。

4

6 に答える 6

2

and部分のwhileループの条件に不適切なロジックがありました。デクリメントにより最終的に 0 になるため、これらを両方のケースでまたは単純に変更します。while(i<argc)while(i<num_states)while(i>=0)while(i)i--

#include <stdio.h>
  int main(int argc, char *argv[])
{
int i = 2;   // If OP is certain argc is 2!Better use i=argc instead
while(i >= 0)   //Error was  here 
{
    printf("arg %d: %s\n",argc-i, argv[argc-i]); // alteration here
    i--;
}


char *states[] = {
    "cali","heo","arb","flu"
};

int num_states = 4;
i = 3;  // watch for this
while(i >=0) {  //alteration here
    printf("state %d: %s\n", num_states-i, states[num_states-i]); // Here too
    i--;
}

return 0;}

注意: 2 番目のプログラムのは、繰り返しごとに 1 ずつ減少し、4 に固定されたままwhile(i < num_states)の場合、毎回条件が満たされるため、大きな問題を引き起こすことは間違いありません。inum_states

于 2013-04-24T06:21:13.423 に答える
1

ループのアイデアはi、最大値に設定して開始しi、反復ごとに減少させることです。

i = argc;
while (--i >= 0)
    printf("arg %d: %s\n", i, argv[i]);

i = 4;
while (--i >= 0)
    printf("state %d: %s\n", i, states[i]);
于 2013-04-24T06:18:55.440 に答える
0

次のコード:

while(i < num_states) { <---------------------- HERE
    printf("state %d: %s\n", i, states[i]);
    i--;
}

あなたは実際にカウントダウンして間違った値をチェックしています。

でなければなりません:

 while(i >= 0)

ここ:

while(i < argc) {
    printf("arg %d: %s\n", i, argv[i]);
    i--;
}

同じ:

while(i >= 0)
于 2013-04-24T06:20:35.857 に答える
0

セグメンテーション違反は、i が負のときに argv[i] (または states[i]) を呼び出そうとしたことが原因ですが、これはループ構造の論理上の欠陥が原因です。

たとえば、最初のループでは次のようになります。

int i = 2;
while(i < argc) {
    printf("arg %d: %s\n", i, argv[i]);
    i--;
}

たとえば、argc が 4 だとします。あなたのコードは、i が 4 未満になるたびにループを繰り返すように指示しています。また、i は 2 で始まり、毎回下がるので、このループは永遠に繰り返される可能性があります。ループ条件は常に true と評価されます。ただし、最終的に i が負になり、それを配列インデックスとして使用しようとすると、セグメンテーション フォールトが発生します。それを修正する最も簡単な方法は次のとおりです。

int i = argc-1;
while(i >= 0) {
    printf("arg %d: %s\n", i, argv[i]);
    i--;
}

このように、i は argv の最後のインデックス (argc は配列内の要素の数であり、argv は要素 0 から始まる配列であるため、argc-1 です) から開始します。たとえば、argc が 5 の場合、このコードは次のようになります。 argv[0] から argv[4] を出力します)

while ループを考える最良の方法は、基本的な英語です。「y が true の間、x を繰り返し続ける」。あなたのコードでは、y は常に true であるため、x は永久に (または、この場合は、セグメンテーション エラーが発生するまで) 繰り返されます。

このロジックを他のループにも適用できるかどうかを確認してください。cを楽しく学ぼう!

于 2013-04-24T06:34:53.600 に答える