call by name/reference problem
-
hi,
ich habe ein programm mit einer struktur "auto".
sie hat ein attribut "ps" als integer.über punktnotation kann ich super den wert ändern.
jedoch wenn ich mir eine funktion schreibe "setPS", über die man
den ps-wert ändern kann, compiled das zwar ohne probleme, jedoch
wird nicht tatsächlich der neue Wert in das Objekt "auto" geschrieben,
sondern es ist noch immer der alte drin.ich glaube mich entsinnen zu können, dass das etwas mit
call by name / reference zu tun hat oder?wenn ich meine funktion "setPS" auf ein auto anwende, dann ist es
glaube ich nur call by name und es wird sozusagen nur mit dem wert gearbeitet,
nicht mit der tatsächlichen Speicherzelle, wo die PS des autos gespeichert sind, oder?nun zumindest wollte ich das durch "const" lösen, damit es mit
call by reference arbeitet.
und das funktioniert irgendwie nichtich kann mit der funktion
setPS einfach nicht wirklich die neue PS-anzahl in ein objekt speicher:#include <stdio.h> #include <string.h> struct auto { int ps; }; int getPS(struct auto a) { return a.ps; } int setPS(struct auto a,const int newPS) { a.ps = newPS; return 0; } int main(int argc, char *argv[]){ struct auto bmw; bmw.ps = 100; setPS(bmw,200); printf("ps von bmw: %i\n",getPS(bmw)); return 0;}
die ausgabe ist immer noch 100, obwohl ich ja in der funktion
setPS die variable als 'const' deklariert habe...bräuchte da mal ein wenig nachhilfe bitte
und überhaupt: hat das etwas mit call by name /reference zu tun oder
bring ich da jetzt irgendwas total durcheinanderdanke
-
hdi schrieb:
und überhaupt: hat das etwas mit call by name /reference zu tun oder
bring ich da jetzt irgendwas total durcheinandereiniges. du solltest die struct 'by reference' übergeben, indem du einen pointer an die funktionen übergibst. nur dann kann das originalobjekt verändet werden. so wie du es machst (übergabe 'by value') wird jedesmal eine kopie erzeugt und änderungen davon haben natürlich keine wirkung auf das original.
-
okay danke, ich hab das jetzt so gemacht.
allerdings bekomme ich immer einen speicherzugriffsfehler.
hier jetzt, was ich geändert hab:#include <stdio.h> #include <string.h> #include <stdlib.h> struct auto { int ps; }; int getPS(struct auto a) { return a.ps; } int setPS(struct auto a,const int *newPS) { a.ps = *newPS; return 0; } int main(int argc, char *argv[]){ struct auto bmw; bmw.ps = 100; int *ps; *ps = 200; setPS(bmw,ps); printf("ps von bmw: %i\n",getPS(bmw)); return 0;}
und noch eine frage: ich habe es jetzt nur so hinbekommen, damit
der compiler nicht meckert wegen castings und so.
aber diese zeilen hier:int *ps; *ps = 200; setPS(bmw,ps);
geht das nicht einfacher? ich hab doch extra eine funktion setPS, damit es eben leichter geht, aber irgendwie funktioniert es bei mir nur, wenn ich davor eben n neuen pointer anleg. kann ich das nicht irgendwie gleich mit der funktion übergeben?
-
du kannst die struct nicht 'auto' nennen, denn auto ist ein reserviertes schlüsselwort in C. mach das A gross oder so, dann geht es.
-
hey, das war nur ein beispiel.
ich bekomm nen speicherzugriffsfehler, das hat doch etwas mit pointern zu tun oder arrays oder so oder?
-
so etwa könnte es klappen
#include <stdio.h> #include <string.h> #include <stdlib.h> struct Auto { int ps; }; int getPS (struct Auto *a) { return a->ps; } void setPS (struct Auto *a, int newPS) { a->ps = newPS; } int main () { struct Auto bmw; setPS (&bmw, 13); printf("ps von bmw: %i\n",getPS(&bmw)); }
-
ui oO.
was isn das mit diesen "->".
man muss dazu sagen ich fang gerade erst mit c an,
also vielen dank für den vorschlag,
jedoch möchte ich lieber vertraut werden mit den
sachen, mit denen ich mich gerade beschäftige.es muss doch auch anders gehen.
ich hoffe ihr versteht das, ich möchte es halt gerne "normal" machen,
also ohne diese komischen "->".
ich will einfach step by step lernen und bin einfach im moment an einem
punkt (online tutorial) wo diese dinger noch nicht behandelt wurden.trotzdem müsste ich das programm eigentlich hinkriegen
man ich check das noch nicht so ganz mit diesen pointern irgendwie :p
-
Ohne Pointer kriegst du die Übergabe eigentlich nicht hin.
Außer du gibst die geändert Struktur wieder zurück:struct Auto setPS(struct Auto a, const int newPS) { a.ps = newPS; return a; } int main () { struct Auto bmw; bmw = setPS(bmw, 13); }
Nachteil dieser Methode (besonders bei großen Strukturen) ist, daß jedesmal die gesamte Struktur kopiert wird.
Aber der übliche Weg in C ist die Übergabe mit "Call by Reference", d.h. mit Zeigern (so wie vom Vorposter beschrieben).
Und du solltest übrigens die Struktur als Pointer übergeben, nicht den zu änderden Wert!
Aber wenn du dann bei den Zeigern (bei deinem Online-Tutorial) angekommen bist, dann kanst du dieses Beispiel ja noch mal heranziehen.
-
hi,
das wurde jetzt missverstanden:
ich habe schon pointer gemacht, nur dieses "->" hab ich noch nie gesehen.
ich meinte, es müsste ja auch ohne das "->" gehen mit pointern oder?und du sagst, ich soll die struktur als pointer übergeben.
wie genau meinst du das? ich hab jetzt 20 minuten rumprobiert
und mal hier ein * davorgesetzt und mal da, aber krieg immer fehelr.
ich kapier das einfach nicht mit den pointern irgendwie..bitte könnt ihr mir nicht sagen wie ich das programm genau ändern muss, ich komme einfach nicht drauf durch eure hinweise
-
hdi schrieb:
hi,
das wurde jetzt missverstanden:
ich habe schon pointer gemacht, nur dieses "->" hab ich noch nie gesehen.
ich meinte, es müsste ja auch ohne das "->" gehen mit pointern oder?Klar geht es auch ohne - das wäre dann
(*a).ps = newPS;
(aber weil dort die Klammerung nötig - und u.U. reichlich verwirrend - ist, gibt es die Variante mit ->)und du sagst, ich soll die struktur als pointer übergeben.
wie genau meinst du das? ich hab jetzt 20 minuten rumprobiert
und mal hier ein * davorgesetzt und mal da, aber krieg immer fehelr.
ich kapier das einfach nicht mit den pointern irgendwie..Mach's doch so, wie Heidi das vorgeführt hat - die Funktion bekommt einen "struct Auto* pa" als Parameter und beim Aufruf übergibst du die Adresse "&meinAuto".
-
okay jetzt geht es!
Also nur damit ich mir das richtig merke:
Das "*" muss in Klammern gesetzt werden, sobald man
auf einem Pointer mit der Punktnotation arbeitet oder?und "->" ist einfach nur eine andere Schreibweise,
arbeitet aber genauso wie die Punktnotation?dankeschön
-
hdi schrieb:
Das "*" muss in Klammern gesetzt werden, sobald man
auf einem Pointer mit der Punktnotation arbeitet oder?nur bei pointern auf structs, weil der punkt sonst vorrang vor dem '*' hätte und dann würde es nicht klappen.
hdi schrieb:
und "->" ist einfach nur eine andere Schreibweise,
arbeitet aber genauso wie die Punktnotation?jo, das '->' ist zum indirekten zugriff auf struct-members da.