2010-01-12 7 views

Antwort

27

Das ist implementierungsabhängig. Gewöhnlich wird es jedes Mal aufgerufen, aber wenn der Compiler sehen kann, dass sich word niemals ändert, und dass strlen eine reine Funktion ist (keine Nebenwirkungen), kann es den Anruf anheben.

Siehe: http://underhanded.xcott.com/?page_id=15 für ein bekanntes Beispiel dafür ausgenutzt wird. :-)

+0

Das ist die richtige Antwort ... tatsächlich hängt es davon ab, wie clever der Compiler ist. – Noldorin

+0

Im Beispiel wurde dies mit einem 'char *' gemacht, was bedeutet, dass weder der Zeiger noch die Daten konstant waren. Macht gcc das wirklich? Es scheint unglaublich gefährlich zu sein. –

+0

@PP: Angenommen, Ihr 'Wort' wird nirgendwo anders innerhalb der Schleife übergeben (oder nur an eine Funktion übergeben, die' char const * '), und Ihr Code wird als single-threaded angesehen, und es ist kein Aliasing beteiligt weil die Funktion unary ist, oder weil der Zeiger als "restricted" deklariert ist. In diesem Fall würde ich sagen, dass es eine ziemlich sichere Annahme ist, dass sich die Daten nicht ändern werden. –

8

Es wird für jede Iteration der Schleife ausgewertet werden (edit: bei Bedarf).

Wie Tatu sagte, wenn word wird nicht in der Länge ändern, könnten Sie die strlen Anruf vor der for-Schleife tun. Aber wie Chris sagte, der Compiler kann gut genug sein, um zu erkennen, dass word nicht ändern kann, und die doppelten Aufrufe selbst zu beseitigen.

Aber wenn word in der Schleife in der Länge ändern können, dann müssen Sie natürlich den strlen Anruf in den Loop-Zustand halten.

+1

Eigentlich sollten die meisten Compiler dies optimieren, solange "Wort" nicht innerhalb des Schleifenkörpers geändert oder als "flüchtig" deklariert wird; Wie immer, können Sie die (Demontage-) Montage überprüfen, um zu sehen, was passiert ... – Christoph

+0

Bah, das ist weit von der vollständigen Antwort entfernt. Wenn der Compiler halbwegs brauchbar ist, sollte er den Aufruf wirklich optimieren, so dass er nur einmal ausgewertet wird. – Noldorin

+0

Das stimmt, ein Compiler kann schlau genug sein, um jedes Mal einen Anruf zu optimieren und zu vermeiden. –

0

strlen prüft die Länge der angegebenen Zeichenfolge. Das bedeutet, dass wenn die Länge 10 ist. Ihre Iteration wird so lange weitergehen, wie ich unter 10 bin.

Und in diesem Fall. 10 mal.

Read more about loops

+0

-1 weil die Zeichenkette innerhalb der Schleife modifiziert werden kann und somit 'strlen' unendlich oft aufgerufen werden könnte (vorausgesetzt, der Compiler speichert nicht das Ergebnis von' strlen() '). –

+0

Zusätzlich gab es im Beispiel keine Garantien, dass 'i' auch nicht verändert wurde. –

+0

Das ist ein dummer Grund, um abzustimmen. Angenommen, er manipuliert die Saite nicht. Es war mehr eine sehr grundlegende Erläuterung, wie es auf den ersten Blick aussehen würde und dann eine Referenz, wie Schleifen funktionieren. –

6

Ich werde manchmal Code, der als ...

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

... so dass Strlen nur einmal aufgerufen wird (die Leistung zu verbessern).

0

Es wird für jede Iteration aufgerufen. Der folgende Code ruft die strlen-Funktion nur einmal auf.

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

Die Anzahl der strlen(word) ausgeführt wird, ist abhängig von:

  1. Wenn word als Konstante deklariert wird (die Daten konstant ist)
  2. oder der Compiler kann erkennen, dass word nicht geändert wird.

Nehmen wir folgendes Beispiel:

char word[256] = "Grow"; 

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

In diesem Beispiel wird die Variable word withing der Schleife modifiziert:
0) "wachsen" - Länge == 4
1) „Wachsen *“- Länge == 5
2) "wachsen **" - Länge == 6

Allerdings kann der Compiler den strlen Aufruf ausklammern, so wird es einmal aufgerufen, wenn der varia ble word als konstant deklariert ist:

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

Die Funktion hat erklärt, dass die Variable word konstante Daten ist (tatsächlich ein Zeiger auf konstante Daten). Daher ändert sich die Länge nicht, so dass der Compiler strlen nur einmal aufrufen kann.

Im Zweifelsfall können Sie die Optimierung immer selbst durchführen, was in diesem Fall mehr lesbaren Code darstellt.

+3

Ein "const" -qualifizierter Zeiger ist nur ein Versprechen, dass der Zeiger nicht über diese spezifische Variable (ohne Casting) geändert wird, nicht dass die Daten selbst unveränderlich sind. – jamesdlin

Verwandte Themen