Ich halte Zuweisungsanweisungen und Zeigervariablen, um unter die wertvollsten Schätze der Informatik sein.
Donald Knuth, Strukturierte Programmierung mit Go zu StatementsIn der Informatik ist ein Zeiger eine Programmiersprache Objekt, dessen Wert bezieht sich direkt an ein anderes an anderer Stelle in dem Computerspeicher mit seiner Adresse gespeicherten Wert. Für High-Level-Programmiersprachen, Zeiger effektiv an die Stelle der Universalregister in Low-Level-Sprachen wie Assembler-Sprache oder Maschinencode, sondern können in den verfügbaren Speicher sein. Ein Zeiger verweist auf eine Stelle im Speicher, und Erhalten des an dieser Stelle gespeicherte Wert wird als Dereferenzierung des Zeigers bekannt. Ein Zeiger ist eine einfache, weitere konkrete Umsetzung der abstrakteren Referenzdatentyp. Mehrere Sprachen unterstützen eine Art Zeiger, obwohl einige haben mehr Einschränkungen für ihre Verwendung als andere. Als Analogie könnte eine Seitenzahl in einem Buch-Index als ein Zeiger auf die entsprechende Seite wird; Dereferenzierung wie ein Zeiger würde durch Umklappen auf die Seite mit der angegebenen Seitenzahl durchgeführt werden.
Zeiger auf Daten Leistung für sich wiederholende Vorgänge wie Verfahrgeschwindigkeit Streichern, Lookup-Tabellen, Steuertabellen und Baumstrukturen deutlich zu verbessern. Insbesondere ist es oft viel billiger in Zeit und Raum zu kopieren und Dereferenzierung Zeiger, als es zu kopieren und auf die Daten, auf die der Zeiger Punkt.
Zeiger werden auch verwendet, um die Adressen der Einstiegspunkte für aufgerufene Subroutinen in prozeduralen Programmierung und Laufzeit Verknüpfung mit Dynamic Link Libraries zu halten. Bei der objektorientierten Programmierung, sind Zeiger auf Funktionen zur Bindungsverfahren verwendet wird, oft mit, was als virtueller Methodentabellen finden.
Während "Zeiger" verwendet wurde, um zu den Referenzen im Allgemeinen beziehen, mehr richtig anwendet, um Datenstrukturen, deren Interface explizit erlaubt die Zeiger auf als Speicheradresse manipuliert werden, im Gegensatz zu einem Magic Cookie oder die Fähigkeit, wo dies nicht möglich ist. Da Zeiger erlauben sowohl geschützte als auch ungeschützte Zugriff auf Speicheradressen gibt es Risiken bei der Verwendung von ihnen vor allem im letzteren Fall verbunden. Primitive Zeiger werden häufig in einem Format ähnlich zu einer ganzen Zahl gespeichert sind; jedoch versuchen, dereferenzieren oder "nachschlagen" einen Zeiger, deren Wert war nie eine gültige Speicheradresse würde dazu führen, ein Programm zum Absturz bringen. Zur Linderung dieses potentielle Problem, als eine Frage der Typsicherheit, werden Zeiger als eine separate Art von der Art der Daten, auf die sie verweisen parametriert, auch wenn das zugrundeliegende Repräsentation eine ganze Zahl ist. Andere Maßnahmen können auch getroffen werden.
Geschichte
Harold Lawson ist mit 1964 Erfindung des Zeiger gutgeschrieben. Im Jahr 2000, Lawson präsentiert der Computer Pioneer Award der IEEE "oder die Erfindung des Zeigervariable und die Einführung dieses Konzept in PL / I, womit zum ersten Mal die Möglichkeit, flexibel in einem Mehrzweck-Hochsprache zu behandeln verkettete Listen ".
Formale Beschreibung
In der Informatik ist ein Zeiger eine Art Referenz.
Ein Daten primitive irgendein Datum, das gelesen oder in einem Computerspeicher mit einem Speicherzugriffs geschrieben werden können.
Ein Daten Aggregat ist eine Gruppe von Grundelementen, die im Speicher logisch zusammenhängenden sind und gemeinsam als ein Bezugspunkt betrachtet wird. Wenn ein Aggregat ist vollständig aus der gleichen Art von primitiven besteht, kann das Aggregat eine Anordnung genannt werden; In gewissem Sinne ist ein Multi-Byte-Wort primitive ein Array von Bytes, und einige Programme durch Wörter in dieser Weise.
Im Rahmen dieser Definitionen ist ein Byte die kleinste Primitivs; jede Speicheradresse gibt eine andere Byte. Die Speicheradresse des Anfangsbytes eines Datums wird als die Speicheradresse der gesamten Bezugspunkt.
Ein Speicherzeiger ist ein primitiver, deren Wert bestimmt ist, als Speicheradresse verwendet werden kann; Es wird gesagt, dass ein Zeiger auf eine Speicheradresse. Es wird auch gesagt, dass ein Zeiger auf einen Nullpunkt, wenn der Wert des Zeigers ist Speicheradresse das Datum des.
Allgemeiner ist ein Zeiger eine Art Referenz, und es wird gesagt, dass ein Zeiger verweist auf eine Bezugs irgendwo im Speicher gespeichert sind; zu erhalten, dass Datum ist zu dereferenzieren den Zeiger. Die Funktion, die Zeiger von anderen Arten von Referenz trennt, ist, dass der Wert eines Zeigers soll als Speicheradresse, die eine ziemlich Low-Level-Konzept interpretiert werden.
Referenzen dienen als Dereferenzierungsebene: Wert ein Zeiger bestimmt, welche Speicheradresse in einer Berechnung verwendet werden soll. Weil Indirektion ist ein grundlegender Aspekt von Algorithmen werden Zeiger oft als grundlegende Datentyp in Programmiersprachen zum Ausdruck; in statisch typisierten Programmiersprachen, den Typ eines Zeigers bestimmt den Typ des Datenelements an die der Zeiger zeigt.
Verwenden Sie in Datenstrukturen
Beim Einrichten Datenstrukturen wie Listen, Warteschlangen und Bäume ist es notwendig, um Zeiger, um die Verwaltung, wie die Struktur realisiert und kontrolliert werden müssen. Typische Beispiele für Zeiger Startzeiger, Ende Zeiger und Stapelzeiger. Diese Zeiger können entweder absolut oder relativ, die typischerweise verwendet weniger Bits als eine vollständige Adresse, aber es gewöhnlich erforderlich, eine zusätzliche Rechenoperation zu lösen).
Relative-Adressen sind eine Form der manuellen Speichersegmentierung, und teilen viele ihrer Vorteile und Nachteile. Ein Zwei-Byte-Offset, enthaltend eine 16-Bit Ganzzahl, kann verwendet werden, die relative Adressierung von bis zu 64 Kilobyte an einer Datenstruktur zur Verfügung zu stellen. Dies kann leicht zu 128K, 256K und 512K erweitert werden, wenn die Adresse, auf gezwungen ist, ausgerichtet werden - auf einem Halbwort, Wort oder Doppelwortgrenze. Generell sind jedoch solche Systeme eine Menge Ärger und Bequemlichkeit für den Programmierer absoluten Adressen bevorzugt.
Ein Ein-Byte-Offset, wie die hexadezimale ASCII-Wert eines Zeichens verwendet werden, um zu einem alternativen ganzzahligen Wert in einem Array verweist. Auf diese Weise können die Zeichen sehr effizient von "Rohdaten" übersetzt werden, um eine nutzbare Laufindex und dann in eine absolute Adresse ohne Nachschlagetabelle.
Einsatz in Steuertabellen
Steuertabellen, die verwendet werden, um Programmfluss zu steuern, in der Regel machen ausgiebigen Gebrauch von Zeigern. Die Zeiger, gewöhnlich in einem Tabelleneintrag eingebettet ist, kann zum Beispiel verwendet werden, um die Eintrittspunkte zu halten Subroutinen ausgeführt werden soll, auf Basis von bestimmten, in der gleichen Tabelleneintrag festgelegt hat. Die Zeiger können aber einfach Indizes für andere Teilbereiche, die zugehörigen, Tische, umfassend eine Anordnung von den tatsächlichen Adressen oder Adressen selbst zu sein. Sie können auch verwendet werden, um zu früheren Tabelleneinträge zeigen oder sich auf einige Tabelleneinträge überspringen werden. Zu diesem letzteren Zweck kann die "Zeiger" kann einfach die Tabelleneintragsnummer selbst sein und kann in eine tatsächliche Adresse durch einfache arithmetische transformiert werden.
Architektur Wurzeln
Zeiger sind eine sehr dünne Abstraktion auf der Oberseite der Adressierungsmöglichkeiten von den meisten modernen Architekturen bereitgestellt. Je nachdem, ob die Architektur ist byte-adressierbar oder Wort adressierbar - im einfachsten Schema wird eine Adresse oder ein numerischer Index wird zu jeder Einheit des Speichers in dem System, in dem die Einheit ist typischerweise entweder ein Byte oder ein Wort belegt - effektiv die Umwandlung der gesamte Speicher in ein sehr großes Array. Dann, wenn wir eine Adresse haben, stellt das System eine Operation, die in der Speichereinheit an dieser Adresse gespeicherten Wert abzurufen.
Im üblichen Fall, ist ein Zeiger groß genug, um mehrere Adressen zu halten, als es Speichereinheiten in dem System. Dies eröffnet die Möglichkeit, dass ein Programm kann versuchen, eine Adresse, die zu keinem Speichereinheit entspricht zugreifen, sei es, weil nicht genügend Speicher installiert ist, oder die Architektur unterstützt keine solche Adressen. Der erste Fall kann in bestimmten Plattformen wie die Intel x86-Architektur, ein Segmentation Fault aufgerufen werden. Der zweite Fall ist in der aktuellen Umsetzung der AMD64, wo Zeiger sind 64-Bit-langen und Adressen auf 48 Bits zu erweitern möglich. Es muss Zeiger auf bestimmte Vorschriften entsprechen, so dass, wenn eine nicht-kanonische Zeiger dereferenziert, hebt der Prozessor eine allgemeine Schutzverletzung.
Andererseits haben einige Systeme mehr Speichereinheiten gibt als Adressen. In diesem Fall wird eine komplexere System wie Speichersegmentierung oder Paging verwendet werden, um den verschiedenen Teilen des Speichers zu unterschiedlichen Zeiten verwendet werden. Die letzten Inkarnationen der x86-Architektur unterstützt bis zu 36 Bit der physikalischen Speicheradressen, die mit der 32-Bit-linearen Adressraum durch die PAE Paging-Mechanismus zugeordnet wurden. Somit wird nur 1/16 der möglichen Gesamtspeicher zu einem Zeitpunkt abgerufen werden. Ein weiteres Beispiel in dem gleichen Computer Familie war die 16-Bit-Protected-Mode der 80286-Prozessor, der, wenn auch die Unterstützung nur 16 MiB des physikalischen Speichers, könnte den Zugang zu 1 GiB des virtuellen Speichers, aber die Kombination von 16-Bit-Adresse und Segment Registern Zugriff auf mehr als 64 KiB in einer Datenstruktur umständlich. Einige Einschränkungen ANSI Zeigerarithmetik kann schon aufgrund der segmentierten Speicher Modelle dieser Prozessorfamilie haben.
Um eine einheitliche Schnittstelle zur Verfügung, einige Architekturen Memory-Mapped I / O, die einige Adressen, die die Einheiten im Speicher beziehen, andere beziehen sich auf Geräteregister von anderen Geräten im Computer ermöglicht. Es gibt analoge Konzepte wie Datei-Offsets, Array-Indizes, und Remote-Objektreferenzen, die einige der gleichen Zwecke wie Adressen für andere Arten von Objekten dienen.
Verwendungen
Zeiger werden direkt ohne Einschränkungen in Sprachen wie PL / I, C, C ++, Pascal und die meisten Montage Sprachen unterstützt. Sie werden vor allem für den Bau von Referenzen, die wiederum von grundlegender Bedeutung für die Konstruktion fast alle Datenstrukturen, sowie im Übergabe von Daten zwischen den verschiedenen Teilen eines Programms verwendet wird.
In funktionalen Programmiersprachen, die stark auf Listen sind Zeiger und Referenzen abstrakt von der Sprache über interne Konstrukte wie Nachteile verwaltet.
Wenn es sich um Anordnungen, die kritische Lookup-Operation beinhaltet typischerweise eine Stufe namens Adressenberechnung, welche die Konstruktion einen Zeiger auf den gewünschten Datenelement in dem Array umfasst. Wenn die Datenelemente in dem Array haben Längen, die teilbar durch Potenzen von zwei sind, ist diese arithmetische Regel etwas effizienter. Padding wird häufig als ein Mechanismus zur Sicherstellung diesem Fall verwendet wird, trotz der erhöhten Speicherbedarf. In anderen Datenstrukturen, wie beispielsweise verketteten Listen werden Zeiger als Referenz verwendet, um ein Stück der Struktur explizit binden zu einem anderen.
Zeiger werden verwendet, um die Parameter als Verweis übergeben. Dies ist nützlich, wenn der Programmierer will Änderungen einer Funktion auf einen Parameter sichtbar Anrufer der Funktion sein. Dies ist auch nützlich für die Rückgabe mehrerer Werte aus einer Funktion.
Zeiger können auch verwendet werden für die Zuweisung und freigeben dynamischen Variablen und Arrays im Speicher werden. Da eine Variable oft überflüssig geworden, nachdem sie ihren Zweck erfüllt, ist es eine Verschwendung von Speicher zu halten, und deshalb ist es eine gute Übung, um es freizugeben, wenn es nicht mehr benötigt wird. Bei Nichtbeachtung kann zu einem Speicherverlust führen.
C-Pointer
Die grundlegende Syntax, um einen Zeiger zu definieren ist:
Dies erklärt, wie die Kennung eines Objekts der folgenden Art:
- Zeiger, der auf ein Objekt vom Typ Punkte
Dies ist in der Regel kurz und bündig wie angegeben 'ist ein Zeiger auf.'
Da der C-Sprache nicht eine implizite Initialisierung für Objekte der automatische Speicherdauer anzugeben, sollte darauf oft getroffen, um sicherzustellen, dass die Adresse, an die gilt Punkte werden; aus diesem Grund ist es manchmal vorgeschlagen, dass ein Zeiger ausdrücklich auf die Null-Zeiger-Wert, die traditionell in C mit dem standardisierten Makro angegeben initialisiert wird:
Dereferenzierung eines Null-Zeiger in C produziert undefinierten Verhalten, die katastrophal sein könnten. Allerdings sind die meisten Implementierungen einfach zu stoppen Ausführung des Programms in Frage, in der Regel mit einem Segmentation Fault.
Allerdings Initialisieren Zeiger könnte unnötig Programmanalyse behindern und dadurch versteckte Wanzen.
In jedem Fall ist ein Zeiger einmal erklärt wurde, ist der nächste logische Schritt, damit es auf etwas zeigen:
Dies weist den Wert der Adresse zu. Wenn beispielsweise bei Speicherstelle 0x8130 gespeichert, dann wird der Wert von 0x8130 nach der Abtretung zu sein. Um den Zeiger dereferenzieren, wird ein Sternchen wieder verwendet:
Dies bedeutet, nehmen Sie den Inhalt des "lokalisieren", dass Adresse im Speicher und seinen Wert auf 8. Wenn später wieder zugegriffen wird, wird seine neue Wert 8 werden.
Dieses Beispiel kann klarer sein, wenn der Speicher direkt untersucht. Davon ausgehen, dass in der Adresse 0x8130 in Speicher und 0x8134 liegt; auch davon ausgehen, das ist ein 32-Bit-Maschine, so dass ein int ist 32-Bit breit. Hier finden Sie, was im Speicher, nachdem der folgende Codeausschnitt wird ausgeführt:
Durch die Zuordnung der Adresse zu:
ergeben sich folgende Speicherwerte:
Dann durch Dereferenzierung durch Codierung:
wird der Computer den Inhalt des "lokalisieren" diese Adresse zu nehmen, und weisen 8 bis dieser Stelle ergibt die folgende Speicher:
Klar, Zugreifen auf den Wert von 8 zu erhalten, weil der vorhergehende Befehl modifiziert den Inhalt der durch den Zeiger.
C-Arrays
In C ist Array-Indizierung formell im Hinblick auf die Pointer-Arithmetik definiert sind; das heißt, erfordert die Sprachspezifikation, die äquivalent zu sein. Somit in C, können Arrays als Zeiger auf aufeinanderfolgende Speicherbereiche betrachtet werden, und die Syntax für die Zugriff auf die Arrays identisch ist für das, was zu dereferenzieren Zeiger verwendet werden kann. Beispielsweise kann eine Anordnung angegeben und in der folgenden Weise verwendet werden:
Dies ordnet einen Block von fünf Zahlen und Namen der Block, der als ein Zeiger auf den Block wirkt. Eine weitere häufige Verwendung von Zeigern ist, darauf hinzuweisen, um dynamisch zugewiesenen Speicher von malloc, die eine fortlaufende Speicherblock von nicht weniger als der gewünschten Größe, die als Array verwendet werden kann, zurückkehrt.
Während die meisten Operatoren auf Arrays und Zeiger äquivalent sind, ist es wichtig zu beachten, dass der Operator abweichen. In diesem Beispiel wird zu bewerten, während wird, die Größe der Zeiger selbst auszuwerten.
Standardwerte eines Arrays kann wie deklariert werden:
Wenn Sie davon ausgehen, dass im Speicher diese liegt ab Adresse 0x1000 auf einem 32-Bit-Little-Endian-Maschine dann Speicher wird folgendes enthalten:
Hier vertreten sind fünf Zahlen: 2, 4, 3, 1 und 5. Diese fünf Zahlen belegen jeweils 32 Bits mit dem am wenigsten signifikanten Byte gespeichert erste und nacheinander ab Adresse 0x1000 gespeichert.
Die Syntax für C mit Zeigern ist:
- bedeutet 0x1000
- bedeutet 0x1004 (beachten Sie, dass die "+1" wirklich bedeutet, ein Mal die Größe eines nicht wörtlich "plus eine" add)
- bedeutet, zu dereferenzieren die Inhalte. In Anbetracht des Inhalts als Speicheradresse, sehen Sie den Wert an dieser Stelle.
- Mittel Elementnummer, 0-basierte, von denen Übersetzung
Das letzte Beispiel ist, wie man die Inhalte zugreifen. Zerlegung:
- ist die Speicherstelle des Elements
- Ball Speicheradresse und dereferenziert es, um den Wert zu gelangen.
Z.B. ist ein Synonym, Bedeutung, die sagt, dass "Dereferenzierung der Wert an gespeicherten", in diesem Fall.
C verknüpften Liste
Unten ist ein Beispiel Definition einer verknüpften Liste in C.
Beachten Sie, dass dieser Zeiger-rekursive Definition ist im Wesentlichen dasselbe wie das Referenz-rekursive Definition von Haskell Programmiersprache:
ist die leere Liste, und ist ein Wider Zelle des Typs mit einem anderen Link auch des Typs.
Die Definition mit Referenzen ist jedoch typüberprüft und verwendet keine potentiell verwirrenden Signalwerte. Aus diesem Grund, Datenstrukturen in C sind in der Regel mit über Wrapper-Funktionen, die sorgfältig auf Richtigkeit überprüft werden behandelt.
Pass-by-Adresse mit Hilfe von Zeigern
Pointer verwendet werden, um Variablen, die durch ihre Adresse übergeben, so dass ihr Wert geändert werden soll. Zum Beispiel sollten Sie Folgendes C-Code:
Dynamische Speicherzuweisung
Zeiger werden verwendet, um zu speichern und die Adressen von dynamisch zugewiesenen Speicherblöcke zu verwalten. Solche Blöcke werden verwendet, um Datenobjekte oder Anordnungen von Objekten. Die meisten strukturierten und objektorientierten Sprachen bieten ein Speicherbereich, die so genannte Heap oder Heap, aus denen Objekte werden dynamisch zugewiesen.
Das Beispiel C Code veranschaulicht, wie Struktur-Objekte werden dynamisch zugewiesen und verwiesen wird. Die Standard-C-Bibliothek stellt die Funktion für die Zuweisung von Speicherblöcken aus dem Haufen. Es nimmt die Größe eines Objekts als Parameter zuzuweisen und gibt einen Zeiger zu einem neu zugewiesenen Speicherblock zur Speicherung der Objekt oder es gibt einen Null-Zeiger, wenn die Zuweisung fehlgeschlagen.
Der folgende Code zeigt, wie Speicherobjekte sind dynamisch ausgeplant, dh wieder in den Heap oder Heap. Die Standard-C-Bibliothek stellt die Funktion zum Freigeben eines zuvor zugewiesenen Speicherblock und die Rückkehr es zurück in den Haufen.
Memory-Mapped-Hardware
Auf einigen Computing-Architekturen, können Pointer verwendet werden, um direkt zu manipulieren Speicher oder Speicherbild-Geräte werden.
Zuweisen von Adressen auf Zeiger ist ein unschätzbares Werkzeug bei der Programmierung von Mikrocontrollern. Im Folgenden finden Sie ein einfaches Beispiel Deklaration eines Zeigers vom Typ int und initialisiert es in eine hexadezimale Adresse in diesem Beispiel die Konstante:
Mitte der 80er Jahre, mit dem BIOS, um die Video-Fähigkeiten des PCs zugreifen langsam. Anwendungen, die Anzeigeintensiv waren typischerweise zur CGA-Videospeicher direkt durch Gießen der hexadezimalen Konstante auf einen Zeiger auf ein Feld von 80 unsigned 16 Bit int Werte zuzugreifen. Jeder Wert besteht aus einem ASCII-Code in das Low-Byte und eine Farbe im High-Byte. So, um den Buchstaben "A" in Zeile 5, Spalte 2 in hellen weiß auf blau, würde man Code wie den folgenden zu schreiben gestellt:
Typisierte Zeiger und Gießen
In vielen Sprachen haben Zeigern die zusätzliche Einschränkung, dass das Objekt die sie verweisen, hat einen bestimmten Typ. Zum Beispiel kann ein Zeiger angegeben werden, um in eine ganze Zahl zu zeigen; die Sprache wird dann versuchen, den Programmierer von Zeige es um Objekte, die keine ganzen Zahlen sind, wie zum Beispiel Fließkommazahlen zu verhindern, wodurch einige Fehler.
Beispielsweise in C
würde eine ganze Zahl Zeiger sein und wäre ein Zeiger auf char sein. Das folgende würde eine Compiler-Warnung von "Zuweisung von inkompatiblen Zeigertyp" unter GCC ergeben
da und wurden mit verschiedenen Arten erklärt. Um die Compiler-Warnung zu unterdrücken, muss sie explizit gemacht, dass Sie tatsächlich wollen, um die Zuordnung von typecasting machen werden
die sagt, um den ganzzahligen Zeiger auf einen char-Zeiger gegossen und zuweisen.
A 2005 Entwurf der C-Standard erfordert, dass Gießen einen Zeiger von einem Typ abgeleitet, um eine der anderen Art sollte die Ausrichtung Richtigkeit für beide Arten zu erhalten:
In Sprachen, die Zeigerarithmetik erlauben, Zeigerarithmetik berücksichtigt die Größe des Typs. Zum Beispiel, indem eine ganze Zahl auf einen Zeiger erzeugt einen anderen Zeiger, der auf eine Adresse, die durch diese Zahl mal die Größe des Typs höher verweist. Dies erlaubt uns, die Adresse der Elemente eines Arrays eines gegebenen Typs leicht berechnen, wie in der C-Arrays oben gezeigten Beispiel. Wenn ein Zeiger von einem Typ in einen anderen Typ von anderer Breite, sollte der Programmierer davon aus, dass die Zeigerarithmetik werden unterschiedlich berechnet. In C, zum Beispiel, wenn die Anordnung beginnt bei 0x2000 und 4 Bytes wohin beträgt 1 Byte, so wird auf 0x2004 weisen jedoch in den 0x2001 zeigen. Weitere Risiken Gießen gehören Verlust von Daten, wenn "breit" Daten werden in "engen" Stellen, unerwartete Ergebnisse geschrieben, wenn Bit-Verschiebungswerte und Vergleichs Probleme, vor allem mit vs unsigned Werte unterzeichnet.
Zwar ist es in der Regel nicht möglich, während der Kompilierung, die Würfe sind sicher zu bestimmen, in einigen Sprachen zu speichern Laufzeit-Typinformationen, die verwendet werden können, um zu bestätigen, dass diese gefährliche Würfe sind zur Laufzeit gültig ist. Andere Sprachen lediglich eine konservative Annäherung der sicheren Abgüsse oder keine nehmen überhaupt.
Erstellen Zeiger sicherer
Als ein Zeiger kann ein Programm versucht, ein Objekt, das nicht definiert werden kann, zuzugreifen, können Zeiger der Ursprung einer Vielzahl von Programmierfehlern. Jedoch ist die Brauchbarkeit der Zeiger so groß, dass es schwierig sein kann, die Programmieraufgaben ohne sie auszuführen. Folglich haben viele Sprachen Konstrukte entworfen, um einige der nützlichen Eigenschaften von Zeigern ohne einige ihrer Fallen bereitzustellen geschaffen, manchmal auch als Zeiger Gefahren bezeichnet. In diesem Zusammenhang sind Zeiger, die direkt adressieren Speicher als Ausgangszeiger im Gegensatz zu Smart Pointer oder andere Varianten bezeichnet.
Ein Hauptproblem mit Zeigern besteht darin, daß, solange sie kann direkt als Zahl manipuliert werden, können sie hergestellt, um ungenutzte Adressen oder Daten, die für andere Zwecke verwendet wird, verweisen. Viele Sprachen, einschließlich der meisten funktionalen Programmiersprachen und den letzten imperativen Sprachen wie Java, ersetzen Zeigern mit undurchsichtiger Typ Referenz, üblicherweise einfach als Referenz genannt, die nur dann verwendet werden kann, um auf Objekte und nicht als Zahlen manipuliert, um dies zu verhindern Art des Fehlers. Array-Indizierung wird als Sonderfall behandelt.
Ein Zeiger, die keine Adresse zugewiesen haben, nennt ein wilder Zeiger. Jeder Versuch, eine solche nicht initialisierten Zeiger verwenden können zu unerwartetem Verhalten führen, sei es, weil der ursprüngliche Wert ist keine gültige Adresse, oder weil Sie es können auch andere Teile des Programms beschädigt werden. Das Ergebnis ist oft ein Segmentation Fault, Lagerung Verletzung oder Wild Zweig.
In Systemen mit explizite Speicherzuordnung ist es möglich, eine dangling Zeiger um das Freigeben von Speicherbereich er in verweist. Diese Art der Zeiger ist gefährlich und subtil, weil ein ausgeplanten Speicherbereich kann den gleichen Daten enthalten, wie es tat, bevor es freigegeben wird, aber kann dann umgeschichtet und von unabhängigen Code, unbekannt zu dem früheren Code überschrieben. Sprachen mit Garbage Collection zu verhindern, diese Art von Fehler, weil Freigabe wird automatisch durchgeführt, wenn es keine weiteren Artikeln im Rahmen.
Einige Sprachen, wie C ++, unterstützen intelligente Zeiger, die eine einfache Form der Referenzzählung zu verwenden, um zu verfolgen Zuweisung von dynamischen Speicher zusätzlich zur als Referenz handeln zu helfen. In Ermangelung von Referenzzyklen, wo ein Objekt auf sich selbst indirekt durch eine Folge von Smart Pointer, diese zu beseitigen die Möglichkeit einer baumelnden Zeiger und Speicherlecks. Delphi-Strings unterstützen Referenzzählung nativ.
Null-Zeiger
Ein Null-Zeiger hat einen Wert für die anzeigt, dass der Zeiger nicht auf ein gültiges Objekt beziehen vorbehalten. Null-Zeiger werden routinemßig verwendet, um Bedingungen, wie das Ende einer Liste unbekannter Länge oder den Ausfall zu einer Aktion darstellen; Diese Verwendung von Null-Zeiger kann auf NULL festlegbaren Typen und mit dem Nichts Wert in einer Optionstyp verglichen werden.
Null-Zeiger werden oft als ähnliche Werte in relationalen Datenbanken null, aber sie sind etwas andere Semantik haben. Ein Null-Zeiger in den meisten Programmiersprachen bedeutet "keinen Wert", während ein Nullwert in relationalen Datenbank bedeutet "unbekannter Wert". Dies führt zu wichtigen Unterschiede in der Praxis: zwei Null-Zeiger werden in den meisten Programmiersprachen gleich betrachtet, aber zwei Nullwerte in relationalen Datenbanken nicht.
In einigen Programmiersprache Umgebungen ist die als Null-Zeiger verwendet Wert tatsächlich ein Zeiger auf einen Block aus internen Daten nützlich für die Umsetzung liegen, so dass dasselbe Register als nützlich Konstante und eine Möglichkeit, schnell auf die Umsetzung Einbauten verwendet werden. Dies wird als der Vektor bekannt.
In C werden zwei Null-Zeiger von jeder Art garantiert, um zu vergleichen, gleich. Das Makro wird als Implementierung definiert Null-Zeiger-Konstante, die in C99 portabel ausgedrückt werden, wie der Integerwert konvertiert implizit oder explizit auf die Art definiert.
Dereferenzierung des Nullzeiger führt typischerweise zu einem versuchten Lesen oder Schreiben von Speicher, der nicht abgebildet wird - Auslösung eines Segmentierungsfehler oder Zugriffsverletzung. Dies kann sich in den Entwickler, wie einem Programmabsturz darstellen, oder in eine Ausnahme, die gefangen werden können, umgewandelt werden. Es gibt jedoch durchaus Bedingungen, wo dies nicht der Fall. Zum Beispiel wird in 86-real-Modus, wird die Adresse 0000: 0000 ist lesbar und beschreibbar Regel, daher Dereferenzierung der Null-Zeiger ist ein perfekt gültig, aber in der Regel unerwünschte Aktion, die nicht definiert, aber nicht-Absturz Verhalten in der Anwendung führen kann. Beachten Sie auch, dass es Gelegenheiten, bei denen die Dereferenzierung den NULL ist beabsichtigt und gut definiert; zB BIOS-Code in C für 16-Bit-Real-Modus-x86-Geräte geschrieben wird, kann die IDT an der physikalischen Adresse 0 der Maschine zu schreiben von Dereferenzierung eines NULL-Zeiger für das Schreiben. Es ist auch möglich, dass der Compiler zur Optimierung entfernt die `NULL` Pointer-Dereference, vermeiden einen Segmentation Fault, aber was andere unerwünschte Verhalten.
In C ++, während das Makro wurde von C geerbt, die Ganzzahlliteral für Null traditionell bevorzugt worden, um eine Null-Zeiger-Konstante dar. Jedoch wurde C ++ 11 eine explizite konstanten stattdessen verwendet werden eingeführt.
Ein Null-Zeiger sollte nicht mit einem nicht initialisierten Zeiger verwechselt werden: Ein Null-Zeiger wird garantiert, um zu jedem Zeiger, der auf ein gültiges Objekt verweist vergleichen ungleich. Jedoch je nach Sprache und Umsetzung, eine nicht initialisierte Zeiger kann keine solche Garantie. Es könnte gleich Andere, gültige Zeiger zu vergleichen; oder es könnte zu vergleichen, gleich Null-Zeiger. Es könnte auch zu unterschiedlichen Zeiten zu tun.
Im Jahr 2009 C.A.R. Hoare erklärte, er erfand die NULL-Verweis im Jahr 1965 als Teil des Algol W Sprache, obwohl NIL in Lisp seit 1959 bestanden hatte, dass 2009 In Bezug Hoare beschreibt seine Erfindung als ein "Milliarden-Dollar-Fehler":
Da ein Null-Zeiger nicht zu einer sinnvollen Objekt zeigen, ein Versuch, die Dereferenzierung eines Null-Zeiger in der Regel führt zu einem Laufzeitfehler oder unmittelbaren Programmabsturz.
- In C ist das Verhalten der Dereferenzierung eines Null-Zeiger nicht definiert. Viele Implementierungen verursachen solchen Code in das Programm mit einem Segmentation Fault gestoppt führen, weil die Null-Zeiger-Darstellung gewählt wird, um eine Adresse, die niemals durch das System zum Speichern von Objekten zugeordnet werden. Allerdings ist dieses Verhalten nicht universell.
- In Java, Zugang zu einer Nullreferenz löst ein, der durch Fehlerbehandlungscode abgefangen werden kann, aber die bevorzugte Praxis ist es, sicherzustellen, dass solche Ausnahmen nie auftreten.
- In.NET, Zugriff auf NULL-Verweis löst eine Nullreferenceexception geworfen werden. Obwohl fangen diese wird in der Regel als schlechte Praxis kann diese Ausnahmetyp erfasst und vom Programm behandelt werden.
- In Objective-C kann Nachrichten an ein Objekt, ohne dass das Programm unterbrochen werden soll gesendet werden; die Nachricht einfach ignoriert, und der Rückgabewert ist, oder je nach dem Typ.
In Sprachen mit einer markierten Architektur kann eine eventuell Null-Zeiger mit einer markierten Union, die explizite Behandlung des Ausnahmefall erzwingt ersetzt sein kann; in der Tat kann eine evtl. Nullzeiger als getaggten Zeiger mit einem rechnerischen Tag gesehen werden.
Autorelative Zeiger
Der Begriff autorelative Zeiger kann auf einen Zeiger, deren Wert als ein Offset von der Adresse des Zeigers selbst interpretiert beziehen; Wenn somit eine Datenstruktur ,, hat einen autorelative Punkteinstellglied ,, die zu einem gewissen Teil selbst angibt, dann kann in dem Speicher, ohne den Wert zu aktualisieren, verlagert werden.
Die zitierten Patent verwendet auch den Begriff Selbst relativen Zeiger auf das gleiche bedeuten. Allerdings hat die Bedeutung dieses Begriffes auch auf andere Weise verwendet:
- Es wird oft verwendet, um einen Offset von der Adresse einer Struktur anstatt von der Adresse der Zeiger selbst bedeuten.
- Es wurde verwendet, um einen Zeiger enthält eine eigene Adresse, die nützlich für die Rekonstruktion in jeder beliebigen Speicherbereich eine Sammlung von Datenstrukturen, die zueinander weisen darauf sein kann bedeuten.
Basierend Zeiger
Ein auf der Basis ist ein Zeiger, dessen Wert ein Offset vom Wert eines anderen Zeiger. Dies kann verwendet werden zum Speichern und Laden von Datenblöcken, die Zuordnung der Adresse des Beginns des Blocks zu der Basiszeiger.
Mehrere Umleitungs
In einigen Sprachen kann ein Zeiger eine andere Zeiger verweisen, neuequiring mehrere dereferenzieren Vorgänge auf den ursprünglichen Wert zu erhalten. Während jede Dereferenzierungsebene kann einen Leistungskosten hinzuzufügen, ist es manchmal notwendig, um eine korrekte Verhalten für komplexe Datenstrukturen zu schaffen. Beispielsweise in C ist es typisch, eine verknüpfte Liste in Bezug auf ein Element, das einen Zeiger auf das nächste Element der Liste enthält definieren:
Diese Implementierung verwendet einen Zeiger auf das erste Element in der Liste als ein Ersatz für die gesamte Liste. Wenn ein neuer Wert auf den Beginn der Liste hinzugefügt wird, muss verändert werden, um auf das neue Element zu zeigen. Da C Argumente werden immer als Wert übergeben, mit doppelten Indirektion erlaubt das Einfügen korrekt implementiert werden und hat den wünschenswerten Nebeneffekt Beseitigung besonderer Fall Code, um mit Insertionen an der Vorderseite der Liste zu tun:
In diesem Fall, wenn der Wert geringer ist als der von der Anrufer ist ordnungsgemäß an die Adresse des neuen Elements aktualisiert.
Ein einfaches Beispiel ist in der argv Argument an die Hauptfunktion in C, die in der Prototyp als gegeben wird - dies ist, da die Variable selbst ist ein Zeiger auf ein Feld von Zeichenketten, so wird ein Zeiger auf den 0-ten String und die 0. Charakter des 0-ten String.
Funktionszeiger
In einigen Sprachen kann ein Zeiger ausführbaren Code, dh Referenz, kann es zu einer Funktion, Methode oder Vorgehensweise zeigen. Ein Funktionszeiger speichert die Adresse einer Funktion aufgerufen wird. Während dieser Anlage können Funktionen dynamisch nennen werden, ist es oft eine Lieblingstechnik von Viren und anderer bösartiger Software Schriftsteller.
Wilde Zeigern
Ein wilder Zeiger ist ein Zeiger, die nicht initialisiert worden ist, und kann ein Programm zum Absturz zu bringen oder verhalten sich seltsam. In der Pascal oder C-Programmiersprachen, können Zeiger, die nicht speziell initialisiert Unvorhersehbare Adressen im Speicher verweisen.
Der folgende Beispielcode zeigt eine wilde Zeiger:
Hier kann, um überall im Speicher zeigen, so dass die Durchführung der Zuordnung kann beschädigt ein unbekannter Bereich des Speichers oder lösen einen Segmentation Fault.
Wilde Zweig
Wo ein Zeiger wird als die Adresse des Zugangspunkt zu einem Programm oder Beginn eines Unterprogramms verwendet und ist auch entweder nicht initialisierte oder beschädigt wird, wenn ein Anruf oder Sprung dennoch an diese Adresse gemacht wird, wird ein "wilder Zweig", so eingetreten, . Die Folgen sind meist nicht vorhersehbar, und der Fehler kann sich auf verschiedene Weise abhängig davon, ob oder ob nicht die Zeiger ein "gültig" Adresse und ob es einen gültigen Befehl an dieser Adresse oder aber nicht vorhanden. Der Nachweis eines wilden Zweig kann, da ein Großteil der Beweise eines der schwierig und frustrierend Debugging-Übungen präsentieren kann bereits im Vorfeld oder durch die Ausführung einer oder mehrerer Anweisungen unangemessen an der Zweigstelle zerstört. Falls verfügbar, einen Befehlssatz-Simulator kann in der Regel nicht nur eine wilde Zweig zu erkennen, bevor sie wirksam wird, sondern bieten auch eine vollständige oder teilweise Spur von seiner Geschichte.
Simulation mit einem Array-Index
Es ist möglich, Zeigerverhalten zu simulieren unter Verwendung eines Index in ein Array.
Vor allem für Sprachen, die keine Zeiger unterstützen explizit, aber tun Support-Arrays kann die Anordnung von dacht und verarbeitet, als ob es die gesamte Speicherbereich und jeder Index, es kann als äquivalent zu einem Mehrzweckregister in Assembler gedacht werden waren werden. Vorausgesetzt das Array, sagen wir, ein zusammenhängendes 16-Megabyte-Zeichendatenstruktur können einzelne Bytes direkt angesprochen und manipuliert unter Verwendung des Namens des Array mit einem 31-Bit-Ganzzahl ohne Vorzeichen, wie der Zeigerdarstellung. Zeigerarithmetik kann durch Addieren oder Subtrahieren von dem Index, mit minimalem zusätzlichen Aufwand im Vergleich zu echten Zeigerarithmetik simuliert werden.
Es ist auch theoretisch möglich, unter Verwendung der oben genannten Technik, zusammen mit einem geeigneten Befehlssatz-Simulator, um jede Maschinencode oder die Zwischen jeder Prozessor / Sprache in eine andere Sprache, die keine Zeiger unterstützt haupt simulieren. Um dies zu erreichen, kann der binäre Code zunächst in zusammenhängende Bytes des Arrays geladen werden für den Simulator zu "lesen", zu interpretieren und Maßnahmen vollständig innerhalb des desselben Arrays enthaltenen Speicher. Wenn nötig, um Pufferüberlauf-Probleme vollständig zu vermeiden, können Längenprüfung in der Regel für den Compiler actioned werden.
Support in verschiedenen Programmiersprachen
Ada
Ada ist eine stark typisierte Sprache, in der alle Zeiger sind typisiert und nur sichere Typumwandlungen sind erlaubt. Alle Zeiger sind standardmäßig initialisiert, und jeder Versuch, Daten über einen Zeiger zugreifen verursacht eine Ausnahme zu erheben sind. Zeiger in Ada sind Zugriffsarten bezeichnet. Ada 83 nicht erlaubte arithmetischen auf Zugriffsarten, aber Ada 95 unterstützt "sicher" Arithmetik auf Zugriffsarten über das Paket.
BASIC
Einige alte Versionen von BASIC für die Windows-Plattform hatte Unterstützung für STRPTR, um die Adresse eines Strings zurück, und für VARPTR, um die Adresse einer Variablen zurück. Visual Basic 5 hatte auch Unterstützung für ObjPtr, um die Adresse eines Objekts Schnittstelle zurückzukehren und für eine AddressOf-Operator, um die Adresse einer Funktion zurückzukehren. Die Typen von all diesen sind ganze Zahlen, aber ihre Werte, die den von Zeigertypen gehalten werden.
Neuere Dialekte von BASIC, wie zum Beispiel Freebasic oder BlitzMax, haben Anspruch auf Vollständigkeit Zeiger-Implementierungen, aber. In Freebasic, Zeigerarithmetik werden behandelt, als ob der Zeiger ein Byte-Breite. Pointer kann nicht in C dereferenziert werden, als auch, Gießen zwischen Zeigern und jede andere Art von erhalten keine Warnungen zu generieren.
C und C ++
In C und C ++ Zeiger sind Variablen, die Adressen zu speichern und kann null sein. Jeder Zeiger hat einen Typ es um Punkte, aber man kann sich frei zwischen Zeigertypen gegossen. Eine spezielle Zeigertyp als "Leerzeiger" ermöglicht, die auf jeden Variablentyp, wird jedoch durch die Tatsache, dass er nicht direkt dereferenced beschränkt. Die Adresse selbst können oft direkt durch Gießen eines Zeigers zu und von einem integralen Typ von ausreichender Größe bearbeitet werden, obwohl die Ergebnisse durch die Implementierung definiert und kann in der Tat zu undefinierten Verhalten; während früher C-Normen nicht über einen integrierten Typ, der gewährleistet war groß genug sein, C99 legt die in definierten typedef Name, sondern eine Umsetzung muss nicht bieten es.
C ++ unterstützt C Zeiger und C Typumwandlung. Es unterstützt auch eine neue Gruppe von Typecasting Betreibern zu helfen, fangen einige unbeabsichtigte gefährliche Würfe zur Übersetzungszeit. Da C ++ 11 stellt die C ++ Standardbibliothek auch intelligente Zeiger, die in einigen Situationen als sichere Alternative zu primitiven C-Pointer verwendet werden kann. C ++ unterstützt auch eine andere Form der Referenz, ganz anders als ein Zeiger, genannt einfach eine Referenz oder Verweistyp.
Pointer-Arithmetik, das heißt, die Fähigkeit, Zieladresse ein Zeiger mit arithmetischen Operationen zu ändern, wird durch den Sprachstandard beschränkt, innerhalb der Grenzen eines einzelnen Array-Objekt bleiben und sonst nicht definiertes Verhalten aufzurufen. Addieren oder Subtrahieren von einem Zeiger bewegt sich durch ein Vielfaches der Größe des Datentyps er zeigt. Beispielsweise Addieren von 1 zu einem Zeiger auf 4-Byte-Ganzzahlwerte werden den Zeiger um 4. Dies hat den Effekt des Erhöhens der Zeiger auf das nächste Element in einer zusammenhängenden Matrix von ganzen Zahlen, die oft das beabsichtigte Ergebnis weisen inkrementieren. Zeigerarithmetik kann nicht auf Hinweise durchgeführt, da der Hohlraumtyp hat keine Größe, und kann somit das spitze-Adresse hinzugefügt werden, um, obwohl gcc und andere Compiler-Byte-Arithmetik auf eine Nicht-Standard-Erweiterung durchzuführen. Für "direkt" Arbeiten mit Byte sie in der Regel gegossen Zeiger auf, oder wenn nicht in der Standard-Bibliothek definiert verwendet.
Zeigerarithmetik bietet dem Programmierer eine einzige Art und Weise des Umgangs mit verschiedenen Arten: Addieren und Subtrahieren der Anzahl von Elementen anstelle der tatsächlichen Offset in Bytes erforderlich. Insbesondere explizit erklärt der C Definition, dass die Syntax, die der -ten Element der Anordnung ist, entspricht, das den Inhalt des Elements gerichtet ist. Dies impliziert, dass entspricht, und man kann schreiben, beispielsweise oder genauso gut auf das vierte Element eines Arrays zuzugreifen.
Während mächtig, kann Zeigerarithmetik eine Quelle der Computer Bugs. Es neigt dazu, Programmieranfänger zu verwirren, in verschiedenen Kontexten zwingt sie: ein Ausdruck kann eine gewöhnliche arithmetische eine oder eine Zeigerarithmetik sein, und manchmal ist es einfach, eine für den anderen zu verwechseln. Als Reaktion darauf haben viele moderne High-Level-Programmiersprachen nicht erlauben den direkten Zugriff auf Speicher mit Adressen. Außerdem befasst sich die sichere C-Dialekt Cyclone viele der Probleme mit Zeigern. Siehe Programmiersprache C für weitere Diskussion.
Der Zeiger, oder wird in ANSI C und C ++ als Oberzeigertyp unterstützt. Ein Zeiger auf eine Adresse, um alle nicht-Funktion Datentyp zu speichern, und in C, implizit zu einem anderen Zeigertyp im Auftrag umgewandelt, aber es muss explizit gegossen werden, wenn Inline dereferenziert. K & amp; RC verwendet für die "Art-agnostische Zeiger" Zweck.
C ++ erlaubt nicht die implizite Konvertierung von den anderen Zeigertypen, auch in Zuweisungen. Dies war eine Design-Entscheidung zu nachlässig und sogar ungewollte Würfe zu vermeiden, obwohl die meisten Compiler nur dann ausgegeben, Warnungen, keine Fehler, bei der Begegnung mit anderen kranken Würfe.
In C ++ gibt es keine zu ergänzen, weil Referenzen verhalten sich wie Aliasnamen auf die Variablen auf die sie verweisen, und es kann nie eine Variable, deren Typ zu sein.
C #
In der Programmiersprache C # werden Zeiger nur unter bestimmten Bedingungen unterstützt: Jeder Codeblock einschließlich Zeigern muss mit dem Schlüsselwort gekennzeichnet werden. Solche Blöcke erfordern in der Regel höhere Sicherheitsberechtigungen als zeiger Code zu dürfen ausgeführt werden. Die Syntax ist im wesentlichen die gleiche wie in C ++, und die Adresse kann entweder spitz verwaltet werden oder verwalteten Speicher. Allerdings müssen Zeiger auf verwalteten Speicher unter dem Stichwort, das der Garbage Collector von Bewegen des spitzen Gegenstand als Teil der Speicherverwaltung während sich der Mauszeiger in Umfang, wodurch der Zeigeradresse gültig verhindert deklariert werden.
Eine Ausnahme ist von der Nutzung der Struktur, die eine sichere Managed gleichwertig ist, und keine unsicheren Code erforderlich. Diese Art wird häufig bei der Verwendung von Methoden aus der zum Beispiel zurückgegeben:
The.NET Framework enthält viele Klassen und Methoden in den Namespaces und Typen, die nach und von vielen nicht verwalteten Typen und Zeigern convert.NET um die Kommunikation mit nicht verwaltetem Code ermöglichen.
COBOL
Die Programmiersprache COBOL unterstützt Zeiger auf Variablen. Primitiven oder einer Gruppe von Datenobjekten innerhalb des eines Programms deklariert sind inhärent zeigerbasierte, wobei der Festwertspeicher in dem Programm zugewiesenen Platz für die Adresse des Datenelements. Im Programm-Quellcode, werden diese Datenelemente wie jede andere Variable verwendet, aber ihre Inhalte werden implizit indirekt durch ihre Zeiger abgerufen.
Speicherplatz für jedes darauf hingewiesen zu Datenobjekt wird in der Regel zugeordnet dynamisch mit externen Abschluss oder über Embedded erweiterten Sprachkonstrukte wie oder Aussagen.
Erweiterte Versionen von COBOL bieten auch Zeigervariablen mit Klauseln erklärt. Die Werte dieser Zeigervariablen festgelegt und geändert mit und Aussagen.
Einige erweiterte Versionen von COBOL bieten auch Variablen, die zum Speichern der Adressen von ausführbaren Code sind.
PL / I
Die PL / I-Sprache bietet volle Unterstützung für Zeiger auf alle Datentypen, Rekursion, Multitasking, String-Handling und umfangreiche integrierte Funktionen. PL / I war ein Sprung nach vorn im Vergleich zu den Programmiersprachen seiner Zeit.
D
Die Programmiersprache D ist ein Derivat von C und C ++, die vollständig unterstützt C Zeiger und C Typumwandlung.
Eiffel
Der Eiffelobjektorientierte Sprache unterstützt Zeiger in Form von Referenzen, die eingegeben werden und nicht jede Form der Zeigerarithmetik zu ermöglichen. Die ECMA-Standard für Eiffel enthält einen "angebracht Typ" Mechanismus, der Leere Sicherheitsgewährleistungsansprüche.
Fortran
Fortran-90 eingeführt, eine stark typisierte Zeiger-Fähigkeit. Fortran Zeiger enthalten mehr als nur eine einfache Speicheradresse. Sie kapseln auch die untere und obere Grenze des Array-Dimensionen, Fortschritte, und andere Metadaten. Ein Verband Betreiber, wird verwendet, um eine auf eine Variable, die ein Attribut zuzuordnen. Die Fortran-90-Anweisung kann auch verwendet werden, um einen Zeiger auf einen Speicherblock zuzuordnen. Zum Beispiel könnte der folgende Code verwendet werden, um zu definieren, und erstellen Sie eine verknüpfte Listenstruktur werden:
Fortran-2003 fügt Unterstützung für Prozedurzeiger. Auch als Teil des C Interoperabilität Funktion, Fortran-2003 unterstützt intrinsischen Funktionen zur Umwandlung von C-Stil-Zeiger in Fortran-Pointer und zurück.
Gehen
Go hat Zeigern. Seine Deklarationssyntax ist äquivalent zu der von C, aber andersherum geschrieben, endend mit dem Art. Im Gegensatz zu C, hat Go Müllabfuhr, und verbietet Zeigerarithmetik. Referenztypen, wie in C ++, gibt es nicht. Einige eingebauten Typen wie Karten und Kanäle, sind eingerahmt und werden mit Hilfe der Funktion initialisiert. Als ein anderer Ansatz zur einheitlichen Syntax zwischen Zeigern und Nicht-Zeigern, hat der Pfeil Betreiber fallen gelassen wurde es möglich ist, den Punktoperator direkt auf einen Zeiger zu verwenden, um einen Datentyp, ein Feld oder eine Methode des dereferenzierte Wert zugreifen, als ob die Punkt-Operator wurden von der zugrunde liegenden Datentyp verwendet. Dies ist jedoch nur mit 1 Zwischenstufe.
Java
Im Gegensatz zu C, C ++ oder Pascal, gibt es keine explizite Darstellung von Zeigern in Java. Stattdessen werden immer komplexer Datenstrukturen wie Objekte und Arrays mit Referenzen implementiert. Die Sprache bietet keine explizite Zeigermanipulation Betreiber. Es ist immer noch möglich, dass Code, um zu dereferenzieren ein NULL-Verweis versuchen jedoch, die in einer Laufzeitausnahme geworfen führt. Der Raum, der von nicht referenzierten Speicherobjekte besetzt wird automatisch von der Garbage Collection zur Laufzeit wiedergewonnen.
Modula-2
Zeiger sind sehr viel wie in Pascal implementiert, ebenso wie Parameter im Prozeduraufrufe. Modula-2 ist noch stark typisierte als Pascal, mit weniger Möglichkeiten, um das Typsystem zu entkommen. Einige der Varianten von Modula-2 gehören Müllabfuhr.
Oberon
Viel wie mit Modula-2, sind Zeiger zur Verfügung. Es gibt immer noch weniger Möglichkeiten, um das Typsystem zu umgehen und so Oberon und seine Varianten sind noch sicherer in Bezug auf Zeigern als Modula-2 oder dessen Varianten. Wie bei Modula-3, ist die Garbage Collection ein Teil der Sprachspezifikation.
Pascal
Im Gegensatz zu vielen Sprachen, die Zeiger verfügen, ermöglicht Norm ISO Pascal nur Zeiger auf dynamisch erstellten Variablen, die anonym sind und erlaubt ihnen nicht zu statisch oder lokale Variablen Referenz Referenz. Es muss nicht Zeigerarithmetik. Pointers muss auch eine zugeordnete Art und ein Zeiger auf einen Typ ist nicht mit einem Zeiger auf einen anderen Typ kompatibel. Dies hilft, die Art inhärenten Sicherheitsprobleme mit anderen Zeiger Implementierungen, insbesondere solche für PL / I oder C verwendet beseitigen Es beseitigt auch einige Risiken durch baumelt Zeiger verursacht, sondern die Fähigkeit, dynamisch loslassen referenzierten Speicherplatz mit Hilfe der Standard-Verfahren bedeutet, dass das Risiko der dangling Zeiger nicht gänzlich eliminiert.
Doch in einigen kommerziellen und Open-Source-Pascal-Compiler-Implementierungen wie Free Pascal, Turbo Pascal oder der Object Pascal in Embarcadero Delphi ein Zeiger darf standard statischen oder lokalen Variablen referenzieren und kann von einem Zeigertyp in einen anderen umgewandelt wird. Überdies Zeigerarithmetik nicht beschränkt ist: Addieren oder Subtrahieren von einem Zeiger bewegt sich durch diese Anzahl von Bytes in jeder Richtung, aber unter Verwendung der Standardverfahren oder mit ihm bewegt sich der Zeiger durch die Größe des Datentyps erklärt wird, zu zeigen. Eine nicht typisierte Pointer ist auch unter dem Namen, der mit anderen Zeigertypen kompatibel ist vorgesehen.
Perl
Die Programmiersprache Perl unterstützt Zeiger, wenn auch nur selten verwendet, in der Form der Packung und entpacken Funktionen. Diese werden nur für einfache Interaktionen mit kompiliert OS-Bibliotheken gedacht. In allen anderen Fällen, verwendet Perl Referenzen, die eingegeben werden und nicht jede Form der Zeigerarithmetik zu ermöglichen. Sie werden verwendet, um komplexe Datenstrukturen aufzubauen.
Kommentare - 0