2013-06-12 11 views
6

私は以下のコードを書いてCの文字列を逆にしています。コードが正しく動作しているように見えます。そのため、私は混乱しています。誰もがここにエラーがない理由を知っていますか?私は、範囲外の配列または無限ループのforループを期待していましたが、ループが負の値になる前にブレークしているようです。文字配列 - forループが無限でないのはなぜですか?

#include <stdio.h> 
#include <string.h> 

void reverse(char* str); 

void reverse(char* str) 
{ 
    size_t len = strlen(str); 

    for(int i = (int)len-1; i<=len; i--) 
    { 
     printf("%c", str[i]); 
    } 
} 

int main (int argc, const char * argv[]) 
{ 
    char string[] = {'h', 'e', 'l', 'l', 'o', '\0'}; 
    reverse(string); 

    return 0; 
} 
+0

を '生成'論理的に正しいだものです。あなたが持っていたことは、「i」が「len」よりも小さい間は真実であり、常に真です。 –

+0

符号付き/符号なし比較は賢明ではありません。 http://stackoverflow.com/a/5416498/489590 –

+4

@Legend so?それは彼の質問に答えない、なぜ彼が働いているのか、私たちは皆それが正しく行われていることを知っている。 – Ulterior

答えて

16

size_tは、通常、符号なしとして定義されます。符号付きの番号または符号なしの番号または等しいランクを比較すると、符号付きの番号は符号なしに変換されます。符号付きの数値はおそらくマシンの2の補数で表されるので、実際には負の数が大きくなります。

だから、iが-1になると、それは大きくなり、比較結果はlenよりも大きいと考えられます。

これは、コンパイラで警告をオンにすることによって起こっていることがわかります。

を打ち鳴らす-Weverythingを使用してプログラムをコンパイルするために(int型I =(int型)のlen-1; I> = 0; I - )は、この警告に

unsigned.c:10:30: warning: comparison of integers of different signs: 
        'int' and 'size_t' (aka 'unsigned long') [-Wsign-compare] 
+0

ええ、これは正しいと思います。 –

+2

詳細修正:符号付きの番号と等しい番号の符号なしの番号を比較すると、符号付きの番号は_変換されてから符号なしになります。 – aschepler

+0

奇妙なことに、(size_t i = len-1; i <= len; i--)のような書き直しもうまくいくようです。参考までに、私はGNU gdb 6.3.50-20050815(Appleバージョンgdb-1708)x86_64-apple-darwinを使用しています。 – sager89

関連する問題