2016-04-29 15 views
2

Ich sehe oft Leute über C-Stil-Arrays mit einem Zeiger iterieren, während ich es besser finde, einen Index zu verwenden. Das folgende Beispiel veranschaulicht die zwei Möglichkeiten, über die ich nachdenke. Sie führen nicht zu der gleichen Demontage ...Wie kann ich am besten über ein C-Array iterieren? Mit Zeigern oder nach Index?

Meine Frage: Ist es vorteilhaft, einen "Läufer" anstelle eines Index zu verwenden? Übrigens, gibt es einen anderen Namen für die "Läufer" -Technik?

Kommt es auf den zugrunde liegenden Typ, z. int, char oder eine Struktur?

struct somestruct 
{ 
    float f; 
    int i; 
}; 

const unsigned int uiSize = 10000; 
somestruct * myarray = new somestruct[uiSize]; 
const somestruct * const pEnd = myarray + uiSize; 

// way 1: runner 
somestruct * pRunner = myarray; 
while(pRunner < pEnd) 
{ 
    pRunner->f += 5; 
    pRunner->i += 5; 
    ++pRunner; 
} 

// way 2: index 
unsigned int ui = 0; 
for (ui = 0; ui < uiSize; ++ui) 
{ 
    myarray[ui].f += 6; 
    myarray[ui].i += 4; 
} 
+3

Das ist C++ nicht C. Und ich denke, du meinst "Array" nicht "Vektor". – kaylum

+0

http://stackoverflow.com/a/11625741/187690 – AnT

+0

Ist es nicht wie beide gleich sind? –

Antwort

5

Es spielt keine Rolle, ob Sie integrale Indizierung oder Zeiger verwenden. Beide von Ihnen bereitgestellten Beispiele entsprechen jedoch nicht der Standardmethode in C (oder C++). Hier ist ein Umschreiben, das tut:

// way 1: runner 
for (somestruct * pRunner = myarray; pRunner != pEnd; ++pRunner) 

// way 2: index 
for (size_t ui = 0; ui < uiSize; ++ui) 

Wenn einfach alle Iterieren über die Elemente eines Behälters, wir immer for Loops verwenden, und nie while Loops, weil es kürzer und idiomatische ist (was bedeutet, jeder tut es auf diese Weise, so jeder kann es schnell lesen).

+1

"Es ist egal" - während ich mit Ihnen einverstanden bin Das, IMO, sollten Sie dennoch darauf hinweisen, dass beide Wege ** nicht semantisch äquivalent sind. –

0
array[index] 

Dies ist das gleiche (in C) wie *(array + index). Daher haben Sie zusätzlich zur Erhöhung der index auch einige * Zusätze, um den Zeiger array + index zu erhalten, den Sie dereferenzieren. Diese zusätzliche Addition ist nicht erforderlich, wenn Sie einen Zeiger direkt inkrementieren.

*) würde ich von jedem anständigen Compiler erwarten, dass dies zu einem einzigen zusätzlich zu bringen (und zwischenspeichern das Ergebnis in einem gewissen Register oder auf dem Stapel) pro Iteration. Von einem guten Compiler würde ich erwarten, dass er dieses Muster erkennt und Code generiert, der der direkten Verwendung von Zeigern entspricht.

Schlussbemerkung: Wenn Sie dies in einer sehr engen Schleife und den Compiler ist mit sind nicht Lage, anständigen Code und Ihr Profiler Dir sagte zu erzeugen, dass dies Ihr Leistungsengpass, bevorzugt die Lösung, die ist leichter zu verstehen und zu lesen.

+0

"er wird nicht benötigt, wenn Sie einen Zeiger direkt inkrementieren." Und was denken Sie, ist ein Zeiger-Inkrement dann, wenn nicht eine Addition (nach Größe von 1 Element)? – Lundin

+0

@Lundin Mit dem Zeiger erhöhen Sie ein "Ding", mit dem Index erhöhen Sie den Index und fügen den Index zum Basiszeiger hinzu. Also, zwei Additionen gegen eins. –

+0

Mit beiden Methoden laden Sie die Basisadresse in ein Indexregister. Der Unterschied besteht darin, dass bei der Array-Methode das Indexregister, das die Basisadresse enthält, erhalten bleibt und Sie dieses mit einem Wert hinzufügen und das Ergebnis in einem anderen Indexregister speichern. Mit der Zeigermethode ändern Sie das Indexregister, indem Sie das Ergebnis der Addition im selben Register speichern. Es ist nicht offensichtlich, warum eine Form auf einem generischen Computer schneller ist als die andere. Wahrscheinlich gibt es keinen oder zumindest keinen nennenswerten Unterschied. – Lundin

Verwandte Themen