Hi zusammen, ich möchte eine Funktion in einer Funktion aufrufen (diese wird vordefiniert) und der Rückgabe wert soll ein Array sein. Allerdings geht es nur wenn ich das array als global anlege. Könnte mir jemand erklären warum das so ist ? Grundstrucktur des Programms: //Defintions and Declaration: unsigned short int a; unsigned short int b; unsigned short int c; unsigned short int array[3]; -> als globales Array funktioniert das Programm // Function-Predefinitions: unsigned short int func2() { unsigned char i=0; unsigned short int s_a = 20; unsigned short int s_b = 40; unsigned short int s_g = 60; array[1]=s_a*2; array[2]=s_b*2; array[3]=s_g*2; return(array[i]); } void func1(void) { -> unsigned short int array[3]; => als lokales Array geht es nicht func2(); th_U = times[1]; th_V = times[2]; th_W = times[3]; } //MAIN int main(void) { func1(); return 0; } Danke im vorraus für eure Hilfe
Ein Arry als Rückgabe geht nicht. Du must der Funktion einen Zeiger auf das Array übergeben. Dann kannst du in der Funktion das Array verändern.
Deine 'lokale' Variante: Alexander S. wrote: > unsigned short int func2() > { > unsigned char i=0; > unsigned short int s_a = 20; > unsigned short int s_b = 40; > unsigned short int s_g = 60; /*** array[...] ist hier nicht deklariert */ > array[1]=s_a*2; > array[2]=s_b*2; > array[3]=s_g*2; > return(array[i]); > }
Geht deswegen nicht, weil func2 nichts von dem lokalen Array weiss. Es kenn nur seine Variablen und die globalen. Die lokalen Variablen einer anderen Funktion sieht es nicht. Der lokale Array gilt also nur in func1.
Hallo, @ Bernd Hallinger > Ein Arry als Rückgabe geht nicht. Du must der Funktion einen Zeiger auf > das Array übergeben. Dann kannst du in der Funktion das Array verändern. Nur zum richtigen Verständnis: Eine "Array"-Variable in "C" ist doch immer ein Zeiger (auf das erste Element). In dem Quelltextauszug sind aber noch reilich Ungereimtheiten, so dass ich meine Zweifel habe, dass er sich überhaupt compilieren läßt, bzw. sinnvolle Ergebnisse liefert. Stichworte: undefinierte/-deklarierte Variablen, Namensräume, Bereichsüberschreitungen, ... Tschü Dude
Bernd Hallinger wrote:
> Ein Arry als Rückgabe geht nicht.
Das geht schon, Du mußt Dir nur einen entsprechenden Typ definieren.
Bloß gewinnst Du dabei nichts, da das der Returnwert der Funktion ist,
den Du einer gleichen Variable des Aufrufers zuweisen mußt.
Der Aufrufer muß sie also immer anlegen.
Peter
Arrays als rueckgabe wert geht schon. Wenn Du das array mit call by reference uebergibst (pointer auf array) dann kann die aufgrufene funktion da reinschreiben und der Aufrufer hat dann die Werte da wo er sie will. Also auch als automatische variable (in der funktion deklariert) Nur wenn ich mir das so anschaue was du da vorhast schlage ich vor das Du eine strukur definierts da arrays ein paar nachteile haben. Die dimension des arrays muss zwischen Aufrufer und Aufgerufenen abgesprochen sein oder man uebergibt das als zusaetzliche variable. Also in etwa so: //Defintions and Declaration: typedef struct _mydata_s { unsigned short int a; unsigned short int b; unsigned short int g; } mydata_t; // Function-Predefinitions: mydata_t * func2( mydata_t *pD ) { unsigned char i=0; unsigned short int s_a = 20; unsigned short int s_b = 40; unsigned short int s_g = 60; pD->a = s_a*2; pD->a = s_b*2; pD->a = s_g*2; // Das return st nicht notwendig da func2 ueber ptr pD direkt zugriff // auf die daten hat return(pD); } void func1(void) { mydata_t loc_data; // !!! nicht initialisiert func2( &loc_data ); // nach aufruf enthaelt // loc_data.a loc_data.b loc_data.g die gwuenschten daten th_U = times[1]; th_V = times[2]; th_W = times[3]; } //MAIN int main(void) { func1(); return 0; }
Hallo,
@Heinz Blättner
> Wenn Du das array mit call by reference uebergibst (pointer auf array)...
Wie oben schon geschrieben:
Eine "Array"-Variable in "C" ist doch immer ein Zeiger (auf das erste
Element).
Also kann man ein "Array" (nicht nur ein Element!) doch nur als Pointer
übergeben.
Tschü Dude
Eben es ist schon ein Pointer aber man muss der Funktion die Adresse hin übergeben. Die Adresse / der Pointer muss der Funktuion bekannt gemacht werden nicht das Array zurückgeben. void foo (unsigned int * liste) { liste[1] = 0; liste[2} = 4711; } void main(void) { unsigned int Folge[10]; foo(Folge); printf("%d", Folge[2]); }
@ 12er Dude (Gast) >> Wenn Du das array mit call by reference uebergibst (pointer auf array)... > Wie oben schon geschrieben: > Eine "Array"-Variable in "C" ist doch immer ein Zeiger (auf das erste Element). IMMER nicht siehe: http://en.wikipedia.org/wiki/C_(programming_language)#Array-pointer_interchangeability > Also kann man ein "Array" (nicht nur ein Element!) doch nur als Pointer > übergeben. Das ist der default Fall Mit etwas Aufwand kann man auch arrays by value uebergeben :-) Es wird dann wie gewohnt eine Kopie auf dem stack erzeugt. br heinz
Beispiel fuer array call by value: struct Array { int element[100]; } a; void foo( struct Array arr) { arr.element[0] = 1; } int main(void) { a.element[0] = 0; foo(a); return a.element[0]; } main exist status wird 0 werden, da foo() eine Kopie des arrays bekommt, damit wird a.element[0] nicht veraendert. Das ist aber nicht empfehlenswert (da zusaetzlicher laufzeit fuer array kopieren anfaellt) Besondert nicht auf embedded Kontrollern da: - RAM ist nicht beliebig vorhanden (Platz fuer Kopie auf dem Stack) - Laufzeit (fure das kopieren) br heinz
Hallo, @Heinz Blättner > en.wikipedia.org/wiki/C_(programming_langua... Da steht doch genau das drin, was ich beschrieben habe. Welcher Teil widerspricht? (Bitte mal direkt gegenüberstellen) >> Also kann man ein "Array" (nicht nur ein Element!) doch nur als Pointer >> übergeben. > Das ist der default Fall > Mit etwas Aufwand... Das hat dann aber nicht mehr viel mit Array-Parametern/-Rückgabewerten zu tun, sondern ist typunabhängig. In Deinem Bsp. von heute 18:59 hast Du selbst gezeigt: Array "Folge[]" ist zuweisungskompatibel zu Pointer (uint*) "liste". Tschü Dude
@12er Dude (Gast) >> en.wikipedia.org/wiki/C_(programming_langua... >Da steht doch genau das drin, was ich beschrieben habe. Welcher Teil >widerspricht? (Bitte mal direkt gegenüberstellen) However, there is a distinction to be made between arrays and pointer variables. Even though the name of an array is in most expression contexts converted to a pointer (to its first element), this pointer does not itself occupy any storage. Consequently, you cannot change what an array "points to", and it is impossible to assign to an array. >>> Also kann man ein "Array" (nicht nur ein Element!) doch nur als Pointer >>> übergeben. >> Das ist der default Fall >> Mit etwas Aufwand... >Das hat dann aber nicht mehr viel mit Array-Parametern/-Rückgabewerten >zu tun, sondern ist typunabhängig. typunabhängig ??? >In Deinem Bsp. von heute 18:59 hast Du selbst gezeigt: >Array "Folge[]" ist zuweisungskompatibel zu Pointer (uint*) "liste". Ist nicht von mir
12er Dude wrote: > Wie oben schon geschrieben: > Eine "Array"-Variable in "C" ist doch immer ein Zeiger (auf das erste > Element). Vorsichtig ausgedrückt: NEIN NEIN UND NOCHMAL NEIN! :-) Vektoren sind keine Zeiger!
1 | int Vektor[100]; |
2 | int *Zeiger_auf_Vektor = Vektor; |
3 | int **Zeiger_auf_Zeiger_auf_Vektor = &Zeiger_auf_Vektor; |
4 | |
5 | int **Kein_Zeiger_auf_Zeiger_auf_Vektor = &Vektor; |
http://www.lysator.liu.se/c/c-faq/c-2.html
Hallo, @ Sven P. Schau Dir bitte den Verlauf des Thread und nicht nur die letzten Postings an. Zu klären ist, wie ein Array zurück-/übergeben wird. Die von Dir gezeigten Zusammenhänge sind mir schon geläufig.
1 | int Vektor[100]; |
2 | int *Zeiger_auf_Vektor = Vektor; |
3 | // "Zeiger_auf_Vektor" zeigt nicht auf Vektor, sondern auf &(Vektor[0])
|
4 | int *Zeiger_auf_Vektor = &Vektor; |
5 | // geht zur Not auch, bringt nichts, wie oben
|
"Vektor" ist (und bleibt) für den Compiler ein i m p l i z i t e r Zeiger, der aber selbst keine Adresse besitzt und daher nicht im Speicher zu finden ist. Also kann man seinen Wert nutzen/zuweisen (Adresse, auf die er zeigt), oder ihn derefernzieren. Tschü Dude
12er Dude wrote: > "Vektor" ist (und bleibt) für den Compiler ein i m p l i z i t e r > Zeiger, der aber selbst keine Adresse besitzt und daher nicht im > Speicher zu finden ist. Also kann man seinen Wert nutzen/zuweisen > (Adresse, auf die er zeigt), oder ihn derefernzieren. Trotzdem solltest du vorsichtig sein mit der Aussage, dass ein Array ein Zeiger ist. Denn genau das ist es nicht. Ein Array ist ein Array. Ein Zeiger ist ein Zeiger. In manchen Fällen degeneriert ein Array zu einem Zeiger auf sein erster Element. Aber ein Array ist KEIN Zeiger.
12er Dude wrote: > Hallo, > > @ Sven P. > Schau Dir bitte den Verlauf des Thread und nicht nur die letzten > Postings an. Zu klären ist, wie ein Array zurück-/übergeben wird. Schau Dir bitte den Verlauf des Threads an und nicht nur die letzten Postings. Dann fällt Dir nämlich auf, dass bereits die zweite Antwort hier von mir stammt und das Problem mit dem Codefetzen beschreibt. Ist zwar keine Antwort auf dem Silbertablett, aber etwas Mitdenken darf man wohl erwarten. Zumal im Post vor mir schon eine mögliche und übliche Lösung gegeben wurde. > Die von Dir gezeigten Zusammenhänge sind mir schon geläufig. Sah aber nicht danach aus. Ein Vektor ist und bleibt ein Vektor. Karl heinz Buchegger hat das richtig beschrieben.
Hallo, ich bin nicht allein ;) http://books.google.de/books?id=vhOsStUNcnAC&pg=PA70&lpg=PA70&dq=impliziter+zeiger&source=bl&ots=63zHXg2MQm&sig=KlVoZDfX0nSwrtonZz9YRAFEkYA&hl=de&ei=hxfaScPTEJnU-Qab5MXMBQ&sa=X&oi=book_result&ct=result&resnum=4 Und bitte das Wort "implizit" beachten. Tschü Dude
12er Dude wrote: > Hallo, > > ich bin nicht allein ;) > http://books.google.de/books?id=vhOsStUNcnAC&pg=PA70&lpg=PA70&dq=impliziter+zeiger&source=bl&ots=63zHXg2MQm&sig=KlVoZDfX0nSwrtonZz9YRAFEkYA&hl=de&ei=hxfaScPTEJnU-Qab5MXMBQ&sa=X&oi=book_result&ct=result&resnum=4 > > Und bitte das Wort "implizit" beachten. > > Tschü Dude Ich nehme an du meinst den Satzteil "... Zeigerarray ist, wie bei anderen Arrays auch, ein impliziter Zeiger ..." Nun, er ist dort genauso falsch wie bei dir. Ein Array ist kein Zeiger. Noch nicht mal implizit. Warum wir so darauf herumreiten? Na dann erklär doch mal mit deinem impliziten Zeiger, wo denn hier das Problem liegt: file1.c *******
1 | int Test[5]; |
2 | |
3 | int main() |
4 | {
|
5 | foo(); |
6 | |
7 | printf( "%d\n", Test[2] ); |
8 | }
|
file2.c *******
1 | extern int* Test; |
2 | |
3 | void foo() |
4 | {
|
5 | Test[2] = 5; |
6 | }
|
Ein Array ist kein Zeiger und ein Zeiger ist kein Array. Ein Array kann unter bestimmten Umständen zu einem Zeiger auf die Adresse des ersten Array-Elementes degenerieren. Aber: Das bedeutet nicht, dass es ein Zeiger IST! Die Umwandlung in die erste Elementadresse wird rein durch die Verwendung des Arrays ausgelöst und durch sonst gar nichts. Die Verwendung der Wörter 'Array', 'Zeiger' und 'ist' in ein und demselben Satz ist zumindest problematisch bis oft einfach nur falsch. Im besten Fall ist es für den geneigten Leser einfach nur missverständlich oder verwirrend, so dass dieser Satz am Besten so nie gefallen wäre. Mit dem gleichen Recht könnte ich auch sagen, dass ein int ein impliziter Zeiger ist, der nie irgendwo auftaucht. Denn natürlich führt der Compiler darüber Buch, wo im Speicher welche Variable liegt. In diesem Sinne ist praktisch alles ein 'impliziter Zeiger' (auch Funktionen). Das hilft aber niemandem weiter und erklärt nichts.
Hallo Karl heinz Buchegger, gut, dann beenden wir hier diese Haarspalterei. Auf einen grünen Zweig kommen wir wohl eh nicht. Und sorry an den OP, dass wir seinen Thread missbraucht haben. Tschü Dude
12er Dude wrote:
> Und sorry an den OP, dass wir seinen Thread missbraucht haben.
Ich denke das ist kein Problem.
Alles worauf Sven und ich hinaus wollen ist:
Sei vorsichtig, was du einem Neueinsteiger erzählst. Ich hab schon
mitgekriegt, dass du den Unterschied verinnerlicht hast und dass du
Arrays und Zeiger nicht verwechselst. Aber ein Neueinsteiger hört
'Array', 'Zeiger' und baut sich innerlich den Satz zusammen 'Ein Array
ist ein Zeiger'. Dass du den Satz ganz anders gemeint hast, überhört er.
Es bringt nichts, bei diesem Thema mit sprachlichen Feinheiten zu kommen
und das Wesentliche in ein einziges Wort 'implizit' zu legen. Diese
Botschaft kommt einfach nicht an.
Das hab ich oft genug auf comp.lang.c-c++ und Konsorten miterlebt. Bis
wir uns dort in der Community darauf geeinigt haben, solche Sätze schon
im Keim zu ersticken. Ab da lief es dann besser.
Feld gleich Zeiger? was passt hier nicht: [c] void schmafu (void) { int test[2]; int* ptest = test; int nochntest[2]; test++; ptest++; nochntest[]++; *test = 'a'; *ptest = 'b'; *(nochntest[]) = 'c'; *(nochntest[0]) = 'c'; } p.s.: als Anfänger hab ich sowohl Variante a als auch Variante b ohne Initialisierung des Zeigers probiert. b fand ich lustiger! c hab ich noch nicht probiert, aber das wär doch die Umsetzung der Aussage Array == Pointer?
> gut, dann beenden wir hier diese Haarspalterei. Auf einen grünen Zweig > kommen wir wohl eh nicht. Der Unterschied ist doch ziemlich deutlich: Ein Pointerarray braucht noch ein zusaetzliches Wort im Speicher (eben fuer den Pointer) und ein Array nicht, weil dessen Adresse fest ist. Ob 1 Wort (also z.B. 4 Bytes) jetzt weniger als ein Haar sind muss jeder selber wissen :) Einen groesseren Unterschied macht das in der Adressierung: Pointerarrays werden indirekt adressiert, Arrays direkt.
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.