2015-04-27 11 views
5

PoniższyJaka jest luka w tej logice porównywania ciągów znaków?

#include <iostream> 

unsigned short int stringCompare (char * s1, char * s2) 
{ 
// returns 1 if the character arrays s1 and s2 are equal; 
// returns 0 otherwise 
    while (*s1 && (*s1++ == *s2++)); 
    return (!(*s1) && !(*s2)); 
} 

int main() 
{ 
    char str1 [] = "americano"; 
    char str2 [] = "americana"; 
    std::cout << stringCompare(str1,str2); 
    return 0; 
} 

wydruki 1, czyli logika mojej funkcji jest nieprawidłowy. Chciałbym zrozumieć, dlaczego. Pozwól mi wyjaśnić moją logikę:

while (*s1 && (*s1++ == *s2++)) 

równocześnie zwiększa wskaźniki s1 i s2 tak długo, jak s1 nie jest równe '\0' a wartość s1 wskazuje jest taka sama jak wartość s2 punkty. Ma to być krótszy sposób pisania i polegania na precedensie operatorów, aby go skrócić.

Oświadczenie

return (!(*s1) && !(*s2)) 

oznacza

"If s1 and s2 are both the null character, return true; otherwise return false" 

bo jeśli ciągi są równe wtedy s1 i s2 będzie zarówno jako znak null po pętli while.

Gdzie ja się mylę?

+3

Czy zastanawiałeś się po prostu przechodząc przez algorytm? Bardzo szybko znajdziesz problem ... –

Odpowiedz

12

Błąd polega na tym, że ++ jest wykonywany w pętli nawet na ostatnim znaku, gdy nie pasują. Jeśli pasuje następujący znak (co robi w tym przypadku, terminator o wartości zerowej), wówczas porównuje się jako prawdziwy.

+1

Tak; Napisałem 'while (* s1 && (* s1 == * s2)) {s1 ++; s2 ++; } "Lub coś. –

+0

Oh ... więc nie ma zwarcia? –

+0

@CrappyProgrammer "&&" zwarcia, jeśli pierwszy warunek jest spełniony, ale w tym przypadku tak nie było. –

4

Problem polega na stanowisko operatora inkrementacji

while (*s1 && (*s1++ == *s2++)); 

gdy przyrost s1 po porównaniu ostatniej zakaz znak null porównanie zwraca false, ale wskaźniki są zwiększane tak. Fałszywa ocena prowadzi do zakończenia pętli while. Ale w następnej linii użyjesz warunku, w którym wskaźniki wskazują zarówno na puste znaki (które robią), aby wskazać dopasowanie łańcuchowe (które nie pasowało). W związku z tym twój kod będzie uwzględniał wszelkie łańcuchy do dopasowania, nawet jeśli ich ostatnia postać nie pasuje.

+1

Przyrost nie koniecznie ** po ** porównaniu. Co się dzieje, to wartości użyte do porównania są wartościami z poprzedniego punktu sekwencyjnego, a w następnym punkcie sekwencji wskaźniki zostały zwiększone. Nie ma określonego celu zrobić przyrosty i porównania w. * Myśląc o tym w ten sposób jest uproszczony widok, który może wywoływać błędy w bardziej skomplikowanych wyrażeń. * – pmg

+0

@pmg Tak sprawiedliwy punkt jest źle sformułowane. Zmontowałem go, aby spróbować wyjaśnić. – mathematician1975

Powiązane problemy