Zeiger und Referenzen in C + + Teil 2

2. Mai, · 2009 Posted in C / C + +

Weiterbildung mit diesem Versuch Reihe von Beiträgen über Zeiger und Referenzen, die etwa zu sprechen begann Zeigern , diskutieren Artikeln heute.

Eine Referenz ist ein Alias für ein Objekt eines Pseudonyms gestattet. Neben der, der sagt, das ist nicht mich, sondern die sehr Bjarne Stroustrup , rund um das Thema 5.5 von seinem Buch , dessen Inhalt so gut ist, dass ich erst jetzt bemerken, dass die Abdeckung C. hat eine brechende Welle in Form von Ich mag das Cover!

Deklarieren von Referenzen

Ein Verweis auf einen bestimmten Typ deklariert ist oder durch Anhängen der Zeichen & (kaufmännisches Und-Zeichen ) nach dem Namen der Art der Bezugnahme. Beachten Sie, dass die gleiche Weise wie in der Deklaration von Zeigern, behandeln wir das &-Zeichen als eine Bewertung und nicht einen Betreiber. Es ist ein Operator-Deklaration von Zeigern oder Referenzen. Es ist nur eine Notation der Sprache. Angesichts eines Typs T, der Ausdruck bedeutet, T & T-Referenz. Zum Beispiel:

  / / Deklariert eine Integer-Variable Original.
 / / Es könnte auch sein, char, float, etc..
 int i;

 / / Deklariert Verweise auf die Variable i.
 / / Alle Formen sind gleichwertig, aber lieber den ersten.
 / / Beachten Sie, dass die Arten von Referenzen müssen die gleichen sein
 / / Die Variablen verwiesen wird.
 ra = i ; int & ra = i;
 rb = i ; int rb = & i;
 rc = i ; int & rc = i;

 / / Im Gegensatz zu Zeigern, die Zeile darunter generiert ein
 / / Compilation Fehler.  Man könnte sagen, warum?
 r1, & r2 ; int & R1 & R2; 

Während in C + + Referenzen erinnern einige Hinweise, sie sind ganz anders. Im Gegensatz zu, was geschieht mit Zeigern, müssen einen Hinweis in ihrer Deklaration initialisiert werden. Der Versuch, ohne eine Referenz zu initialisieren, erzeugt einen Fehler bei der Kompilierung, dh der Compiler wird in Ihrem Gesicht spucken zu erklären "Lost Playboy verloren." Die einzige Ausnahme von dieser Regel ist als Referenz deklariert als extern , da sie das Programm initialisiert werden an jedem anderen Punkt, aber das ist ein anderes Gespräch.

Wenn Sie versuchen, indem er erklärt, eine externe Referenz ohne zu initialisieren, wird der Compiler nicht beschweren, zu betrügen. Wenn es noch nie benutzt, ok. Wenn der Compiler ist intelligent und merken, dass es nicht verwendet werden, es kann sogar entfernen Sie sie aus der Liste der Symbole. Aber wenn es überall im Programm verwendet wird, wird der Linker auf Ihr Gesicht lachen, lachend, "undefined reference to 'nome_da_variavel'." Also die Dinge richtig machen. Erklärt einen Hinweis? So iniclalize es. extern? Bist du sicher, du weißt, was du tust?

Die Logik dahinter ist, dass ein Verweis geplant war, einen Namen für etwas sein. Wenn Sie nicht neu starten, wird es nicht umsonst Namen, dann macht es Sinn. Ein sehr wichtiges Detail ist, dass die Gründung eines Referenz ist es nicht zu einen Wert zuweisen. Da die prório Bjarne sagt, betreibt kein Betreiber auf Verweise, dh es gibt keine Möglichkeit, zuordnen, Addieren, Subtrahieren, etc mit einem Verweis. Als Referenz ist ein Alias für ein Objekt, wirkt jeder Betreiber NESE Objekt, nicht in der Referenz. Einmal initialisiert, eine Referenz immer dasselbe Objekt verweisen.

Die erste Falle, die mit Artikeln, sowie Hinweise ist die Frage der Größe. Während die Größe eines Zeigers (und andere Datenstrukturen) mit dem sizeof-Operator erzeugt werden können, die Größe eines Hinweises kann nicht mit konventionellen Methoden erreicht werden, da bei der Anwendung der Operator sizeof auf einen Verweis, sind wir eigentlich Anwendung des Operators auf das Objekt, auf die sie verweist, wie wir im vorhergehenden Absatz sah.

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
  char c;
 int i;
 double d;

   rc = c ; char & rc = c;
    ri = i ; int & ri = i;
 rd = d ; Doppel & rd = d;

 / / Der Operator sizeof sagt die Größe der Typ des Arguments.
 "Size of char:    " << sizeof ( c ) << " bytes" << endl ; cout <<"Größe der Zeichen:" <<sizeof (c) <<"bytes" <<endl;
 "Size of int:     " << sizeof ( i ) << " bytes" << endl ; cout <<"Größe von int:" <<sizeof (i) <<"bytes" <<endl;
 "Size of double:  " << sizeof ( d ) << " bytes" << endl ; cout <<"Größe von double:" <<sizeof (d) <<"bytes" <<endl;

 endl ; cout <<endl;

 "Size of char&:   " << sizeof ( rc ) << " bytes" << endl ; cout <<"Größe von char &:" <<sizeof (rc) <<"bytes" <<endl;
 "Size of int&:    " << sizeof ( ri ) << " bytes" << endl ; cout <<"Größe von int &" <<sizeof (ri) <<"bytes" <<endl;
 "Size of double&: " << sizeof ( rd ) << " bytes" << endl ; cout <<"Größe von double &:" <<sizeof (RD) <<"bytes" <<endl; 

Die Techniken zur Erlangung von den Größen der Referenzen sind über den Rahmen dieses Textes, aber ich will darüber später reden. Denn jetzt, ich werde einfach sagen, ohne dafür, dass gegebenenfalls, ist die Größe eines Verweises identisch mit der Größe eines Zeigers.

Der gute Teil der Geschichte ist, dass oft die Größen der Zeiger und Referenzen weit weniger relevant als die Größe des Objekts sind spitz oder indirekten Verweisen. Ich brauchte nie besonders auf diese Informationen benutzen, aber für die Entwicklung oder auf den unterschiedlichen Architekturen für Embedded-Systeme, hat es interessanter geworden.

Mit Referenzen

Die Verwendung von Artikeln ist jetzt viel einfacher, als die Zeiger, weil die Betreiber nicht verpflichtet sind, Adressen oder de-Referenzierung zu extrahieren. Variablenreferenzen als gemeinsame Variablen verwendet werden, der Feststellung, dass eine Operation auf einen Verweis auf die immer durchgeführt Objekt referenziert.

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
  int x, y;
 rx = x ; int & rx = x;
 ry = y ; int & ry = y;

 ; x = 13;
 ; y = 10;

 ; // A atribuição é automaticamente aplicada em x. rx = 42 / / Die Zuordnung wird automatisch angewendet, um x.
 // O incremento é automaticamente aplicado em y. ry + + / / Der Zuwachs wird automatisch angewendet, um y.

 "x:  " << x << endl ; // Valor de x. cout <<"x:" <<x <<endl / / Wert von x.
 "y:  " << y << endl ; // Valor de y. cout <<"y:" <<y <<endl / / Wert von y.
 "rx: " << rx << endl ; // Valor de rx == x. cout <<"RX:" <<rx <<endl / / Wert Rx == x.
 "ry: " << ry << endl ; // Valor de ry == y. cout <<"ry:" <<ry <<endl / / Wert ry == y. 

Mit einem Verweis lautet wie transparent für den Programmierer, braucht er nicht zu wissen, dass ist eine Referenz. Genau wie bei einem normalen variablen Einsatz. Mit meinem begrenzten Vorstellungskraft kann nicht sehen, wie jemand sein kann exkommuniziert für die Verwendung von Begriffen unangemessen. Obwohl es immer etwas Schwein Geist , der mit Artikeln kann Scheiße, ist viel einfacher, durch Aufstehen stolperte Saci auf Zeiger Griff.

Adressen und Referenzen

Vom Standpunkt der Murphy , Referenzen sind hässlich, langweilig und dumm, weil es wenig potenzielles Risiko für die mit ihnen zu tun. Selbst als es viele Überraschungen Adresse (wird?). Betrachten Sie den folgenden Code:

  17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
  10 ; int a = 10;
 13 ; int b = 13;

 ra = a ; int & ra = a;
 rb = b ; int & rb = b;

 ; Ra = 42;
 ; rb = 7;

 "ra  = " << ra << endl ; // O valor de ra == 42. cout <<"ra =" <<ra <<endl / / Der Wert der ra == 42.
 "rb  = " << rb << endl ; // O valor de rb == 7. cout <<"rb =" <<rb <<endl / / Der Wert von RB == 7.
 "a   = " << a << endl ; // O valor de a == ra == 42. cout <<"a =" <<a <<endl / / Der Wert der ra == == 42.
 "b   = " << b << endl ; // O valor de b == rb == 7. cout <<"b =" <<b <<endl / / Der Wert von b rb == == 7.

 "&a  = " << & a << endl ; // O endereço de a. cout <<"& a =" <<& a <<endl / / Die Adresse des a.
 "&b  = " << & b << endl ; // O endereço de b. cout <<"& b =" <<& b <<endl / / Die Adresse des b.
 "&ra = " << & ra << endl ; // O endereço de ra == &a. cout <<"& RA =" <<& ra <<endl / / Die Adresse des ra == & a.
 "&rb = " << & rb << endl ; // O endereço de rb == &b. cout <<"& rb =" <<& rb <<endl / / Die Adresse des rb == & b. 

Auf den Strecken 17.18 erkläre ich zwei Integer-Variablen (hätte tun dies mit einem Beispiel haben ...). Auf den Strecken 20.21 Ich erkläre zwei Referenzen, Verweisen auf die beiden vorangegangenen Variablen. Danach werden die Variablen RA und RB sind nur Aliase für die Variablen a und b. Wie wir bereits gesehen, jeder Betreiber die Verweise tatsächlich angewandt arbeitet auf der referenzierten Objekte, so dass jedes Paar mit variabler Referenz immer den gleichen Wert hat.

Der interessante Teil ist zu beachten, dass die Adressen der Fundstellen sind genau die gleichen Adressen der Variablen, die sie verweisen, im Gegensatz zu Zeigern, die ihre eigenen Adressen hatte. Warum? Weil Sie in sank Pegadinha Malandro tun . Denken Sie daran, dass das Gerede von einem Betreiber auf einen Verweis angewandt? Nun, der &-Operator verwendet hier ist die "Adresse", die angewendet wird auch direkt auf den ursprünglichen Variablen und nicht in den Artikeln. Die gleichen Techniken verwendet Ninja zu den Größen der Referenzen zu erhalten sind notwendig, um die Adressen von ihnen zu erhalten.

Auch der Spaß daran ist, dass die Referenz-Mechanismus wurde entwickelt, um so transparent wie möglich an den Programmierer. Maße und physikalischen Adressen von Referenzen sind irrelevante Informationen aus der Sicht des "normalen" Programm in C + +.

Unterschiede und Gemeinsamkeiten zwischen Zeiger und Referenzen

Beide Zeiger und Referenzen sind Mechanismen der Dereferenzierung in C + +, oder Mechanismen sind, die aus einem bestimmten Symbol (Variable) verwendet werde ich in der Lage, ein anderes Objekt zu manipulieren.

Die wichtigsten Anwendungen für Zeiger der Regel sind die Verwaltung und Bearbeitung von dynamischen Speicher, der Schaffung und Zerstörung von Objekten mit unterschiedlichen Formen und besondere Momente sowie die dazugehörigen "Parameterübergabe by reference" (so zitiert). Referenzen werden bereits in der Übergabe als Referenz (warum?) Und das Überladen von Operatoren verwendet.

Grundsätzlich können wir mit allen Artikeln kann mit Zeigern emuliert werden kann. Bereits reziprok ist nicht immer wahr. Der große Vorteil von ihnen ist jedoch, dass die Dereferenzierung völlig transparent für den Programmierer zu werden.

Eine interessante Allegorie besser helfen zu verstehen, die Unterschiede zwischen Zeiger und Referenzen ist der Spitzname. Zum Beispiel: Stell dir vor, dass eine Person, sagen wir, Dunga , ist unsere ursprüngliche Variable, das Objekt. Dunga ist bereits ein Hinweis auf Dunga, da sie Gegenstand ist ein Alias für die gleiche und dieselbe Person sind. Bereits die Mutter von Dunga (oder Dunga, was auch immer), die als lang ist durch die Menschenmenge zitiert werden, kann es als ein Zeiger auf, weil bestimmte Daten Betreiber Wortschatz, machte ihr ein Kompliment, ist eigentlich indirekt gezielte ihn.

Links

Kommentare

  • Hallo,

    Ich schätze das Kompliment.

    Die Zeit ist knapp, aber schreiben Sie die Fortsetzungen so bald wie möglich.
  • Bis weitere rechtliche
  • Partner Blab!

    Herzlichen Glückwunsch für den Artikel, sehr gut!

    [] S
  • Meine Naivität, wird angenommen, dass die Angelegenheit bereits beendet, wenn Sie ", sagte Vom Standpunkt der Murphy, die Verweise sind hässlich, langweilig und dumm, weil es wenig potentielle Gefahr mit ihnen zu tun." Anyway, bereits empfohlen Ihren Artikel für einen Anfänger, weil es ist eigentlich sehr gut erklärt für diejenigen, die die Unterschiede zwischen C und C + + wagen werden.

    Ich suche nach Fortsetzungen.

    [] S
  • Große Artikel!

    Leider sind die Verweise nicht so harmlos wie sie scheinen. Stellen Sie sich folgende Situationen:


    1. Jemand gibt einen Verweis auf eine nicht statische lokale Variable:


    QueroEconomizarCopiasDeString & string ()
    (
    String ret;
    / / Hack Hack Hack
    Rückkehr ret; / / smart guy ...
    )


    In diesem Fall wird der Anwendungsbereich endet, noch bevor jemand die Referenz verwendet.

    Die Lösung ist eine Referenz als Parameter erhalten und stellen nur eine Kopie: für die Variable "out".


    2. Jemand will dynamischen Speicher als normale Variablen verwenden:


    int main ()
    (
    int * pi = new int;

    / / Codezeilen zu vergessen, wer ist pi

    int & ri = pi * / / Ich denke Zeigern kompliziert

    / / Mehr Codezeilen an RI und PI vergessen

    pi zu löschen;

    / / Tcharammm ...

    Ri = 42 / / ist die Antwort auf alles, nicht wahr?
    )



    Diese Beispiele scheinen Tier, aber nicht so unwahrscheinlich, wie sie scheinen. Einfach den Code auf über mit Design Patterns oder sonstigen Unsinn verschwiegen werden und es explodiert, ohne dass Sie wissen, was passiert.

    [] S
  • Caloni, du bist ein Kerl stürzte zu:)

    Ja, Sie haben völlig recht. Aber ich lasse es Zweck.
    Ich habe auch noch nicht auf Zeiger oder Referenzen const gesprochen, auch nicht, dass Assoziation zwischen Zeigern und Arrays, aber ich will reden.

    Danke für das Kompliment, es ist sehr motivierend.

    Prost
Blog-Kommentare powered by Disqus