2013-07-22 12 views
6

ho questo codice:C stringhe Confronto con il segno di uguale

char *name = "George" 

if(name == "George") 
    printf("It's George") 

ho pensato che le stringhe C non potevano essere confrontato con == segno e devo usare strcmp. Per ragioni sconosciute quando compilo con gcc (versione 4.7.3) questo codice funziona. Ho pensato che fosse sbagliato perché è come confrontare i puntatori, quindi ho cercato su google e molte persone dicono che è sbagliato e non si può fare il confronto con ==. Quindi, perché questo metodo di confronto funziona?

+6

utilizzare 'strcmp()', si confrontano gli indirizzi. –

+0

Puoi controllare che qui http://stackoverflow.com/questions/13253113/strcmp-with-pointers-not-working-in-c. – someone

+1

@nouney Che cos'è UB? Non vedo alcuna ragione per questo. –

risposta

27

ho pensato che le stringhe C non potevano essere confrontati con il segno == e devo usare strcmp

destro.

ho pensato che questo era sbagliato, perché è come paragonare i puntatori così ho cercato in Google e molte persone dicono che è sbagliato e il confronto con == non può essere fatto

Proprio così troppo.

Quindi, perché questo metodo di confronto funziona?

Non funziona ". Sembra che solo funzioni.

Il motivo per cui questo accade è probabilmente un'ottimizzazione del compilatore: le due stringhe sono identiche, in modo che il compilatore genera davvero solo un esempio di loro, e utilizza quella stessa puntatore/matrice quando la stringa letterale viene fatto riferimento.

1

Ciò non riuscirà, dal momento che si confrontano due diversi puntatori di due stringhe separate. Se questo codice funziona ancora, questo è il risultato di una forte ottimizzazione di GCC, che mantiene solo una copia per l'ottimizzazione della dimensione.

Utilizzare strcmp(). Link.

+2

OP ha appena dichiarato che le stringhe si sono rivelate uguali. Sa anche perché 'strcmp()' dovrebbe essere usato. Questa non è una risposta. È anche sbagliato, perché "stai confrontando due diversi indicatori di due stringhe separate" non è vero - proprio per la ragione che ho spiegato nella mia risposta. –

+0

Le stringhe sono uguali, ma sono collocate in due diverse posizioni di memoria. Di conseguenza i loro indicatori sono diversi e il confronto è sbagliato. Se questo codice funziona ancora, questo è il risultato di una forte ottimizzazione di GCC. –

+0

"ma sono collocati in due diverse posizioni di memoria" - no, non lo sono, ti suggerisco infine ** leggere ** la mia risposta. –

4

Il confronto effettuato ha confrontato la posizione delle due stringhe, anziché il loro contenuto. Accade solo che il compilatore abbia deciso di creare solo una stringa letterale contenente i caratteri "George". Ciò significa che la posizione della stringa memorizzata in name e la posizione del secondo "George" sono uguali, pertanto il confronto restituisce valori diversi da zero.

Il compilatore non è tenuto a farlo, tuttavia, potrebbe facilmente creare due diversi valori letterali stringa, con posizioni diverse ma con lo stesso contenuto, e il confronto restituirebbe zero.

8

solo per fornire un riferimento di @ H2CO3 risposta:

C11 6.4.5 Le stringhe

È specificato se queste matrici sono distinti fornito loro elementi hanno i valori appropriati. Se il programma tenta di modificare tale array, il comportamento è indefinito.

Ciò significa che nel tuo esempio, name (una stringa letterale "George") e "George" possono e non possono condividere la stessa posizione, è fino alla realizzazione. Quindi non contare su questo, potrebbe risultare diversamente in altre macchine.

+3

Questo è veramente utile, +1. –

+0

+1, GCC inserirà tutti i valori letterali di stringa nella sezione .rodata ed è abbastanza intelligente da eliminare duplicati. :) – ludesign

0

Se si confrontano due punture a cui si stanno confrontando gli indirizzi di base di quelle stringhe non i caratteri effettivi in ​​quelle stringhe. per confrontare stringhe utilizzare le funzioni di libreria strcmp() e strcasecmp() o scrivere come questo. di seguito non è un codice completo solo la logica richiesta per il confronto delle stringhe.

void mystrcmp(const char *source,char *dest) 
{ 
    for(i=0;source[i] != '\0';i++) 
     dest[i] = source[i]; 
    dest[i] = 0; 

}