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 ?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top