Markus: aber wieso kommen in Deinem Code 7 und 13 anstatt 6 und 11 als Arrayinhalte?
1+5=6
6+5=11
Du bist in Begriff, Forum64 zu verlassen, um auf die folgende Adresse weitergeleitet zu werden:
Bitte beachte, dass wir für den Inhalt der Zielseite nicht verantwortlich sind und unsere Datenschutzbestimmungen dort keine Anwendung finden.
letzter Beitrag von MOS am
Markus: aber wieso kommen in Deinem Code 7 und 13 anstatt 6 und 11 als Arrayinhalte?
1+5=6
6+5=11
Das ist unser Array:
1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 |
Es wird Zeile 0, Spalte 0 ausgegeben, dann Zeile 1 Spalte 1, dann Zeile 2 Spalte 2.
Ich habe in der printf-Anweisung nämlich nicht das 0. Element der Zeile, auf der pmatrix zeigt, ausgegeben, sondern das i-te (i=0, ..., 2).Und pmatrix zeigt auch auf die i-te Zeile.
Dein erwartetes Ergebnis bekommst Du mit
an Stelle der printf-Anweisung.
Ich scanne Dir mal die Erklärung ein, wie man "komplexe Vereinbarungen" liest.
Falls Du es noch nicht gesehen hast: Der Scan ist als PM an Dich. Taucht oben unter Konversationen auf.
Mal so eine Frage zu Pointer in C, wozu braucht man die denn eigentlich genau und geht es auch nicht ohne? Ich hab' das mit den Pointern nie so ganz gerafft. Ich glaube wenn man an einer Stelle ein Pointer definiert, konnte man an einer anderen Stelle per Referenz auf die Variable zugreifen, wo ist denn da der Sinn von den Pointern? Hab' jetzt auch nie wirklich mit C gearbeitet, eigentlich ausschließlich mit Basic, Assembler und Verilog.
Wenn du z.B. an irgendner Stelle n Struct voller Arrays und ähnlichen Kram hast und den von einer Funktion manipulieren lassen willst, musst du bei call by value erst den ganzen Rotz in den Structklon der Funktion kopieren und dann auch wieder zum Ursprungstruct zurück. Stattdessen einfach nur einen paar Byte grossen Zeiger auf den Struct zu übergeben spart dann ne Menge Zeit und Speicher.
Die benötigte CPU Zeit und der Speicher der heutigen Software spielt doch eh' nur noch eine nebensächliche Rolle, ich denke nicht dass ich in absehbarer Zeit C benötige, bisher ging auch alles ohne.
Mal so eine Frage zu Pointer in C, wozu braucht man die denn eigentlich genau und geht es auch nicht ohne?
Nein, es geht nicht ohne. Ein Pointer ist nichts weiter als eine Variable, die eine Speicheradresse enthält. Wenn man in Basic
schreibt, ist das das Basic-Äquivalent dazu - mit dem entscheidenden Unterschied, dass in C auch noch definiert ist, auf welchen Datentypen der Pointer zeigt. In objektorientierten Sprachen sind es dann die Objektreferenzen, die unter der Haube wiederum nichts anderes sind als Pointer. Sobald man das dahinterliegende Konzept kapiert hat, findet man die Pointer auch in nahezu allen anderen Sprachen wieder, nur heißen sie da nicht so bzw. werden vor dem Benutzer versteckt.
Hab' jetzt auch nie wirklich mit C gearbeitet, eigentlich ausschließlich mit Basic, Assembler und Verilog.
Wenn man in 6502-Assembler eine indirekte Adressierungsart verwendet, ist die angegebene Adresse auch nichts anderes als ein Pointer.
Die benötigte CPU Zeit und der Speicher der heutigen Software spielt doch eh' nur noch eine nebensächliche Rolle
Wenn Betriebssystem und Anwendungen jede Struktur per call-by-value übergeben würden, hättest Du den Satz da gar nicht schreiben können.
In Sachen C hab' ich halt nicht so die Erfahrung und C++ macht einen auch total wirr mit den ganzen Klassen, Konstruktoren, Vererbungen etc. und was es da sonst noch so alles gibt. Ein Zeiger, der auf einen Zeiger zeigt, klingt auch seltsam. Und wenn ich Strukturen manipulieren würde, dann am liebsten Global, spart bestimmt auch Ausführungszeit
Und wenn ich Strukturen manipulieren würde, dann am liebsten Global, spart bestimmt auch Ausführungszeit
Und erst die Ersparnis beim Debuggen
Ein Zeiger, der auf einen Zeiger zeigt, klingt auch seltsam.
Warum?
(ja, das ist ein fieses Beispiel)
Einfache Zeiger habe ich ja noch verstanden als N00bie damals, aber diese Zeiger-auf-Zeiger-auf-Zeiger etc. Beispiele zeigen doch, dass sauberes Programmieren für Anfänger besser mit anderen Sprachen zu lernen ist.
Das geht auch mit Klassen und Vererbung ohne diese Selbstkasteiung mit Pointern und Semikolon Dogmatik.
Aber mir ist schon klar, man möchte sich halt abheben vom Pöbel...
Aber mir ist schon klar, man möchte sich halt abheben vom Pöbel...
Jetzt mal ohne Polemik. C wurde doch als "portabler Assembler" konzipiert, um das Betriebssystem Unix auf anderen Maschinen laufen zu lassen. Auf so einer Low-Level-Ebene stand/steht Performance an erster Stelle.
Richtig. Das Konzept von Zeigern ist auf CPU-Ebene unverzichtbar. Man kann sie mehr oder weniger gut hinter anderen Sprachelementen verstecken, aber letztlich sind es halt doch Speicheradressen, die eine andere Speicheradresse enthalten.
Natürlich sucht man sich auch den geeigneten Datentyp nach der Anwendung aus. Wenn man die nicht hat (bzw. noch nie zwischengehabt hat), kann man auch mit der abstrakten Definition was der Datentyp ist, nichts anfangen.
Klassisches Beispiel für die Anwendung von Pointer auf Pointer ist eine Datenstruktur, welche eine - nicht von vornherein festgelegte! - Anzahl von Zeichenketten (0-terminiert) verwaltet, deren Länge wiederum nicht von vornherein festgelegt ist. Also: jede dieser Zeichenketten kann unterschiedlich lang sein.
Diese Datenstruktur würde man dann so vereinbaren: char **page;
Damit haben wir bereits einen Zeiger auf Zeiger: page zeigt auf ein Array von Zeichenketten. Diese werden, wie in C üblich, als "char *" deklariert. Den Zeiger auf die i-te Zeichenkette (sofern page genügend groß alloziert wurde!) bekommt man dann mit
geliefert, was C intern direkt in die Notation *(page+i) umsetzt.
Ist die i-te Zeichenkette von page auch lang genug, so kann man das j-te Zeichen dieser Zeichenkette mit
herausholen.
Diese Datenstruktur wird in C in jedem Programm verwendet! Die Laufzeitumgebung teilt auf diese Weise dem aufgerufenen Programm über die Parameter von main() mit, mit welchen Argumenten in der Kommandozeile das Programm aufgerufen wurde. Darum lautet die vollständige Deklaration von main() eben:
int main(char **argv, int argc)
Das folgende kleine Programm, macht nun nichts anderes, als die eigene Kommandozeile, inklusive dem eigenen Programmnamen in argv[0] auszugeben:
Hier wurde ausschließlich der Pointer in argv verwendet. Mit argv++ wird zur nächsten Zeichenkette übergegangen, *vorher* aber noch der Pointer auf die aktuelle Zeichenkette als Argument an printf() übergeben. Als letzter Pointer steht in argv[argc] (mit dem Aufrufwert von argv) vereinbarungsgemäß immer ein NULL-Zeiger drin, und die while-Schleife nutzt das als Abbruchbedingung.
Mit der Array-Notation läßt sich das ganze auch hinschrieben, man braucht nur halt eine Extra-Laufvariable:
Was nun für die jeweilige Anwendung besser ist, muß der Programmierer selbst entscheiden. Manchmal ist die Array-Notation naheliegend, ein andermal (z.B. bei verketteten Listen) ist die Pointer-Notation eher passend.
Das folgende kleine Programm, macht nun nichts anderes, als die eigene Kommandozeile, inklusive dem eigenen Programmnamen in argv[0] auszugeben:
Alles anzeigenCHier wurde ausschließlich der Pointer in argv verwendet. Mit argv++ wird zur nächsten Zeichenkette übergegangen, *vorher* aber noch der Pointer auf die aktuelle Zeichenkette als Argument an printf() übergeben. Als letzter Pointer steht in argv[argc] (mit dem Aufrufwert von argv) vereinbarungsgemäß immer ein NULL-Zeiger drin, und die while-Schleife nutzt das als Abbruchbedingung.
Wusste gar nicht, dass am Ende von argv eine NULL garantiert ist, ist aber scheinbar im C99 Standard enthalten.
http://stackoverflow.com/quest…a-null-at-the-end-of-argv
Zitat von tulanWusste gar nicht, dass am Ende von argv eine NULL garantiert ist, ist aber scheinbar im C99 Standard enthalten.
Gilt auch schon für C89 bzw. C90. Siehe "K&R, Programmieren in C", Zweite Ausgabe, auf Seite 110 ganz unten:
Zitat von K&R...; zusätzlich verlangt der Standard, daß argv[argc] ein Nullzeiger ist.
Wusste gar nicht, dass am Ende von argv eine NULL garantiert ist
Ich auch nicht. Danke, wieder was gelernt.
EDIT: ...habe aber gerade bei einem Blick in einen alten Sourcecode gesehen, dass ich es schon mal gewusst haben muss