void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
Warum ist die Ausgabe No, not equal
?
Javed Akram
void main() {
if("a" == "a")
printf("Yes, equal");
else
printf("No, not equal");
}
Warum ist die Ausgabe No, not equal
?
Tim Cooper
Was Sie vergleichen, sind die beiden Speicheradressen für die verschiedenen Zeichenfolgen, die an verschiedenen Orten gespeichert sind. Das sieht im Wesentlichen so aus:
if(0x00403064 == 0x002D316A) // Two memory locations
{
printf("Yes, equal");
}
Verwenden Sie den folgenden Code, um zwei Zeichenfolgenwerte zu vergleichen:
#include <string.h>
...
if(strcmp("a", "a") == 0)
{
// Equal
}
Zusätzlich, "a" == "a"
kann tatsächlich true zurückgeben, abhängig von Ihrem Compiler, der gleiche Strings zur Kompilierzeit zu einem kombinieren kann, um Platz zu sparen.
Wenn Sie zwei Zeichenwerte vergleichen (die keine Zeiger sind), handelt es sich um einen numerischen Vergleich. Zum Beispiel:
'a' == 'a' // always true
GCC hat auch die Optionen -fmerge-constants
und -fno-merge-constants
um das konstante Zusammenführen von Zeichenfolgen und Fließkommazahlen über Übersetzungseinheiten hinweg zu aktivieren/deaktivieren, obwohl es auf einigen GCCs scheint, dass das konstante Zusammenführen unabhängig von dieser Option immer aktiviert ist.
– Adam Rosenfield
30. Januar 2011 um 15:35 Uhr
Es würde funktionieren, wenn Sie ‘a’ anstelle von ‘a’ verwenden. Das erste ist ein Zeichen, das eigentlich ein numerischer Wert ist.
– GolezTrol
30. Januar 2011 um 15:41 Uhr
@GolezTrol: In C hat das wörtliche ‘a’ tatsächlich int
Typ. 🙂 Außerdem müssen Zeiger keine numerischen Werte sein.
– Bastien Léonard
30. Januar 2011 um 16:25 Uhr
int
ist auch numerisch, oder? Aber ich dachte, Zeichen wären Byte. Ganzzahl ist 4 Byte. Zeiger selbst sind ebenfalls ganzzahlig. Sie enthalten die Adresse einer Reihe von Daten (Daten, die tatsächlich nicht numerisch sein müssen).
– GolezTrol
30. Januar 2011 um 16:58 Uhr
'a' == 'A' // not true
… MySQL ist anderer Meinung.
– Stefan
30. Januar 2011 um 21:09 Uhr
gleich
Ich komme etwas spät zur Party, aber ich werde trotzdem antworten; technisch die gleichen Bits, aber von a bisschen andere Perspektive (C-Sprache unten):
In C ist der Ausdruck "a"
bezeichnet a String-Literalbei dem es sich um ein statisches unbenanntes Array von handelt const char
mit einer Länge von zwei – das Array besteht aus Zeichen 'a'
und '\0'
– Das abschließende Nullzeichen signalisiert das Ende der Zeichenkette.
In C können Sie jedoch auf die gleiche Weise Arrays nicht per Wert an Funktionen übergeben – oder ihnen Werte zuweisen (nach Initialisierung) – es gibt keinen überladenen Operator ==
für Arrays, daher ist es nicht möglich, sie direkt zu vergleichen. In Betracht ziehen
int a1[] = {1, 2, 3};
int a2[] = {3, 4, 5};
a1 == a2 // is this meaningful? Yes and no; it *does* compare the arrays for
// "identity", but not for their values. In this case the result
// is always false, because the arrays (a1 and a2) are distinct objects
Wenn die ==
vergleicht keine Arrays, was macht es dann eigentlich? In C, in fast allen Kontexten – einschließlich diesem – Arrays Verfall in Zeiger (die auf das erste Element des Arrays zeigen) – und der Vergleich von Zeigern auf Gleichheit macht das, was Sie erwarten würden. So effektiv, wenn Sie dies tun
"a" == "a"
du bist es tatsächlich Vergleichen der Adressen der ersten Zeichen in zwei unbenannten Arrays. Nach dem C-Standard kann der Vergleich entweder wahr oder falsch (dh 1 oder 0) ergeben – "a"
s kann tatsächlich dasselbe Array oder zwei völlig unabhängige Arrays bezeichnen. Technisch gesehen ist der resultierende Wert nicht spezifiziertwas bedeutet, dass der Vergleich zulässig ist (dh nicht undefiniertes Verhalten oder ein Syntaxfehler), aber jeder Wert ist gültig und die Implementierung (Ihr Compiler) muss nicht dokumentieren, was tatsächlich passieren wird.
Wie andere bereits betont haben, verwenden Sie zum Vergleichen von “c-Strings” (dh Strings, die mit einem Nullzeichen enden) die Convenience-Funktion strcmp
in Standard-Header-Datei gefunden string.h
. Die Funktion hat einen Rückgabewert von 0
für gleiche Saiten; Es wird als bewährte Methode angesehen, den Rückgabewert explizit mit zu vergleichen 0
anstatt den Operator `!´ zu verwenden, dh
strcmp(str1, str2) == 0 // instead of !strcmp(str1, str2)
Prasun Saurav
Gemäß C99 (Abschnitt 6.4.5/6)
Zeichenfolgenliterale
Es ist nicht angegeben, ob diese Arrays unterschiedlich sind, vorausgesetzt, ihre Elemente haben die entsprechenden Werte.
In diesem Fall ist also nicht spezifiziert, ob beides der Fall ist "a"
s sind verschieden. Ein optimierter Compiler könnte einen behalten "a"
am schreibgeschützten Ort und beide Referenzen könnten darauf verweisen.
Sehen Sie sich die Ausgabe auf gcc an hier
Antwan van Houdt
Weil sie 2 getrennt sind const char*
‘s, Zeiger, keine tatsächlichen Werte. Du sagst sowas wie 0x019181217 == 0x0089178216
was natürlich NEIN zurückgibt
Verwenden strcmp()
Anstatt von ==
Jonathan Holz
Einfach ausgedrückt, C hat keinen eingebauten String-Vergleichsoperator. Strings können auf diese Weise nicht verglichen werden.
Stattdessen werden Zeichenfolgen mit Standardbibliotheksroutinen wie strcmp() oder durch Schreiben von Code zum Durchlaufen jedes Zeichens in der Zeichenfolge verglichen.
In C gibt eine Textzeichenfolge in doppelten Anführungszeichen einen Zeiger auf die Zeichenfolge zurück. Ihr Beispiel vergleicht die Zeiger, und anscheinend existieren Ihre beiden Versionen der Zeichenfolge an unterschiedlichen Adressen.
Aber es vergleicht nicht die Saiten selbst, wie Sie es zu erwarten scheinen.
Lesmana
Zeiger.
Der Erste "a"
ist ein Zeiger auf eine nullterminierte ASCII-Zeichenfolge.
Der Zweite "a"
ist ein Zeiger auf eine andere nullterminierte ASCII-Zeichenfolge.
Wenn Sie einen 32-Bit-Compiler verwenden, würde ich erwarten "a"=="a"-4
. Ich habe es gerade mit tcc/Win32 versucht, und ich bekomme "a"=="a"-2
. Nun ja…
Ken
Sie vergleichen zwei Speicheradressen, daher ist das Ergebnis nicht immer wahr. Hast du versucht if('a' == 'a'){...}
?
void main
??? Äh…– PaulR
30. Januar 2011 um 15:59 Uhr
Eingebettete C-Compiler erlauben void main(), da es möglicherweise kein Betriebssystem gibt, dem ein Rückgabecode übergeben werden kann.
– Jeanne Pindar
30. Januar 2011 um 20:20 Uhr
Wie kann eine Frage wie diese so oft positiv bewertet werden? Es ist wirklich nicht so interessant … Ich meine, dass Strings Arrays und Arrays Zeiger sind, ist wirklich ein alter Hut in C, oder?
– Felix Dombek
31. Januar 2011 um 2:27 Uhr
@Felix, es ist eine prägnant geschriebene Frage, die einen häufigen Verwirrungspunkt für Neulinge in der Sprache anspricht. SO ist nicht nur etwas für Experten, sondern auch für Anfänger, und gezielte Fragen wie diese sind gut, um Anfänger in Zukunft darauf hinzuweisen.
– bdonlan
31. Januar 2011 um 3:00 Uhr
@Felix: Du liegst falsch. Arrays sind keine Zeiger
– Johannes Dibling
31. Januar 2011 um 20:52 Uhr