2016-01-25 12 views
10

ループはjから0(包括的に)になる必要があります。私j変数は、通常、符号なしでタイプsize_tです。無限ループを引き起こす符号なし整数を使用するとき、forループ条件で配列を逆方向に反復する

マイコード:

#include<stdio.h> 
#include<conio.h> 

#define SIZE 100 

int main(){ 
    char str[SIZE]; 
    size_t i=0; 
    size_t j; 
    puts("Enter any string"); 
    scanf("%s",str); 
    while(str[i]!='\0'){ 
     i++; 
    } 


    for(j=i-1;j>=0;j--){ 

     printf("%c",str[j]); 
    } 


    getch(); 
    return 0; 
} 

私は無限ループを取得します。ゼロの等価性を取り除くと、文字列の逆を最初の文字なしで出力します。だからここに何が問題なの?

答えて

6

size_tは符号なし整数であり、決して0より小さくなることはありません。 forループの条件が常に真であるので、 :あなたの状態では、あなたが\0ヌルを印刷していることを

for(j=i; j-- > 0;){ 
    ... 
} 

注:

for(j=i;j>=0;j--) 

あなたは(ビット醜いが)に条件を変更することができますバイトも印刷できない文字です。 (jは文字列の長さに等しい値で始まるため)。上記の条件でもそれが処理されます。

また:

  • あなたはそれの上に自分をループするのではなく、strlen()を使用することができます。
  • 入力読み取りが成功した場合は、戻り値scanf()を確認してください。
+0

はい、私はjは、フォームI-1を開始すべきであることに気づいたと私は –

+0

は私の問題を解くとありがとうありがとう固定します多くのソリューションと私は私がstrlen()を使用できることを知っている..しかし、あなたは私の理由muのコードが無限ループを引き起こしていることを説明することができます??と私はちょうどintによってsize_tを置き換えた場合、出力は正しいでしょう? size_t ??ループがj = 0になると仮定すると、要素0を出力し、その後は条件が偽になるので終了する必要があります。なぜ無限ループに入るのですか?? –

+1

'size_t'の場合、符号なし整数は0より小さい値を持つことはできません。したがって、jが0の場合、SIZE_MAX(size_tが保持できる最大値)になります。 SIZE_MAXが4294967295で、ループがj - > 0 - > 4294967295 - > 0 - >から実行され、サイクルが進行するとします。 'int'を使うと、期待どおりに動作します。しかし、 'size_t'は文字列の長さを見つけるための正しい型です.Hence、無限ループを取得します。 'int'を使うと、期待どおりに動作します。しかし、 'size_t'は、文字列の長さを見つけるための正しい型です。 –

2

符号なし整数はすべてCでラップします。符号なし整数は常に0以上です。コード:uint >= 0は常にtrueです。

SIZE_MAXとの比較は、size_t型の最大値であるため、SIZE_MAXと比較することができます。コードは繰り返し処理され、0に印刷されます。必要に応じてSIZE_MAXに折り返され、ループは終了します。 (これは文字列の長さがSIZE_MAXない前提としています。)

for(j=i; j < SIZE_MAX ;j--){ 

    printf("%c",str[j]); 
} 

はまた、あなたのコードがnull文字を印刷していることに注意してください。だから、開始インデックスは、文字列の長さが0である場合、ループのために何を印刷されませんので、ラッピングの振る舞いとうまく動作しますj=i-1、、、i-1 == SIZE_MAXためにする必要があります。

9
for(j=i; j>0; j--) { 
    printf("%c", str[j-1]); 
} 

他のオプションもあります。初心者のため
理解し、多分簡単に。
しかし、他の回答には良いだろう。

編集:私は最高だと言うでしょうfor(j=i; j-- > 0;)によってl3x。
0より大きいかどうかをチェックした後にjをデクリメントします。

do()while()ループも使用できます。

j = i; 
do { 
    j--; 
    printf("%c", str[j]); 
} while (j > 0); 
+1

これは、奇妙なフォーマットの醜いコードのまったく同じように見えます。 – Malina

5

あなたは、これは必ずすべてのデータがまだフィットになり、あなたが-1値に達することができるlongsize_tからjを変更することができます。サイドノートとして

for (j = i - 1;;--j) 
{ 
    // code 
    if (j == 0) break; 
} 

別のオプションは、次の文とforループを終了することで、あなたの最初のループはstring.hstrlen()と同じ処理を行いながら。

+0

'j = i;行う { ...; j-; } while(j!= 0); 'おそらくもっと読みやすくなります。 – Lundin

3

ダウンカウントループはあまりにも曖昧で読みにくい傾向があります。代わりに、この代替の使用を検討してください:

const size_t max = i-1; // maximum value that j can have 

for(j=0; j<=max; j++) 
{ 
    ... str[max-j]; 
} 
0

符号なし値がそうラップアラウンドj == 0とループがj--を行う際に、j >= 0はまだ本当です。 olleH

void reversePrint(char str[]) 
{ 
    size_t j = strlen(str); 
    while (j-- > 0) 
     printf("%c", str[j]); 
} 

は逆の順序で文字列を出力します:

基本と読みやすいソリューションは、このように書きます。

+0

Downvoters、説明してください? – Chnossos

+0

しかし、彼らはあなたが言ったやり方が気に入らなかったと思う。 "解読しやすい解が..." *: '..while(j - > 0)...'ユーザーに[この質問をする](http://stackoverflow.com/questions/1642028/what-is-the-name-of-theoperator-in-c);そして、第二に、文字列リテラル*、 'str'に' strlen'を積極的に使ってコンパイル時にサイズの長さを知っていることです。 – WhiZTiM

+0

私はあなたのポイントを得る。この編集はどうでしょうか? – Chnossos

1

問題はjunsignedあるのでj >= 0は常にtrueであるということです。

unsignedでゼロまでカウントすると、私は通常のpostfix --使用:

while (j-- > 0)