strcmp in C?
Diesmal eine Frage zu einer anderen Sprache^^
Wir haben einen Code bekommen in der die Funktion strcmp enthalten ist. Diese Funktion vergleicht zwei Strings, aber hier wurde noch ein ! davor gesetzt. Was genau das jetzt bewirkt weiß ich aber nicht. Eine Verneinung vielleicht?
Welche Bibliothek muss man einbinden, um strcmp nutzen zu können?
4 Antworten
Das ! ist der Negationsoperator. Er macht zB. aus einem true ein false und umgedreht.
In C berechnet das !, auf einen Integer angewandt, das Zweierkomplement. Also praktisch die binäre Darstellung der "negativen" Zahl
!3 = -3
!-4 = -(-4) = 4
!0 = 0
usw.
strcmp ist eine Funktion, die 0 zurück gibt, wenn die Strings identisch sind, eine Zahl kleiner 0, wenn die linke seite lexikographisch kleiner ist, als die rechte und eine Zahl größer null, wenn die linke seite größer ist.
Für return = 0 hätte es keine Auswirkung. Aber sobald die Strings nicht mehr identisch sind, musst du die Logik der Rückgabewerte umkehren.
warum macht man das?
strcmp(a, b) vergleicht a mit b
!strcmp(a,b) vergleicht aber b mit a.
Man könnte das natürlich auch strcmp(b,a) schreiben.
auf einen Integer angewandt, das Zweierkomplement.
Das bitweise Negieren ist in C ~. Der ! Operator ist die logische Negation, bei der alle Integerwerte außer 0 als TRUE gewertet werden.
Wenn die Strings gleich sind, wird der Ausdruck als "true" ausgwertet und Kontrollstrukturen verhalten sich entsprechend.
strcmp ist in string.h;
Wenn du das Ergebnis der Funktion negierst, bekommst du bei Gleichheit einen Wert ungleich 0 und bei Ungleichheit den Wert 0.
Das heist quasi, dass du bei Gleichheit den Wert "true" zurückbekommst.
Das ist leider etwas falsch. Da 0 == !0 ist, bekommst du bei Gleichheit immer noch 0 heraus. Du kannst ja nur den Rückgabewert selbst negieren.
ok, hab das mal probiert. Bei der 0 verhält sich der Compiler so wie du beschrieben hast. Scheinbar wird die 0 dann anders behandelt als alle anderen Integers, bei denen normalerweise das Zweierkomplement bei raus kommt.
Das bit-weise Negieren ist in C der ~ Operator, während ! das logische Negieren ist. !(a) ist gleichbedeutend mit (a) == 0.
Ich meine aber auch mal gehört zu haben, dass es in irgendeiner Programmiersprache so einen Operator gibt, also evtl. findest du dazu etwas.
Das wäre in C/C++/Python/etc. der Operator ~.
int i = 123;
printf("%d %d %d\n", i, ~i, !i);
//Ausgabe: 123 -124 0
Das ! ist ein logisches Nicht, die ~ ein Bitweises.
P.S.: ~0 == -1
Auch hier:
Die bitweise Neagtion ist nicht Äquivalent mit der Bildung des Zweierkomplements.
Das scheint du allerdings erkannt zu haben, wie dein Beispiel zeigt. Demnach liegt dein fehlschluss darin, dass du vermutetest, ich meine den bitweisen Negationoperator. dem ist nicht der Fall.
Das Zweierkomplement spielt in der Frage ja auch keine Rolle. Gefragt war nach:
!strcmp(a, b)
Scheinbar wird die 0 dann anders behandelt als alle anderen Integers, bei denen normalerweise das Zweierkomplement bei raus kommt.
https://www.gutefrage.net/frage/strcmp-in-c#comment-223799187
Darum ging es.
Welche Bibliothek muss man einbinden, um strcmp nutzen zu können?
Die zum Compiler/Linker gehörende Standardbibliothek.
Wenn diese dem "offiziellen" C-Standard folgt, dann kommt für die Deklarationen (damit der Compiler dem Linker überhaupt sagen kann, dass diese Funktion verwendet werden soll) der Header string.h.
Der Rückgabewert von strcmp gibt dabei an ob und falls ja inwiefern sich die beiden Strings unterscheiden.
Ist der Wert kleiner als 0, dann bedeutet das, dass das erste Zeichen, in dem sich beide Strings unterscheiden im ersten String einen niedrigeren Wert hat als das Zeichen im zweiten String an der selben Stelle, für größer als 0 gilt das umgekehrte.
Ist der Rückgabewert dagegen 0, dann sind beide identisch.
Jetzt zum !: In C gilt ein Ausdruck, der zu 0 ausgewertet wird als der boolesche Wert false, alles ungleich 0 als true.
Wenn man jetzt also überprüfen will, ob "String 1 und String 2 identisch sind", dann muss man überprüfen, ob strcmp 0 zurückgibt.
Wenn man nun if(!strcmp(s1, s2)) verwendet, dann überprüft man damit, ob das boolesche Gegenteil des Rückgabewertes true entspricht.
P.S.: Im Grunde könntest du strcmp auch selbst implementieren:
int strcmp(const char *s1, const char *s2){
for(;*s1==*s2;s1++, s2++);
return *s1-*s2;
}
Die gezeigte Implementierung von strcmp() würde nicht bei CHAR(0) abbrechen, sondern auch die Bytes dahinter vergleichen.
Nicht ganz.
Nehmen wir folgenden Testaufbau:
const char *s1 = ""; //Also s1[0] = 0
const char *s2 = "foo";
Dann haben wir beim ersten Schleifendurchlauf die Bedingung
'\0' == 'f'
Mit anderen Worten: Schleifenabbruch.
Und da '\0' - 'f' = -102, wird genau dieser Wert zurückgegeben.
Läuft also wie es soll.
Bei identischen Strings kommt es nicht zum (rechtzeitigen) Schleifenabbruch, würde ich meinen ;-), dann würde frühstens beim 1. Byte hinter \0 abgebrochen, falls es dann nicht schon zu spät ist.
Oh verdammt, stimmt. ^^;;;
Dann nehmen wir diese Implementierung:
int strcmp(const char *s1, const char *s2){
for(; *s1 == *s2 && *s1 && *s2; ++s1, ++s2);
return *s1 - *s2;
}
Ja, in C bedeutet ! eine Verneinung.
!(true!=false) bedeutet false.
Also falls für !strcmp(a,b) der String a mit dem String b übereinstimmt, wird der Code weiter ausgeführt?