Confronto di matrici di caratteri con un operatore == in C
-
05-07-2019 - |
Domanda
So che il modo corretto di confrontare " stringhe " in C è usando strcmp
, ma ora ho provato a confrontare alcuni array di caratteri con l'operatore ==
e ho ottenuto strani risultati.
Dai un'occhiata al seguente codice:
int main()
{
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%d\n", s1 == s2); //1
printf("%d\n", s3 == s4); //0
printf("%d\n", s1 == s5); //0
}
Il primo printf
stampa correttamente un 1
, che indica che non sono uguali. Qualcuno può spiegarmi perché, confrontando gli array di caratteri, il ==
sta restituendo un 0
?
Qualcuno può spiegarmi perché il primo printf
sta restituendo un 1
(ovvero, sono uguali) e gli array di caratteri stanno restituendo un 0
?
Soluzione
== sta confrontando l'indirizzo di memoria.
È probabile che il tuo compilatore stia facendo s1 e s2 puntare agli stessi dati statici per risparmiare spazio.
es. L '"Andreas" nelle prime due righe di codice è memorizzato nei dati eseguibili. Lo standard C afferma che queste stringhe sono costanti e quindi ha optomizzato i due puntatori per puntare allo stesso archivio.
Le righe char [] creano una variabile copiando i dati nella variabile e quindi vengono memorizzati su un diverso indirizzo nello stack durante l'esecuzione.
Altri suggerimenti
Uh ... quando ==
stampa un 1, significa che sono uguali. È diverso da strcmp, che restituisce l'ordine relativo delle stringhe.
Stai confrontando gli indirizzi e non le stringhe. I primi due sono costanti e verranno creati una sola volta.
int main()
{
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%d\n", s1 == s2); //1
printf("%p == %p\n", s1, s2);
printf("%d\n", s3 == s4); //0
printf("%p != %p\n", s3, s4);
printf("%d\n", s1 == s5); //0
printf("%p != %p\n", s1, s5);
}
Uscita sul mio computer, ma hai l'idea:
1
0x1fd8 == 0x1fd8
0
0xbffff8fc != 0xbffff8f4
0
0x1fd8 != 0x1fe0
Aspetta un secondo ... 1 significa vero, 0 significa falso. Quindi la tua spiegazione è parzialmente arretrata. Per quanto riguarda il motivo per cui le prime due stringhe sembrano essere uguali: il compilatore ha creato quella stringa costante (s1 / 2) solo una volta.
s1 == s2
significa " (char *) == (char *)
" o che gli indirizzi siano gli stessi.
Stessa cosa per s3 == s4
. Questo è il " gli array decadono in puntatori " al lavoro.
E hai il significato del risultato del confronto sbagliato:
0 == 0; /* true; 1 */
42 == 0; /* false; 0 */
"foo" == "bar"; /* false (the addresses are different); 0 */
Tutti i valori da s1 a s5 non sono carattere , sono puntatori da a carattere . Quindi quello che stai confrontando sono gli indirizzi di memoria di ogni stringa, piuttosto che le stringhe stesse.
Se visualizzi gli indirizzi in questo modo, puoi vedere a cosa stanno effettivamente lavorando gli operatori di confronto:
#include <stdio.h>
int main() {
char *s1 = "Andreas";
char *s2 = "Andreas";
char s3[] = "Andreas";
char s4[] = "Andreas";
char *s5 = "Hello";
printf("%p\n", s1); // 0x80484d0
printf("%p\n", s2); // 0x80484d0
printf("%p\n", s3); // 0xbfef9280
printf("%p\n", s4); // 0xbfef9278
printf("%p\n", s5); // 0x80484d8
}
Esattamente dove le stringhe sono allocate in memoria è specifica dell'implementazione. In questo caso, s1 e s2 puntano allo stesso blocco di memoria statica, ma non mi aspetto che quel comportamento sia portabile.
Non puoi confrontare stringhe, ma puoi confrontare puntatori.