Hallo und willkommen zurück. In dieser Vorlesung möchte ich über Punktarithmetik sprechen.
Nachdem wir die Beziehung zwischen Arrays und Zeigern verstanden
haben, wird dieses Konzept leichter zu verstehen sein.
Wir sagen Arithmetik, aber wir tun es nicht wirklich
- alles, was es wirklich bedeutet, ist, dass Sie
entweder Plus oder Minus oder Inkrementieren oder Dekrementieren für einen Zeiger selbst ausführen können.
Die wahre Kraft der Verwendung von Zeigern auf Arrays kommt also ins Spiel, wenn
Sie die Elemente eines Arrays sequenzieren möchten.
Sie möchten vom ersten Element zum Ende gehen, Sie möchten sie durchlaufen.
Dies sind die wirklichen Leistungszeiger. Da Zeiger auf Adressen
verweisen, ist jedes Element im Array nur eine andere Adresse.
Sie können also einfach Plus Plus für Zeiger tun und zur nächsten Adresse gehen.
Hier kann also der Wertezeiger verwendet werden, um auf die erste
Ganzzahl des Wertearrays zuzugreifen.
Es kann verwendet werden, um auf Werte unter 0 zuzugreifen.
Wenn Sie sich also an Werte erinnern, ist der Zeiger ein Zeiger,
der auf ein ganzzahliges Array zeigt.
Und wir haben es dem ersten Element im Array zugewiesen, indem wir einfach den Zeiger auf den Arraynamen zugewiesen haben.
Wir könnten auch die Adresse des Operators unter 0 verwenden, wenn wir wollten.
Wenn wir jedoch den Zeiger auf Werte
dereferenzieren, weil er auf das erste Element im Array
zeigt, erhalten Sie die erste Ganzzahl im Array mit dem Wert unter 0.
Wenn Sie den Wert sub 3
über die Zeigervariable referenzieren möchten, müssen Sie nur 3 zum Wertezeiger hinzufügen und dann
den Indirektionsoperator anwenden, um ihn zu dereferenzieren.
Sie könnten also einfach so etwas tun. Sie können Wertezeiger plus 3 sagen und ihn
dann mit dem Sternchen dereferenzieren.
Und normalerweise setzen Sie das Sternchen außerhalb von Anführungszeichen, um es klar zu machen.
Dies bedeutet jedoch, dass der Wertezeiger eine
Adresse des ersten Elements im Array ist und 3 hinzugefügt wird.
Und so wird es tatsächlich für jedes Byte für ganze Zahlen addieren, es
wird die Bytes mit den ganzen Zahlen multiplizieren.
Dies wird jedoch im Wesentlichen auf das Sub 3,
das 4. Element im Array, verweisen.
Also im Ausdruck Sternchen Werte Zeiger plus i, der verwendet
werden kann, um auf jeden Wert zuzugreifen, der in einem Wertearray enthalten ist.
Wenn Sie diesen Ausdruck verstehen, können Sie i etwas hinzufügen, und
es verweist Sie auf ein bestimmtes Elementarray.
Wenn Sie also den Wert unter 10 auf 27 setzen
möchten, müssen Sie nur, wenn Sie einen Zeiger
verwenden, den Wertezeiger plus 10 sagen und ihn dann dereferenzieren und gleich 27 sagen.
Sie sehen hier also die unterschiedliche Syntax.
Auch hier ist es eine einfache Bequemlichkeit, aber es ist auch effizienter in Bezug auf das Programm selbst.
Da Zeiger also so eng mit Arrays verwandt sind, können
Sie leicht auf Elemente zugreifen, indem Sie nur dekrementierende Zeiger inkrementieren
oder Werte hinzufügen oder Werte von einem Zeiger subtrahieren.
Sehr, sehr nützlich.
Um den Wertezeiger so einzustellen, dass er auf das zweite Element des Wertearrays
zeigt, können Sie den Adressoperator auf den Wert unter 1 anwenden und die Ergebnisse dem Wertezeiger zuweisen.
Wir haben das gesehen. Dies ist nur eine andere Möglichkeit, dasselbe zu tun,
was ich zuvor erwähnt habe, wenn Sie den Adress-Suboperator verwenden möchten.
Sie können dies immer tun,
wenn Sie möchten, aber es ist viel bequemer, Zeigerarithmetik durchzuführen.
Wenn der Wertezeiger auf den Wert unter 0
zeigt, können Sie den Wertpunkt eins festlegen, indem Sie einfach einen
Wert zum Wertezeiger hinzufügen. Und genau das erreichen wir mit Punktarithmetik.
Alles, was Sie tun müssen, ist zu sagen, dass Wertepunkt oder
Plus gleich Eins sind, und jetzt zeigt der Wertezeiger auf das zweite Element im Array
oder den ersten Index.
Sehr, sehr schöne Notation, sehr einfach zu machen.
Dies ist also ein vollkommen gültiger Ausdruck in c und kann
für Zeiger auf einen beliebigen Datentyp verwendet werden, unabhängig davon, ob es sich um
ein ganzzahliges Zeichen oder etwas anderes handelt. Und Sie sollten wahrscheinlich darüber nachdenken, wie nützlich dies in Charakteren sein kann.
Wenn Sie einen Zeichenzeiger haben, können Sie jetzt auf jedes Element,
jedes Zeichen in einer Zeichenfolge zugreifen, indem Sie einfach ein Plus-Plus für einen Zeiger ausführen.
Die Inkrement- und Dekrementoperatoren plus plus und minus minus sind
besonders nützlich, wenn Sie mit diesen Zeigern arbeiten,
da Sie normalerweise von einem Element zum nächsten wechseln möchten und so weiter.
Es ist nicht so üblich, 22 oder minus 20 zu
addieren, da Sie normalerweise nacheinander arbeiten.
Die Verwendung des Inkrementoperators in einem Zeiger hat also den gleichen Effekt wie das Hinzufügen eines Zeigers zum Zeiger.
Die Verwendung des Dekrementierungsoperators hat den gleichen Effekt wie das Subtrahieren eines vom Zeiger.
Wenn Sie also den Plus-Plus-Wertezeiger sagen,
wird der Wertezeiger auf die nächste Ganzzahl im Wertearray gesetzt.
Minus minus sollte Wertezeiger sein. Wird den
Wertezeiger setzen, der auf die vorherige Ganzzahl im Wertearray zeigt.
Sie sollten jedoch vorsichtig sein, wenn Sie das Minus-Minus ausführen,
da Sie sicherstellen möchten, dass Sie sich mindestens im Array befinden und nicht bei 0 sind.
Und das Gleiche gilt für Plus Plus.
Wenn Sie sich am Ende des Arrays befinden, möchten Sie keine Fehler außerhalb der Grenzen haben.
Stellen Sie also sicher, dass der Wertezeiger, wenn Sie
ihn dekrementieren, anfangs nicht auf den Anfang des Wertearrays zeigte.
Ein weiteres Beispiel
hier, in dem wir tatsächlich alle Elemente im
Array summieren, sehen Sie, dass wir eine
Array-Summenfunktion haben und die Funktion ein
Array und eine konstante Ganzzahl als Parameter verwendet.
Innerhalb der Funktion erstellen wir eine Ganzzahl.
Wir werden diese ganzzahlige Summe auf 0 initialisieren und einen ganzzahligen Zeiger erstellen, einen
Zeiger auf den Typ int.
Wir werden auch einen Zeiger erstellen,
der konstant ist.
Das bedeutet also, dass Sie die Adresse nicht ändern können.
Es wird immer Array plus n sein und es wird Array-Ende genannt.
Wir tun dies, weil es unsere Schleife effizienter macht, wenn wir sie so
einrichten, dass sie zum Array-Ende führt und nur auf den Zeiger schaut.
Das Array-Ende zeigt also auf die Adresse des Array-Endes.
Wir können Array sagen, was übergeben wird, und dann ist n die
Größe, die
Größe des Arrays.
Jetzt initialisiert die for-Schleife den Zeiger der Schleifensteuervariablen, der ein
Zeiger auf das Array ist. Und alles, was Sie tun
müssen, ist, wenn Sie dem ersten Element eines Arrays einen Zeiger zuweisen möchten, müssen Sie nur
sagen, dass der Zeiger gleich dem Array ist.
Und dann ist unsere Schleifenausgangsbedingung, wenn der Zeiger kleiner als das Arrayende ist.
Denken Sie daran, ein Zeiger ist eine Adresse und das Array-Ende ist auch eine Adresse.
Wir sagen also, wenn die Adresse am Zeiger kleiner als der Zeiger n ist,
dann wollen wir den Hauptteil der Schleife ausführen.
Der Zeiger ist nur eine ganze Zahl, es ist eine hexadezimale Adresse.
Jedes Mal, wenn wir inkrementieren, geht es zur nächsten Adresse. Wir haben die Endadresse, also können wir
sagen, gehen Sie durch die Schleife, bis wir das Ende erreichen.
Und dann erhöhen wir den Zeiger selbst, wodurch die
Adresse erhöht wird, um zum nächsten Element im Array zu gelangen, im
Wesentlichen, weil wir darauf zeigen.
Dann haben wir im Körper unserer Schleife, wir sagen Summe plus gleich Zeiger.
Wir dereferenzieren den Zeiger, um den Wert zu erhalten,
weil wir uns daran erinnern, dass wir den Wert erhalten möchten, für den wir nicht die
Adresse des Zeigers erhalten möchten oder auf die die Adresse des Zeigers zeigt.
Und ganz am Ende geben wir die Summe zurück. Dies wird also alle
Elemente in einem Array summieren.
Sie werden im Wesentlichen feststellen, dass wir dort auch eine Deklaration der Funktion im
Gegensatz zum Anfang der Datei vorgenommen haben. Normalerweise füge ich sie gerne oben in die Datei ein.
Aber im Wesentlichen erstellen wir ein Array von 10 Elementen, 3 7 negativen 9 und so weiter.
Wir übergeben dann das Array oder eine Summe und geben
die Größe als 10 an.
Und was Sie bemerken werden, ist, dass es den Wert zurückgibt, der die Summe des Arrays ist.
Es ist also sehr, sehr schön, diese Punktarithmetik zu verwenden, um durch ein Array
zu iterieren. Wir
können einfach zur nächsten Adresse plus und auch zur Endadresse schauen, um herauszuspringen.
Dies ist effizienter, wenn der Zeiger auf die Endadresse schaut, im
Gegensatz zu einem Zähler, der weniger als n sieht.
Und Sie bemerken auch, dass wir sie als Konstanten erstellt haben, weil sich die Konstanten
nicht ändern und dies mit dem Compiler effizienter ist.
Das Array hier ist ein konstanter Zeiger, was bedeutet, dass sich die Adresse nicht ändern kann.
In diesem Beispiel sollten Sie auch
bemerkt haben, dass Sie zum Übergeben eines Arrays an eine Funktion einfach den Namen des Arrays angeben.
Wir wissen also, wie man die Funktion erhöht. Um einen Zeiger auf ein Array zu erstellen,
müssen Sie nur den Namen des Arrays angeben.
Wir haben das gesehen, als wir das erste Element des Arrays einem Zeiger zugewiesen haben.
Dies impliziert also, dass der Aufruf ihrer Array-Summenfunktion,
der an die Funktion übergeben wurde, tatsächlich ein Zeiger auf die Array-Werte war.
Und das sagt Ihnen wirklich, dass Arrays und Zeiger sehr, sehr eng miteinander verbunden sind, dass
ein Array nichts anderes als ein Zeiger ist.
Dies erklärt, warum Sie die Elemente eines Arrays innerhalb einer Funktion ändern können.
Denn bis zu diesem Zeitpunkt, wenn Sie Daten an eine Funktion übergeben, werden diese Daten
außerhalb dieser Funktion nur geändert, wenn es sich um einen Zeiger handelt.
Weil wir deshalb die Adresse für den Scanf übergeben müssen.
Die einzige Möglichkeit, Elemente außerhalb einer Funktion zu ändern, besteht darin,
Zeiger auf eine Funktion zu übergeben.
Und da die Elemente innerhalb dieser Funktion geändert werden, bedeutet
dies, dass Sie einen Zeiger übergeben.
Und dies ist nur ein weiterer Beweis
dafür, dass Arrays und Zeiger sehr, sehr ähnlich sind, da Arrays tatsächlich Zeiger sind, die nur
eine andere Syntax verwenden.
Wir werden darüber sprechen, wie wir als Referenz oder wirklich als
Kopie einer Referenz übergeben können, um
Daten in einer Funktion außerhalb dieser Funktion zu ändern.
Wenn Sie sich an eine unserer vorherigen Herausforderungen
erinnern, mussten wir immer dann, wenn wir Daten in einer Funktion ändern
wollten, eine globale Variable verwenden.
Weil wir das Konzept der Referenzübergabe nicht
verstanden haben und das Konzept der Zeiger nicht verstanden haben.
Aber ich habe bereits erwähnt, dass einer der Vorteile von Zeigern
darin besteht, dass Sie jetzt Daten innerhalb einer Funktion ändern können und diese außerhalb dieser Funktion wiedergegeben werden.
Aber das ist ein anderer Vortrag.
Dieses Konzept an sich zeigt jedoch aufgrund des vorherigen Beispiels, wie
Arrays im Wesentlichen Zeiger sind.
Sie fragen sich vielleicht, warum der formale Parameter in der Funktion nicht als Zeiger deklariert ist.
Nun, es könnte sein. Wir könnten einfach so etwas machen, int array sum, int star array.
Wir müssen das nicht als Array deklarieren.
Es ist vollkommen gültig, da Arrays und Zeiger dieselben sind, die wir als int star array bezeichnen können.
Wir haben erwähnt, dass sie wirklich eng miteinander verwandt sind.
Sie können also einen Array-Typ als einen Typ von
Ints-Array innerhalb der Array-Summenfunktion deklarieren oder ihn als Zeiger auf int deklarieren.
Aus diesem Grund sehen Sie viele Funktionen, die Arrays als Parameter oder als Argumente
akzeptieren, bei denen die Parameter tatsächlich Zeiger sind.
Wenn Sie also Indexnummern verwenden, um auf die Elemente eines Arrays zu verweisen, das an eine
Funktion übergeben wird, deklarieren Sie den Parameter als Array.
Auch hier ist die Notation bequem, es ist nur eine andere Art
der Notation, entweder unter Verwendung der Klammern und des Index oder unter Verwendung eines Zeigers.
Das Array selbst ist in Bezug auf die Wartung
des Programms normalerweise leichter zu lesen. Es spiegelt die Verwendung des Arrays durch die Funktion besser wider.
Der Zeiger ist jedoch einfacher zu bedienen.
Wenn Sie ein Argument als Zeiger auf das Array verwenden, deklarieren Sie es im formalen
Parameter als Zeiger vom Typ.
Hier ist ein Beispiel mit der Zeigernotation der Funktion, bei
der im vorherigen Beispiel eine Array-Notation verwendet wurde.
Hier sagen wir einfach int start
array und Sie werden feststellen, dass die Funktion sofort viel
kleiner wird, da wir den Zeiger auf das Array nicht wie wir dem
ersten Element zuweisen müssen.
Die Schleife wird auch viel kleiner, weil wir diese Zuweisung
in der ersten Anweisung nicht vornehmen müssen.
Wir können nur sagen, bis das Array kleiner als das Array-Ende ist, und wir
können das Array inkrementieren. Es ist also etwas weniger Code,
es ist immer noch sehr klar, was hoffentlich los ist, wenn Sie Arrays und Zeiger verstehen.
Wir übergeben ein Int-Star-Array und müssen
dieses Array nicht mehr initialisieren, da wir es im Zeiger
übergeben. Wir initialisieren den Zeiger nicht mehr.
Und dann setzen wir tatsächlich die Adresse des Endes des
Arrays auf einen konstanten
Zeiger, das Arrayende. Wir verwenden dies, um
aus der Schleife zu springen, und wir sagen einfach, dass Summe plus
gleich Sternarray ist, wobei wir den Indirektionsoperator verwenden, um das Array erneut zu dereferenzieren und die Summe zurückzugeben.
Und dann ist die Hauptfunktion genau dieselbe, außer dass die Deklaration jetzt ein Zeiger im Gegensatz zu einem Array ist.
Hier sind zwei Beispiele, die unterschiedliche Notationen verwenden, aber dieselbe Funktionalität
bieten. Deshalb sehen Sie viele Zeiger als Parameter
innerhalb eines Funktionsparameters.
Zusammenfassend sind hier einige Dinge, die gültig sind, wenn Sie Zeiger verwenden,
und Dinge, die nicht gültig sind.
Wenn wir hier also einige Variablen deklarieren, deklarieren wir ein Array namens Earn,
das 3 Elemente enthält, und deklarieren dann 2 Zeiger.
Mit diesen Zeigern können wir nun rechnen. Wir können Zeiger eins plus plus sagen.
Wir können sagen, Punkt oder 2 ist gleich Punkt oder eins plus 2.
Wir können sogar sagen, dass Zeiger 2 gleich Verdienst plus eins ist.
Dies ist absolut gültig, da Sie Zeiger haben und die Zeiger anhand der Adresse
ändern, sodass Sie Punktarithmetik ausführen können.
Sie können keine Punktarithmetik für Arrays ausführen. Sie können also nicht Earn Plus Plus sagen.
Sie können nicht Zeiger 2 0 sagen. 2 plus 0. 1,
weil das Adressen sind.
Und Sie zeigen tatsächlich nicht auf
etwas innerhalb eines Arrays.
Und Sie können nicht mal Punkt oder eins verdienen, um Punkt oder 2 zu bekommen.
Diese sind ungültig.
Achten Sie daher auf die korrekte Syntax für die Zeigerarithmetik und
verstehen Sie auch, dass die Punktarithmetik nur auf Zeiger und nicht auf Arrays angewendet
werden kann.
Auch Funktionen, die Arrays verarbeiten, verwenden Zeiger als Argumente.
Sie haben die Wahl zwischen Array-Notation und Zeiger-Notation zum
Schreiben von Array-Verarbeitungsfunktionen.
Wenn Sie also die Zufallsfunktion verarbeiten möchten, ist es vollkommen in Ordnung, einen Zeiger als Parameter zu verwenden.
Sie können auswählen, welche Sie verwenden möchten.
Die Verwendung von Zeigern ist jedoch normalerweise weniger Code und effizienter.
Durch die Verwendung der Array-Notation wird deutlicher, dass die Funktion mit
Arrays arbeitet, und die Array-Notation sieht für Programmierer mit
Programmierhintergrund in bestimmten Sprachen vertrauter aus.
Wenn Sie also vorher und Fortran und Pascal usw. programmieren,
können Sie die Pfeilnotation verwenden.
Andere Programmierer sind möglicherweise eher daran gewöhnt, mit Zeigern zu arbeiten, und finden
die Zeigernotation möglicherweise natürlicher, was nur sinnvoller ist.
Es ist näher an der Maschinensprache, wenn die Punktarithmetik
und die Zeigernotation bei einigen Compilern verwendet werden. Dies führt zu effizienterem Code, ein weiterer
Grund, ihn zu verwenden.
Schauen wir uns diese Beispiele in Codeblöcken
an.
Hier ist unser Beispiel von den Folien. Wir haben unsere Funktionsdeklaration in Zeile 3.
Es ist eine Array-Summe.
In diesem Beispiel verwenden wir die Array-Notation.
Wir werden also die Klammern verwenden, wenn wir Indizes verwenden.
Und wir werden es als Übergabe
im Werte-Array und Übergabe in der Größe bezeichnen.
Die Array-Summenfunktion verwendet also ein ganzzahliges Array. Nun, als erstes müssen Sie den
Zeiger erstellen, den Sie für die Punktarithmetik in Zeile
14 verwenden möchten. Und dann müssen Sie das
Ende des Arrays dem Adressarray plus der Größe zuweisen.
Das ist das Ende des Arrays, mit dem Sie jetzt die Schleife verlassen können.
Aber wir müssen den Zeiger dem Array zuweisen.
Wir wissen, dass wir Zeigern Arrays zuweisen können, um auf
das erste Element zu verweisen, indem wir nur den Namen des Arrays verwenden.
Wir müssen nicht die Adresse des Mitarbeiters verwenden.
Wir könnten, wenn wir wollten, tatsächlich so etwas tun.
Und das ist auch gut so.
Und dann plus wir plus den Zeiger. Wir erhöhen den Zeiger, weil alles, was
wir tun, auf die nächste Adresse erhöht wird. Es zeigt auf das nächste Element im Array.
Und dann dereferenzieren wir in Zeile 18 den Zeiger, um die Summe zu berechnen, die Summe
ist gleich, die Summe plus den Wert des Zeigers, auf den er zeigt.
Wenn wir dies erstellen, haben wir eine Warnung, die main ist
kein int. Wir möchten dies ändern, da es
gut ist, Fehlerwerte von main zurückzugeben und einfach
return 0 zu sagen.
Sie könnten zurückkehren, wenn es einen Fehler in main
gab, Sie würden einen negativen zurückgeben. Wenn wir dies ausführen, werden Sie sehen, dass es nur die Summe
der Werte im Array ausführt, nämlich 3 plus 7 plus negative 9 usw., nicht einmal sicher, was
das ist, aber es sieht so aus, als wäre es 21.
Jetzt können wir diesen Array-Parameter einfach so ändern, dass er
einen Zeiger enthält, indem wir nur das Sternchen vor dem Zeiger deklarieren.
Wir nennen es genauso. Wir ändern nur. Wir müssen den Zeiger
nicht mehr deklarieren. Wir möchten wahrscheinlich den Namen
ändern, um es einfacher zu machen, aber wir müssen diesen Zeiger nicht mehr deklarieren.
Wir wollen immer noch das Ende des Arrays erreichen
und müssen es auch nicht mehr zuweisen.
Wir können dort einfach ein leeres Ding haben. Und es könnte tatsächlich nützlicher sein, hier eine while-Schleife zu haben.
Wenn wir jedoch keine Zuordnung haben, können wir das Semikolon einfach dort einfügen.
Und jetzt sind wir gut. Wir möchten es immer noch de-referenzieren und wir wollen es immer noch zurückgeben.
Wenn wir
dies jedoch erstellen, möchten wir
sicherstellen, dass wir die Funktionsdeklaration als Zeiger definieren, da wir sie geändert haben.
Und dies kann ein beliebiger Name sein, aber wir werden nur konsistent sein.
Jetzt wollen wir
sicherstellen, dass wir wieder alle Variablen verwenden,
die wir geändert haben.
Jetzt, da wir erfolgreich gebaut haben, führen wir es aus und Sie sehen,
dass Sie das gleiche Ergebnis erhalten, nämlich 21.
Wenn Sie diesen Unterschied zwischen der Verwendung von Zeigern als formale Parameter in
Arrays
verstehen, können Sie sie austauschbar verwenden. Es ist nur eine Annehmlichkeit für die Notation.
Aber Sie haben normalerweise weniger Code, wenn Sie einen Zeiger verwenden.
Und Sie können es mehr manipulieren und Sie können leistungsfähigere Dinge tun, es
ist normalerweise auch effizienter, basierend auf dem Compiler. Vielen Dank.