2010-01-12 19 views

risposta

27

Questo dipende dall'implementazione. Di solito, viene chiamato ogni volta, ma, se il compilatore può vedere che word non cambia mai e che strlen è una funzione pura (senza effetti collaterali), può sollevare la chiamata.

Vedere: http://underhanded.xcott.com/?page_id=15 per un noto esempio di questo sfruttamento. :-)

+0

Questa è la risposta giusta ... anzi, dipende da quanto intelligente sia il compilatore. – Noldorin

+0

Nell'esempio fornito ciò è stato eseguito su un 'char *' il che significa che né il puntatore né i dati puntati erano costanti. GCC sta davvero facendo questo? Sembra incredibilmente pericoloso. –

+0

@PP: Supponiamo che il tuo 'word' non venga passato da nessun'altra parte all'interno del ciclo (o passato solo a una funzione che assume' char const * '), e il tuo codice è presunto single-threaded e che non vi è alcun aliasing perché la funzione è unaria o perché il puntatore è dichiarato 'restricted'). In tal caso, direi che è un presupposto abbastanza sicuro che i dati non cambieranno. –

8

Sarà valutata per ogni iterazione del ciclo (edit: se necessario).

Come Tatu ha detto, se word non sta per cambiare in lunghezza, è possibile effettuare la chiamata strlen prima del ciclo for. Ma come ha detto Chris, il compilatore può essere abbastanza buono da comprendere che word non può cambiare ed eliminare le chiamate duplicate.

Ma se word è possibile modificare la lunghezza durante il ciclo, quindi, naturalmente, è necessario mantenere la chiamata strlen nella condizione di loop.

+1

in realtà, la maggior parte dei compilatori dovrebbe ottimizzare questo finché "word" non viene modificato all'interno del corpo del ciclo o dichiarato come "volatile"; come sempre, puoi controllare il (dis-) montaggio per vedere cosa succede ... – Christoph

+0

Bah, questo è lontano dalla risposta completa. Se il compilatore è mezzo waqy decente, dovrebbe davvero ottimizzare la chiamata in modo che venga valutata solo una volta. – Noldorin

+0

È vero, un compilatore può essere abbastanza intelligente da ottimizzare ed evitare ogni volta una chiamata. –

0

strlen controlla la lunghezza della stringa fornita. Il che significa che se la lunghezza è 10. La tua iterazione continuerà fino a quando io sono sotto 10.

E in tal caso. 10 volte.

Read more about loops

+0

-1 perché la stringa può essere modificata all'interno del ciclo e quindi 'strlen' potrebbe essere chiamato un numero infinito di volte (supponendo che il compilatore non memorizzi nella cache il risultato di' strlen() '). –

+0

Inoltre non ci sono garanzie nell'esempio che 'i' non sia stato modificato neanche. –

+0

Questa è una ragione stupida per il down-vote. Supponendo che non manomettere la stringa. Era più un'esplosione di base di come sembrerebbe a prima vista e poi di un riferimento come funzionano i loop. –

6

io a volte il codice che come ...

for (int i = 0, n = strlen(word); i < n; ++i) { /* do stuff */ } 

... in modo che strlen è chiamato solo una volta (per migliorare le prestazioni).

0

Sarà chiamato per ogni iterazione. Il seguente codice chiama solo una volta la funzione strlen.

for (i = 0, j = strlen(word); i < j i++) 
{ /* do stuff */ } 
1

Il numero di volte strlen(word) viene eseguita dipende:

  1. Se word è dichiarata come costante (il dato è costante)
  2. O il compilatore in grado di rilevare che word non viene modificato.

Prendiamo il seguente esempio:

char word[256] = "Grow"; 

for (i = 0; i < strlen(word); ++i) 
{ 
    strcat(word, "*"); 
} 

In questo esempio, la variabile word viene modificato withing loop:
0) "crescere" - lunghezza == 4
1) "Grow *" - lunghezza == 5
2) "Grow **" - lunghezza == 6

Tuttavia, il compilatore può scomporre la chiamata strlen, così è chiamato una volta, se varia BLE word è dichiarata come costante:

void my_function(const char * word) 
{ 
    for (i = 0; i < strlen(word); ++i) 
    { 
    printf("%d) %s\n", i, word); 
    } 
    return; 
} 

La funzione ha dichiarato che la variabile word è dati costanti (in realtà, un puntatore a dati costanti). Quindi la lunghezza non cambierà, quindi il compilatore può chiamare solo strlen una volta.

In caso di dubbio, è sempre possibile eseguire l'ottimizzazione autonomamente, che in questo caso potrebbe presentare un codice più leggibile.

+3

Un puntatore qualificato 'const' è solo una promessa che il pointee non verrà modificato tramite quella specifica variabile (senza il cast), non che i dati siano di per sé immutabili. – jamesdlin