Hallo zusammmen, meine C Pointerkenntnisse sind leider etwas eingerostet, daher habe ich folgende Frage. Ich habe eine Funktion x welche einen Pointer auf eine Int Variable übergeben bekommt. In dieser Funktion habe ich aus Gründen der Übersichtlichkeit einen Teil in eine weitere Funktion y ausgegliedert. Die Funktion y muss dabei aber auch Zugriff auf die Int Variable haben die auf die Funktion x übergeben wurde :) hier mal mein Vorhaben in gekürzter Variante:) void x (int *var_x) //Funktion1 { ..... y(var); } void y (int *var_y) //Unterfunktion { *var_y = 42; } main () { int var; x(var); printf("%d",var); (soll dann 42 ausgeben) } Ist dies so korrekt? Oder muss ich bei der zweiten Funktion einen Pointer auf einen Pointer verwenden. Bin da gerade etwas verwirrt.
der Aufruf von x müsste so ausschauen:
1 | x(&var); |
Da x einen int-Pointer als Parameter will, und var nur als int definiert ist (nicht als pointer zu einem int).
nein, nicht ganz.
1 | void x (int *var_x) //Funktion1 |
2 | { |
3 | ..... |
4 | y( /* hier -> */ var_x); // nicht var, sondern var_x |
5 | |
6 | } |
7 | |
8 | void y (int *var_y) //Unterfunktion |
9 | { |
10 | *var_y = 42; |
11 | } |
12 | |
13 | main () |
14 | { |
15 | int var; |
16 | x( /* hier -> */ &var ); // Adresse der Variablke ist der Pointer darauf |
17 | printf("%d",var); (soll dann 42 ausgeben) |
18 | } |
Abgesehen davon: es hat sich bewährt, Zeigervariablen mit einem p beginnen zu lassen (und Zeiger auf Zeiger mit pp...). Dann kann man leichter auseinanderhalten, was ein Wert ist und was ein Zeiger darauf.
Sorry ich habe einen Fehler gemacht. Meine Main sieht so aus: main () { int var; int *ptr; ptr = &var; x(ptr); printf("%d",var); (soll dann 42 ausgeben) }
Zeiger schrieb: > Quatsch Glückwunsch für deinen ersten qualifizierten Beitrag. Und dann noch orthografisch ohne Mängel!
Zeiger schrieb: > Quatsch Das zeigt nur dass du dich noch nie in einem professionellen Prograsmmier-Umfeld bewegt bzw betätigt hast.
Ungarische Notation ist so ziemlich das dümmste, was es gibt. Der Typ einer Variable ist bei deren Definition nachlesbar. Das braucht man nicht jedes Mal bei jeder Verwendung nochmal.
Zeiger schrieb: > Ungarische Notation ist so ziemlich das dümmste, was es gibt. > Der Typ einer Variable ist bei deren Definition nachlesbar. Das braucht > man nicht jedes Mal bei jeder Verwendung nochmal. Warum sollte man extra etwas nachschauen wollen / müssen, wenn es auch auf einem Blick ersichtlich sein kann? Gruß Dennis
Dennis S. schrieb: > Warum sollte man extra etwas nachschauen wollen / müssen, Er hat eben nur 3 Pointer, und deren Typ kann er sich grad noch so merken, da braucht er nicht nachschauen. Eben ein Profi !
Zeiger schrieb: > Ungarische Notation ist so ziemlich das dümmste, was es gibt. Da gebe ich dir recht. Das war damals schon dämlich, als es propagiert wurde, und ist es gerade bei OO-Sprachen, wo es fast mehr Typen als Objekte gibt. Aber: ein Variablenname soll sprechend sein und klarmachen, um was es sich handelt. Ich weiß nicht, ob wir da einer Meinung sind, aber das ist mir egal. Und ein Name wie "iterator" oder "Zaehler" oder "Summe" ist grundfalsch, wenn es sich nicht um einen Iterator, einen Zähler oder eine Summe handelt, sondern um einen Zeiger auf soetwas. Im OP steht etwas von var_x, obwohl es ein Zeiger auf etwas ist, was man vielleicht als var_x oder x bezeichnen könnte. Also ist var_x für den Zeiger ein mißverständlicher Name und damit einfach schlecht. Ob man das jetzt verbessert, indem man den Zeiger zeiger_auf_x oder ptr_to_x oder p_x nennt, ist natürlich Geschmackssache und das will ich auch niemandem vorschreiben. Aber etwas in dieser Art ist sicher angebracht bei einem Zeiger, und die weitaus üblichste Methode ist nunmal, das zumindest mit einem p zu kennzeichnen. Natürlich gibt es viele Stile, aber das ist einer der gängigeren und er hat sich bewährt. Wer Programme schreibt und darin Zeiger nicht deutlich als solche benennt, den nehme ich nicht wirklich ernst. Und schon gar nicht, wenn er sowas pauschal als Quatsch abtut und nicht sagen kann, warum.
>Aber: ein Variablenname soll sprechend sein und klarmachen,
Da stimme ich dir voll und ganz zu.
Man erreicht dies aber nicht durch dümmliche Regeln, die besagen, dass
man Variablennamen immer mit diesem oder jenem Prefix versehen muss.
Zeiger schrieb: >>Aber: ein Variablenname soll sprechend sein und klarmachen, > > Da stimme ich dir voll und ganz zu. > Man erreicht dies aber nicht durch dümmliche Regeln, die besagen, dass > man Variablennamen immer mit diesem oder jenem Prefix versehen muss. Trotzdem hat es sich bewährt, einem Zeiger Datentyp eine Kennzeichnung zu verpassen. Das hat mit ungarischer Notation nur sehr am Rande zu tun, die (die ungarische Notation) im übrigen sowieso meist falsch verstanden wird. Die Idee bei der ungarischen war es nie, den eigentlichen Datentyp da mit reinzuschustern, sondern eine Kennzeichnung über den logischen Typ einer Variablen dafür vorzusehen, damit man ohne ständiges Nachsehen und Scrollen im Code die Korrektheit leicht verifizieren kann. In der Computergrafik ist es zb unumgänglich zwischen absoluten und relativen Koordinaten zu unterscheiden. Das kann man zb mit einem Präfix oder einem Postfix im Variablennamen machen. Sehe ich eine Anweisung
1 | pointAbs = Object.transformToAbs( pointRel + offsetAbs ); |
dann weiss ich, das das nicht stimmen kann. Denn eine relative Position mit einem im absoluten Korrdinatensystem definierten Offset zu versehen, macht keinen Sinn. Das müsste sehr wahrscheinlich
1 | pointAbs = Object.transformToAbs( pointRel ) + offsetAbs; |
lauten. Und auch bei Pointern ist eine derartige Kennung hilfreich. Bei einem
1 | ppPtr->Object |
hab ich nunmal einen Pointer auf einen Pointer. Und das ist was anderes als ein einfacher Pointer pPtr. Was wiederrum etwas anderes ist, als ein Pointer auf ein Array. Natürlich kann man sich diese kleinen Hilfen auch sparen. Insbesondere in modernen IDEs, in denen dauernd irgendwo ein Tooltip aufgeht, der einem dann den Datentyp einer Variablen anzeigt. Nur da muss ich dann dauernd mit der Maus spazieren fahren, bis die über der Variablen steht und mir anzeigt, was die für einen Typ hat. Markiere ich mir den Pointer im Namen, dann kostet mir das beim Tippen nichts und es gibt keine Unklarheiten, wo ich bei wievielen Dereferenzierungen landen werde und ob ich dann eine -> Operation oder eine . Operation benötige, bzw. wie bei komplexeren Operationen die Klammern sitzen müssen. Ganz abgesehen davon, dass ich in Ruhe und überlegt meinen Code schreiben möchte, ohne das dauernd irgendwo ein Tooltip-Fenster aufpappt.
:
Bearbeitet durch User
>hab ich nunmal einen Pointer auf einen Pointer. Und das ist was anderes als ein einfacher Pointer pPtr. Solche trivialen Fehler werden umgehend von jedem Compiler entlarvt. > pointAbs = Object.transformToAbs( pointRel ) + offsetAbs; Was soll denn ein absoluter Offset sein? Was kommt denn bei der Addition zweier absoluter Werte raus?
Zeiger schrieb: >>hab ich nunmal einen Pointer auf einen Pointer. Und das ist was anderes > als ein einfacher Pointer pPtr. > > Solche trivialen Fehler werden umgehend von jedem Compiler entlarvt. > >> pointAbs = Object.transformToAbs( pointRel ) + offsetAbs; > > Was soll denn ein absoluter Offset sein? > Was kommt denn bei der Addition zweier absoluter Werte raus? wieder ein absoluter Wert. Das ganze hat ein bischen was von der "Kontrollrechnung" in der Physik, in der man nicht mit Zahlenwerten sondern anhand der Einheiten überprüft, ob ein Formelergebnis überhaupt plausibel ist.
In C++ könnte man sich eigene Typen für absolute und relative Werte definieren, und die Operatoren derart überladen, dass man nur zusammenpassende Werte addieren kann. Dann spart man sich die Präfixe weil der Compiler dann alle Fehler findet...
Zeiger schrieb: > Solche trivialen Fehler werden umgehend von jedem Compiler entlarvt. Du hast wohl noch nie größere Projekte fremden Codes lesen müssen. Da nützt dir auch kein Compiler was, du willst schnell verstehen wie und warum jemand das Programm genau so geschrieben hat. Und dabei hilft es immens direkt beim Lesen zu erkennen was für ein Typ die Variablen sind. Sklavische Prefixe bis zum xten Subtyp helfen nicht, aber clever benutzt machen sie Code deutlich lesbarer.
Udo Schmitt schrieb: > Und dabei hilft es immens direkt beim Lesen zu erkennen was für ein Typ > die Variablen sind. Wobei, und das sollte man herausstreichen, mit 'Typ' hier ursprünglich nicht unbedingt der konkrete Datentyp der Variablen gemeint war, sondern mehr von welcher Art eine Variable ist. Anhand des Namens soll man zb. erkennen können, ob man es mit einem echten Pointer zu tun hat, oder ob es sich um einen Handle handelt, der zwar auch irgendein anderes Objekt referenziert, dessen Inhalt aber eben nicht die konkrete Speicheradresse ist, sondern irgendein anderes Merkmal. Die Handles, die man von der Windows-API kriegt, sind eben keine Pointer, die man dereferenzieren kann. Trotzdem identifizieren sie den Pen, den man in den Ausgabefunktionen benutzt. Den Handle krieg ich von der Windows-API, wenn ich einen Pen erzeugen lass und ich gebe ihn ihr auch zurück und benutze ihn in den Ausgabefunktionen. Und genau das ist es, was mir das 'h' in 'hCurrentPen' sagt: es handelt sich um einen Handle und nicht wie in 'pCurrentPen' um einen Pointer zu einem Pen Objekt, wohingegen ein 'CurrentPen' das Pen Objekt selber ist. Und das ganz ohne, dass ich beim Entwickeln des Codes dauernd die Datentypen raussuchen muss. Sicher, bei kleinen einfachen Programmen sind das alles Kinkerlitzchen. Wenn die Anzahl der Codezeilen aber in die Hundertausende geht, ist man über jede Vereinfachung froh, die einem das Leben mit wenig Aufwand leichter macht. Das Microsoft das nicht verstanden hat, dass die Intention der ungarischen Notation nicht darin bestand, dass man an 'dwIndex' anlesen kann, dass es sich um ein Double Word handelt, dafür kann die ungarische nix. Darum ist es in der ursprünglichen ungarischen überhaupt nie gegangen.
:
Bearbeitet durch User
>aber clever benutzt machen sie Code deutlich lesbarer. Ja. clever benutzt. Aber durch eine Regel wie "immer alles schön Prefixen" kommt genau das Gegenteil heraus. Was soll mir denn ein p-Präfix an Lesbarkeit beingen? > currentValue = values->value; versus: > currentValue = pValues->value; Das bringt absolut Null Mehrwert. Ganz im Gegenteil. Es obfuskiert den Namen. Selbst wenn danach ein values++ kommt (Pointerarithmetik), wird aus dem Kontext sofort klar, dass values ein Pointer ist. Da braucht es keinen p-Präfix. >Du hast wohl noch nie größere Projekte fremden Codes lesen müssen. Achje. Ab wieviel Millionen Zeilen ist für dich ein Projekt groß?
Karl Heinz schrieb: > Und genau das ist es, was mir das 'h' in 'hCurrentPen' Warum sollte das denn überhaupt eine Rolle spielen? Wenn ich currentPen lese, dann weiß ich, dass dieses Objekt in irgendeiner Weise den Pen identifiziert. Wie es das macht ist mir doch egal. Sobald ich damit arbeiten will muss ich aber in_ _jedem_ _Fall die Dokumentation der Funktion lesen, der ich currentPen übergebe. Es bleibt nur, dass das 'h' ein zusätzliches Rauschen im Lesefluss ist.
Weißt du, was das schöne an einer Empfehlung ist? Du kannst sie ignorieren, wenn du keinen Sinn drin siehst.
Klaus Wachtler schrieb: > Du kannst sie ignorieren, wenn du keinen Sinn drin siehst. Und deshalb darf man sie nicht grundsätzlich hinterfragen?
Zeiger schrieb: > Klaus Wachtler schrieb: >> Du kannst sie ignorieren, wenn du keinen Sinn drin siehst. > > Und deshalb darf man sie nicht grundsätzlich hinterfragen? Darfst du. Andere haben das auch getan, und das als für sie gut befunden. Was nicht heisst, dass ich die ungarische in ihrer vollen Ausprägung, vor allen in der MS-Version, gut finde. Aber den Pointer p hab ich mir auch angewöhnt und finde ihn gut.
:
Bearbeitet durch User
Das Pointer-p war auch in TPascal üblich und nach meiner Erinnerung teils vorgeschrieben, z.B. um Fenster vom abstrakten Typ TObject bzw. TWindow abzuleiten: PWindow zeigt auf Objekt vom Typ TWindow Von den vielen, für mich neuen (Standard-)Prefixen in C/Cpp war ich anfangs nicht begeistert, finde aber diverse Prefixe nützlich, um Bezeichner näher zu beschreiben und Dinge der gleichen Kategorie durch ein gleiches Prefix vor verschiedenen Namen oder durch den gleichen Namen hinter verschiedenen Prefixen zu gruppieren. Mich stört aber, daß laut einigen Quellen der Unterstrich zu vermeiden ist. Wozu soll das gut sein? Woher kommen die vielen Typen wie uint8_t, size_t, wchar_t, usw.?
:
Bearbeitet durch User
Rainer V. schrieb: > Mich stört aber, daß laut einigen Quellen der Unterstrich zu vermeiden > ist. Nun, "einige Quellen" sind erstmal nicht normativ. Und waren vielleicht führende Unterstriche gemeint? Die sind tastächlich zu vermeiden, weil sie eine Sonderrolle haben.
Rolf Magnus schrieb: > Nun, "einige Quellen" sind erstmal nicht normativ. Und waren vielleicht > führende Unterstriche gemeint? Die sind tastächlich zu vermeiden, weil > sie eine Sonderrolle haben. Zu vermeidne sind nur die führenden, damit sie nicht mit Dingen aus den Headerdateien kolliedieren. Die _ innerhalb von Namen sind im Prinzip zulässig. Allerdings macht es Sinn, Namen nach einem halbwegs einheitlichen Schema zu vergeben. Und da war es in C gängig (wenn auch nicht verbindlich) etwa so zu benamsen: anteil_dummer_teilnehmer_am_ganzen_forum für Variablen bzw. anzahl_t für einen passenden Datentyp. In C++ ist es eher gängig (wenn auch wieder nicht zwingend, nicht _ zum Trennen der einzelnen Wörter in einem Namen, sondern stattdessen Groß-/Kleinschreibung (camel case), wobei Objekte mit einem kleinen Buchstaben angfangen, Typen dagegen mit einem Großbuchstaben, also anteilDummerTeilnehmerImForum vom Typ Anzahl.
Zu Unterstrichen in C/Cpp siehe Wiki "Ungarische Notation", hinter dem Inhaltsverzeichnis in Abschnitt "Apps Hungarian" und ca. in der Mitte im Abschnitt "Bezeichner": http://de.wikipedia.org/wiki/Ungarische_Notation Das war in TPascal auch so: idButton=123 und nicht id_Button=123 Anders im Ressourcenscript: ids_Name="Blaise", idc_PushButton=123 In meinen Büchern steht nichts zu den Prefixen. Da ist nur zu lesen, daß führende Unterstriche eher eine Frage des Schreibstils sind und daß es da keine festen Regeln gibt. Über reservierte, führende/nachfolgende Unterstriche war im Web etwas zu lesen. Es ging um Symbole zur bedingten Compilierung, damit ein Header nicht mehrmals eingebunden wird, oder um Assemblersyntax in den Formaten Intel oder AT&T.
Klaus Wachtler schrieb: > Und da war es in C gängig (wenn auch nicht verbindlich) etwa so zu > benamsen: > anteil_dummer_teilnehmer_am_ganzen_forum für Variablen bzw. anzahl_t für > einen passenden Datentyp. > In C++ ist es eher gängig (wenn auch wieder nicht zwingend, nicht _ zum > Trennen der einzelnen Wörter in einem Namen, sondern stattdessen > Groß-/Kleinschreibung (camel case), Lustigerweise, obwohl die Sprache selbst (sowohl die Standardbibliothek, als auch fest in der Sprache eingebaute Namen wie static_cast) durchgängig die Variante mit Kleinbuchstaben und Unterstrichen nutzen.
:
Bearbeitet durch User
Rolf Magnus schrieb: > Lustigerweise, obwohl die Sprache selbst (sowohl die Standardbibliothek, > als auch fest in der Sprache eingebaute Namen wie static_cast) > durchgängig die Variante mit Kleinbuchstaben und Unterstrichen nutzen. ... was ich aber eigentlich ganz gut finde. Man erkennt dann an der Schreibweise, was vorgegebener Standard ist und was selbst gebraut wurde. Also eine Art inoffizieller namespace :-)
Klaus Wachtler schrieb: > was vorgegebener Standard ist und was selbst gebraut wurde wie etwa bei lecker_koelsch_aus_colonia und altbierausduesseldorf. Aber was ist z.B. mit Funktion localtime_r? Soll laut diesem Tutorial http://www.cplusplus.com/reference/ctime/localtime/?kw=localtime eine Alternative zu localtime aus <time.h> bzw. <ctime> sein, ist jedoch nicht zwingend in jeder Bibliothek vorhanden, daher auch nicht portabel. Einen Unterstrich hat es aber.
Rolf Magnus schrieb: > Lustigerweise, obwohl die Sprache selbst (sowohl die Standardbibliothek, > als auch fest in der Sprache eingebaute Namen wie static_cast) > durchgängig die Variante mit Kleinbuchstaben und Unterstrichen nutzen. Nur wenn man bei FILE beide Augen fest zudrückt... Keine Ahnung was sich die Herren dabei überlegt haben. Auch einige Makros wie EOF, BUFSIZ oder FOPEN_MAX sind gross geschrieben, das ist aber auch gut so, sind ja schliesslich Makros. Ich frage mich eher, warum man für einige Standardfunktionen kryptische Namen wie z.B. strpbrk wählen musste. Aussagekräftige Namen sehen anders aus. Auch das BUFSIZ hätte man wenigstens BUFSIZE, oder gleich STDIO_BUFFER_SIZE taufen können. Aber ich muss Klaus zustimmen, der inoffizielle namespace ist zu gebrauchen :)
be stucki schrieb: > Ich frage mich eher, warum man für einige Standardfunktionen kryptische > Namen wie z.B. strpbrk wählen musste. Das ist historisch gewachsen. Es gab wohl mal eine Zeit, in der Funktionsnamen so kurz wie irgend möglich sein mussten; ähnliches kennt man von unixoiden Betriebssystemen, bei denen viele Programme/Kommandozeilenbefehle auch möglichst kurze Namen haben müssen. Das ist dann "mächtig".
be stucki schrieb: > Rolf Magnus schrieb: >> Lustigerweise, obwohl die Sprache selbst (sowohl die Standardbibliothek, >> als auch fest in der Sprache eingebaute Namen wie static_cast) >> durchgängig die Variante mit Kleinbuchstaben und Unterstrichen nutzen. > > Nur wenn man bei FILE beide Augen fest zudrückt... Keine Ahnung was sich > die Herren dabei überlegt haben. Auch einige Makros wie EOF, BUFSIZ oder > FOPEN_MAX sind gross geschrieben, das ist aber auch gut so, sind ja > schliesslich Makros. Ja, Makros sind nochmal was eigenes. FILE war meines Wissens früher auch mal ein Makro. Rufus Τ. Firefly schrieb: > Das ist historisch gewachsen. Es gab wohl mal eine Zeit, in der > Funktionsnamen so kurz wie irgend möglich sein mussten; Nicht unbedingt so kurz wie möglich. Es gab allerdings in der Urzeit von C bei manchen Linkern Beschränkungen bei den Längen von Bezeichnern. Teilweise waren meines Wissens nur bis zu 6 Zeichen möglich. > ähnliches kennt man von unixoiden Betriebssystemen, bei denen viele > Programme/Kommandozeilenbefehle auch möglichst kurze Namen haben müssen. Die müssen diese nicht haben, aber wenn man manche davon im Alltag hundert mal an einem Tag eintippen muss, ist man froh, wenn der Name kurz ist. Lernen muss man die Kommandos eh, und wen man sie oft benutzt (was damals halt der Normalfall war), dann ist einem eigentlich die konkrete Buchstabenfolge relativ egal, solange sie möglichst kurz ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.