2013-06-12 28 views
6

Napisałem poniższy kod, aby odwrócić ciąg znaków w C. Kod wydaje się działać poprawnie i dlatego jestem zdezorientowany. Czy ktoś wie, dlaczego nie ma tu błędu? Spodziewałem się tablicy poza granicami lub nieskończonej pętli w pętli for, ale wygląda na to, że pętla zrywa się, zanim osiągnie ujemne wartości.Char Array - dlaczego pętla nie jest nieskończona?

#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

'for (int i = (int) len-1; i> = 0; i -)' to, co jest logicznie poprawne. To, co miałeś, byłoby prawdą, podczas gdy 'i' jest mniejsze niż' len', co zawsze jest prawdą. –

+0

Podpisane/niepodpisane porównanie jest nierozsądne. http://stackoverflow.com/a/5416498/489590 –

+4

@Legend so? to nie odpowiada na jego pytanie, dlaczego działa dla niego, wszyscy wiemy, jak to się robi właściwie – Ulterior

Odpowiedz

16

size_t jest generalnie zdefiniowane jako unsigned. Porównując liczbę podpisaną i niepodpisaną lub taką samą liczbę, podpisany numer jest konwertowany na niepodpisany. Ponieważ podpisany numer jest prawdopodobnie reprezentowany w dopełnieniu dwójki w twojej maszynie, liczby ujemne są faktycznie większe.

Więc raz i hits -1, to jest większe porównanie uważa, że ​​jest większy niż len.

Można to zobaczyć, włączając ostrzeżenie w kompilatorze.

Kompilacja swój program z brzękiem -Weverything produkuje to ostrzeżenie

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

Tak, myślę, że to jest poprawne. –

+2

Poprawki szczegółów: Gdy porównujesz podpisany i niepodpisany numer _of równej rangi_, podpisana liczba jest _konwertowana_ na niepodpisaną. – aschepler

+0

O dziwo, przepisywanie jak dla (size_t i = len-1; i <= len; i--) również wydaje się działać dobrze. Dla odniesienia używam GNU gdb 6.3.50-20050815 (wersja Apple gdb-1708) x86_64-apple-darwin. – sager89

Powiązane problemy