2010-01-12 10 views

Respuesta

27

Eso depende de la implementación. Generalmente, se llama cada vez, pero, si el compilador puede ver que word nunca cambia, y que strlen es una función pura (sin efectos secundarios), puede levantar la llamada.

Ver: http://underhanded.xcott.com/?page_id=15 para un conocido ejemplo de esto explotado. :-)

+0

Esta es la respuesta correcta ... de hecho, depende de cuán inteligente sea el compilador. – Noldorin

+0

En el ejemplo proporcionado, esto se hizo en un 'char *', lo que significa que ni el puntero ni los datos apuntados eran constantes. ¿GCC realmente está haciendo esto? Parece increíblemente peligroso. –

+0

@PP: suponga que su 'palabra' no pasa en ningún otro lugar dentro del bucle (o que solo pasa a una función que toma' char const * '), y su código se presume de subproceso único, y que no hay aliasing involucrado (tampoco porque la función es única, o porque el puntero se declara 'restringido'). En ese caso, diría que es una suposición bastante segura de que los datos no cambiarán. –

8

Se evaluará para cada iteración del bucle (edición: si es necesario).

Como dijo Tatu, si word no va a cambiar de longitud, puede hacer la llamada strlen antes del bucle for. Pero como dijo Chris, el compilador puede ser lo suficientemente bueno para darse cuenta de que word no puede cambiar y eliminar las llamadas duplicadas.

Pero si word puede cambiar de longitud durante el ciclo, entonces por supuesto deberá mantener la llamada strlen en la condición de ciclo.

+1

en realidad, la mayoría de los compiladores deberían optimizar esto siempre y cuando 'word' no se cambie dentro del cuerpo del bucle o se declare como' volátil'; como siempre, puede verificar (des) ensamblar para ver qué sucede ... – Christoph

+0

Bah, esto está lejos de ser la respuesta completa. Si el compilador es medio waqy decente, realmente debería optimizar la llamada, por lo que solo se evalúa una vez. – Noldorin

+0

Es cierto, un compilador puede ser lo suficientemente inteligente como para optimizar y evitar una llamada cada vez. –

0

strlen comprueba la longitud de la cadena proporcionada. Lo que significa que si la longitud es 10. Su iteración continuará mientras yo esté por debajo de 10.

Y en ese caso. 10 veces.

Read more about loops

+0

-1 porque la cadena se puede modificar dentro del ciclo y, por lo tanto, 'strlen' podría llamarse un número infinito de veces (suponiendo que el compilador no está almacenando en caché el resultado de' strlen() '). –

+0

Además, no hubo garantías en el ejemplo de que 'i' tampoco se haya modificado. –

+0

Esa es una razón estúpida para votar abajo. Asumiendo que él no altera la cuerda. Era más una explicación muy básica de cómo se vería en una primera mirada y luego una referencia de cómo funcionan los bucles. –

6

Voy a veces código que como ...

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

... para que strlen sólo se le llama una vez (para mejorar el rendimiento).

0

Se llamará para cada iteración. El siguiente código solo llama a la función strlen una vez.

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

El número de veces que se ejecuta strlen(word) depende de:

  1. Si word se declara como constante (los datos es constante)
  2. O el compilador puede detectar que word no se cambia.

Tome el ejemplo siguiente:

char word[256] = "Grow"; 

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

En este ejemplo, la variable word se modifica en el canto del bucle:
0) "crecer" - longitud == 4
1) "crecer *" - longitud == 5
2) "Crecer **" - longitud == 6

Sin embargo, el compilador puede factorizar la llamada strlen, por lo que se llama una vez, si la varia BLE word se declara como constante:

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

La función ha declarado que la variable es word datos constantes (en realidad, un puntero a los datos constantes). Por lo tanto, la longitud no cambiará, por lo que el compilador solo puede llamar al strlen una vez.

En caso de duda, siempre puede realizar la optimización usted mismo, que puede presentar un código más legible en este caso.

+3

Un puntero calificado de 'const 'es solo una promesa de que el pointee no se cambiará a través de esa variable específica (sin conversión), no que los datos sean inmutables. – jamesdlin

Cuestiones relacionadas