strcmp in C?

4 Antworten

Vom Fragesteller als hilfreich ausgezeichnet

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.

Woher ich das weiß:Berufserfahrung – Berufserfahrung

Destranix  22.10.2019, 11:15

!0 != 0, sondern !0 == 1;

0
franzmueller800 
Fragesteller
 22.10.2019, 11:19

Also falls für !strcmp(a,b) der String a mit dem String b übereinstimmt, wird der Code weiter ausgeführt?

0
Destranix  22.10.2019, 11:23
@franzmueller800

Wenn die Strings gleich sind, wird der Ausdruck als "true" ausgwertet und Kontrollstrukturen verhalten sich entsprechend.

1
mjutu  22.10.2019, 12:15
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.

0

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.


TheQ86  22.10.2019, 11:11

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.

0
TheQ86  22.10.2019, 11:18
@Destranix

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.

0
Destranix  22.10.2019, 11:20
@TheQ86

Bei anderen integers sollte dabei 0 herauskommen, auch nicht das Zweierkomplement.

Ich weiß nicht, woher du das hast.(Ich meine aber auch mal gehört zu haben, dass es in irgendeiner Programmiersprache so einen Operator gibt, also evtl. findest du dazu etwas.)

0
mjutu  22.10.2019, 12:13
@Destranix

Das bit-weise Negieren ist in C der ~ Operator, während ! das logische Negieren ist. !(a) ist gleichbedeutend mit (a) == 0.

0
Isendrak  22.10.2019, 12:16
@Destranix
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

1
Destranix  22.10.2019, 18:14
@mjutu

bitweise Negation != Zweierkomplementsbildung!

0
Destranix  22.10.2019, 18:16
@Isendrak

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.

1
Isendrak  22.10.2019, 18:32
@Destranix

Stimmt, Zweierkomplement wäre

int number = 123;
int twos_complement = (~number)+1;
1
mjutu  22.10.2019, 19:01
@Destranix

Das Zweierkomplement spielt in der Frage ja auch keine Rolle. Gefragt war nach:

!strcmp(a, b)

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

mjutu  22.10.2019, 12:11

Die gezeigte Implementierung von strcmp() würde nicht bei CHAR(0) abbrechen, sondern auch die Bytes dahinter vergleichen.

0
Isendrak  22.10.2019, 12:23
@mjutu

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.

0
KarlRanseierIII  22.10.2019, 12:39
@Isendrak

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.

1
Isendrak  22.10.2019, 12:42
@KarlRanseierIII

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

Ja, in C bedeutet ! eine Verneinung.

!(true!=false) bedeutet false.

Woher ich das weiß:Berufserfahrung – Programmierer