2015-04-27 9 views
5

Die folgendeWas ist der Fehler in dieser String-Vergleichslogik?

#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; 
} 

druckt 1, meine Funktion Logik falsch ist Bedeutung. Ich würde gerne verstehen warum. Lassen Sie mich meine Logik erklären:

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

gleichzeitig Zeiger s1 und s2 so lange erhöht, wie s1 ungleich '\0' und der Wert s1 Punkte ist, ist der gleiche wie der Wert s2 Punkte. Es sollte eine kürzere Art des Schreibens

while (*s1 && *s2) 
{ 
    if (*s1 != *s2) break; 
    ++s1; ++s2; 
} 

sein und verlässt sich auf ausgefallene Operator Vorrang, um es zu verkürzen.

Die Anweisung

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

bedeutet

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

, weil, wenn die Zeichenkette gleich sind, dann s1 und s2 werden sowohl die Null-Zeichen nach der while Schleife sein.

Wo bin ich falsch?

+3

Haben Sie überlegt, einfach durch den Algorithmus zu gehen? Sie werden sehr schnell das Problem finden ... –

Antwort

12

Der Fehler ist, dass die ++ in der Schleife auch auf das letzte Zeichen erfolgt, wenn sie nicht übereinstimmen. Wenn das folgende Zeichen übereinstimmt (was in diesem Fall der Null-Terminator ist), werden sie als wahr verglichen.

+1

Ja; Ich würde 'while (* s1 && (* s1 == * s2)) schreiben {s1 ++; s2 ++; } Oder etwas. –

+0

Oh ... so ist es nicht kurzgeschlossen? –

+0

@CrappyProgrammer die '&&' Kurzschlüsse, wenn die erste Bedingung erfüllt ist, aber in diesem Fall war es nicht. –

4

Das Problem liegt in der Post Inkrementoperator

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

wenn Sie s1 nach dem Vergleich der letzten Nicht-Null-Zeichen erhöhen, gibt der Vergleich falsch, aber die Zeiger sowieso erhöht. Die falsche Auswertung führt zur Beendigung der while-Schleife. Aber in der nächsten Zeile verwenden Sie die Bedingung, dass die Zeiger auf Null-Zeichen zeigen (was sie tun), um eine Übereinstimmung der Zeichenfolgen anzuzeigen (was keine Übereinstimmung war). Daher berücksichtigt Ihr Code alle Zeichenfolgen, die übereinstimmen, auch wenn das letzte Zeichen nicht übereinstimmt.

+1

Das Inkrement ist nicht unbedingt ** nach ** Vergleich. Was passiert, ist, dass die Werte, die für den Vergleich verwendet werden, die Werte an dem vorherigen Sequenzpunkt sind und an dem nächsten Sequenzpunkt die Zeiger inkrementiert worden sind. Es gibt keine spezielle Reihenfolge, um die Inkremente und den Vergleich durchzuführen. * Das Denken auf diese Weise ist eine vereinfachte Ansicht, die Fehler in komplizierteren Ausdrücken induzieren kann. * – pmg

+0

@pmg Ja, es ist ziemlich schlecht formuliert. Ich habe es bearbeitet, um es besser erklären zu können. – mathematician1975