Array-Übergabe an Funktion call-by-ref
-
Ich bin mittlerweile auf dieser Seite des Buches angekommen und würde gerne eine Funktion schreiben, die eine Art Schachfeld erstellt (ohne Inhalt). Wenn ich diese Funktion aufrufe, soll diese eben in bestimmte Array-Felder - das Array möchte ich per Adresse übergeben - mit '|'' ' und '+' ein Feld gezeichnet werden.
Soweit so gut. Leider gibt mir folgender Quelltext jeweils beim Aufruf "array..." eine Fehlermeldung aus, dass ich die Grenzen des Arrays nicht gültig definiert habe.
Warum also übernimmt die Funktion nicht die Werte aus FELDERx und FELDERy bzw. warum akzeptiert er x und y nicht als Grenzen in der Funktion?#include <stdio.h> #include <stdlib.h> #define FELDERx 8 #define FELDERy 8 //Funktion um Rahmenelemente im Array zu initialisieren void field (char array[][], int anzahly, int anzahlx) { int d, x, y; for (y=0; y<=anzahly; y++) { d=y; if(d&1) { for (x=0; x<=anzahlx; x=x+3) { array[y][x]='|'; } for (x=1; x<=anzahlx-1; x=x+3) { array[y][x]=' '; array[y][x+1]=' '; } } else { for (x=0; x<=anzahlx; x=x+3) { array[y][x]='+'; } for (x=1; x<=anzahlx-1; x=x+3) { array[y][x]='-'; array[y][x+1]='-'; } } } } int main() { char SFeld[FELDERy][FELDERx]; int x,y; // Aufruf der Funktion "field" um Feld zu erstellen. field(SFeld, FELDERy, FELDERx); // Feld z.K. anzeigen. for (y=0; y<=FELDERy; y++) { for (x=0; x<=FELDERx; x++) { printf("%c", SFeld[y][x]); } printf("\n"); } return 0; }
-
Hör auf dieses Buch zu lesen, bevor es zu spät für dich ist. Jürgen Wolf ist ein Pfuscher, der aus Unwissen viele falsche Dinge in seine Bücher schreibt. Es fällt Leuten sehr schwer, dieses Falschwissen hinterher wieder zu verlernen und führt zu viel Frust.
-
Bei einem 1-Dim-Array char SArray[FELDERx]; berechnet der Compiler die Adresse der Speicherstelle für das Element x als
SArray+x
Bei deinem Feld
char SFeld[FELDERy][FELDERx];
berechnet der Compiler die Adresse der Speicherstelle für das Element x,y alsSFeld + FELDERy*y + x
In main hat der Compiler noch die Kentnisse über die Größe des Feldes.
Da bei deinen Parametern für field aber keine Angaben zu FELDERy gibt, kann der Compiler das auch nicht berechnen.
void field (char *array, int anzahly, int anzahlx) { int d, x, y; // statt array[y][x] schreibst du jetzt *(array+anzahly*y+x) .... }
-
@SeppJ: gescheite Alternative? -> bin relativ resistent gegenüber Frustration
@Dirk:
Habe jetzt ganz stupide *array als Parameter eingesetzt: main.c:27: error: subscripted value is neither array nor pointerzu deiner Erklärung:
Heißt das, beim Ein-Dim-Array funktioniert es, weil er einfach die nächste Speicherstelle von der Adresse aus nimmt - beim Zwei-Dim-Array aber nicht, weil er nicht weiß wo die zweite "Dimension" beginnt oder er überhaupt nicht weiß was er mit der Adresse anfangen soll?
-
Genau.
Was noch geht ist
void field (char array[FELDERy][], int anzahly, int anzahlx) { ....
Dann weiß der Compiler über die zweite Dimension bescheid.
201 schrieb:
Habe jetzt ganz stupide *array als Parameter eingesetzt: main.c:27: error: subscripted value is neither array nor pointer
Ich weiß zwar nicht wo du das eingesetzt hast, aber lass doch mal den * weg. (Oder poste ein Beispiel)
Hast du dich schon mit *argv[] (dem 2. Parameter von main()) auseinandergesetzt?
-
DirkB schrieb:
Was noch geht ist
void field (char array[FELDERy][], int anzahly, int anzahlx) { ....
Dann weiß der Compiler über die zweite Dimension bescheid.
Das klappt so nicht. Du kannst nur die äußerste Dimension weglassen:
void field(char array[][FELDERx], int anzahly, int anzahlx)
(und das ist gleichbedeutend mit
char (*array)[FELDERx]
)
-
void field (char array[FELDERy][], int anzahly, int anzahlx) { int d, x, y; for (y=0; y<=anzahly; y++) { d=y; if(d&1) { for (x=0; x<=anzahlx; x=x+3) .............
Rudimentär. Ich weiß, dass argv[] Pointer auf Speicheradressen enthält, in denen dann die Parameter gespeichert sind die man übergibt. Aber das ist ja auch ein Ein-Dim-Array...
Achso, oben das funzt leider auch nicht...
Ich blick irgendwie nicht mehr durch: Ich übergebe ihm doch eine Adresse, dann zähle ich mit Hilfe von x und y hoch und er muss nichts anderes machen als in 1 Byte schritten weiter zu gehen. Oder übergebe ich ihm gar keine Adresse sondern eine Kopie?
-
Bashar schrieb:
Das klappt so nicht. Du kannst nur die äußerste Dimension weglassen:
Verdammt,
es heißt ja auchSFeld + FELDERx*y + x
FELDERx
*argv[] ist ein Array, dessen Elemente auf Speicherbereiche zeigen. Bei argv auf char.
argv kannst du auch über argv[1][0] ansprechen. Dann hast du das erste (0) Zeichen vom zweiten (1) Argument.
-
Ich blick irgendwie nicht mehr durch: Ich übergebe ihm doch eine Adresse, dann zähle ich mit Hilfe von x und y hoch und er muss nichts anderes machen als in 1 Byte schritten weiter zu gehen. Oder übergebe ich ihm gar keine Adresse sondern eine Kopie?
Dir wurde doch schon geraten das Buch weg zu schmeißen!
Dieser Beispielcode ist unter aller Kanone.
-
kk, aber könntet ihr mir noch ne Alternative sagen?
-
Ich würde Dir ja raten gleich C++ zu lernen.
Wenn es unbedingt C sein muss dann
schau mal hier
http://de.wikibooks.org/wiki/C-ProgrammierungIch sehe auch gerade das das Beispiel von Wolf (auf der verlinkten Seite) völlig anders gestrickt ist.
/* array10.c */ #include <stdio.h> #include <stdlib.h> #define MAX 10 void function(int feld[], int n_anzahl) { int i; for(i = 0; i < n_anzahl; i++) printf("%d; ", feld[i]); printf("\n"); } int main(void) { int val[MAX]; int i; for(i = 0; i < MAX; i++) val[i] = i+1; function(val, MAX); return EXIT_SUCCESS; }
Zunächst mal übergibt er ein 1-dimensionales Feld, und dann auch nur um es auf der Konsole auszugeben. Das ist also ein himmelweiter Unterschied zu dem was Du gebaut hast.
Vielleicht solltest Du beginnen zu Beschreiben was Du vor hast (ich meine im Detail).
-
Kernighan/Ritchie: The C Programming Language (ANSI C Version; 2.Auflage) (die Bibel von den Erfindern der Sprache, auch bekannt als K&RII; wenn dann die englische Version)
Prinz/Prinz: C - Einführung und professionelle Anwendung. (deutsch, Windows-lastig)
Prata: C Primer Plus (5th Edition) (auch nicht ganz fehlerfrei, aber besser als vieles andere)Es gibt in C übrigens kein call by reference, das ist Aberglaube.
Nur weil man einen Zeiger als call by value übergibt, ist es noch lange kein call by reference. Dein gewählter Beitragstitel lässt vermuten, dass du auch hierbei was Falsches gelernt hast.