Problem mit Adressierung im 2D-Gitter



  • Hallo zusammen,

    ich bin ein C-Neuling und bin auf ein Problem gestoßen, das ich bisher nicht lösen konnte. Vielleicht kann mir hierbei ja jemand weiterhelfen:

    Ich möchte ein 2D-Gitter erstellen. Hierbei gibt es eine i-Achse, eine j-Achse und eine Funktion id(i,j) die die i- und j-Werte verrechnet und jedem Wertepaar einen spezifischen Wert zuweist, sodass ich quasi die Wertepaare als einzelne Punkte abfragen kann. Das Problem ist nun folgendes: Ich möchte in einer for-Schleife ein Array füllen, in welchem für jedes Wertepaar am Rand des Gitters eine 1 und für jedes Wertepaar im Innern eine 0 an der durch id(i,j) festgelegten Stelle gespeichert wird. Wenn ich mir die Daten zum Schluss ausgeben lasse, kriege ich nur Nullen raus. Das Programm ist hier zu sehen:

    #include <stdio.h>
    #include <math.h>
    
    int imax=200;
    int jmax=200;
    
    long id(int i, int j){		
    	return ((j*(jmax+1))+i);
    }
    
    int main(){
    
    	int i, j;
    
    	long n_gitterpunkte=(imax+1)*(jmax+1);					
    	double rw_id[n_gitterpunkte];
    
    	for(i=0; i<=imax; i++){
    		for(j=0; j<=jmax;j++){
    
    			rw_id[id(i,j)]=0;	
    
    			if(i==0){							
    				rw_id[id(0,j)]=1;
    			}
    			if(i==imax){
    				rw_id[id(imax,j)]=1;
    			}
    			if(j==0){
    				rw_id[id(i,0)]=1;
    			}
    			if(j==jmax){
    				rw_id[id(i,jmax)]=1;
    			}
    
    		}
    	}
    
    	FILE *datei;
    	datei=fopen("Ausgabe.txt", "w");
    
    	fprintf(datei, "i\t j\t id\t randwert\n");
    	for(j=0;j<=jmax;j++){
    		for(i=0;i<=imax;i++){
    			fprintf(datei, "%.1i\t %.1i\t %.1i\t %.1i\n", i, j, id(i,j), rw_id[id(i,j)]);
    		}
    	}
    
    	fclose(datei);
    
    	return 0;
    }
    

    Hat jemand eine Idee?

    Vielen Dank im voraus!
    2D-Mann



  • Du gibst double mit %i aus.



  • Danke für die Antwort,

    ja, das stimmt, habe ich glatt übersehen. Das Problem besteht aber weiterhin, auch wenn ich keine Integer ausgeben lasse, da es sich bei der Ausgabe der Randwerte ja sowieso nur um Nullen und Einsen handelt.



  • Es hat sich bewährt nicht <= in Schleifen zu verwenden, sondern <. Mit <= verwirrst Du die Leute.

    Und für die Umrechnung von x,y Paaren in Indizes in einem eindimensionalen Feld nimmt man normalerweise, die etwas einfachere Formel yZeilenlänge+x
    *

    Dein Array ist übrigens ein VLA. Ein Variable length array. Das ist erstmal nicht schlimm (solange Wutz es nicht sieht...), aber wahrscheinlich Dir nicht bewusst.

    #include <stdio.h>
    
    #define XMAX 4
    #define YMAX 8
    #define idx(x,y) (y)*XMAX+(x)
    
    void create_border(double *arr, int xmax, int ymax){
      for(int x=0; x<xmax; ++x)
        arr[idx(x,0)] = arr[idx(x,ymax-1)] = 1.0;
      for(int y=0; y<ymax; ++y)
        arr[idx(0,y)] = arr[idx(xmax-1, y)] = 1.0;
    }
    
    void print(const double *arr, int xmax, int ymax){
      for(int y=0; y<ymax; ++y){
        for(int x=0; x<xmax; ++x)
          printf("%f ", arr[idx(x,y)]);
        puts("");
      }
    }
    
    int main(void){
      // ein normales Array, das ich gleich initialisiere
      double arr[XMAX*YMAX]={0.0};
    
      puts("Vorher:");
      print(arr, XMAX, YMAX);
    
      create_border(arr, XMAX, YMAX);
    
      puts("Nachher:");
      print(arr, XMAX, YMAX);
    }
    

    Und aktivier die Warnungen in Deinem Compiler. Den falschen Formatstring in Z. 46 muss Dein Compiler bemängeln.



  • 2D-Mann schrieb:

    Danke für die Antwort,

    ja, das stimmt, habe ich glatt übersehen.

    Bei der Gelegenheit hättest du eigentlich merken müssen, dass id auch long ist 😕 Es mag dich schockieren, aber dein Algorithmus macht das was er soll, nur die Ausgabe ist falsch.

    PS: Und bevor du jetzt denkst, damit wäre alles im Reinen: In id solltest du j * (imax + 1) + i haben, es klappt momentan nur, weil imax == jmax ist. Der Rest sind kosmetische Probleme.



  • Hallo Furble Wurble,

    erstmal danke für die Antwort. Ich hätte von vornherein vielleicht näher spezifizieren sollen, dass ich lediglich in C (ein wenig) programmieren kann, deinen Code kann ich leider nicht kompilieren, da er (laut Compiler) in C99 geschrieben zu sein scheint.

    Die logische Struktur deines Codes kann ich dennoch nachvollziehen, sieht natürlich wesentlich eleganter aus als bei mir. Allerdings stellt sich mir die Frage: Was habe ich konkret in meinem Code falsch gemacht? Denn auch hier ist für mich logisch alles nachvollziehbar, irgendetwas muss ich übersehen. An dem VLA (über den ich mir wirklich nicht bewusst war) kann es wohl nicht liegen? Und an der Integerausgabe statt Float wohl auch nicht, woran denn dann?



  • Problem gelöst, danke!


  • Mod

    2D-Mann schrieb:

    erstmal danke für die Antwort. Ich hätte von vornherein vielleicht näher spezifizieren sollen, dass ich lediglich in C (ein wenig) programmieren kann, deinen Code kann ich leider nicht kompilieren, da er (laut Compiler) in C99 geschrieben zu sein scheint.

    😕 Dein erster Code ist auch C99. Und nutz doch einfach C99, dein Compiler kann das ja offensichtlich. Oder gleich C11. Es ist schließlich nicht mehr 1989.



  • Du solltest lernen, Zeiger zu verwenden, anstatt die Adressierung umständlich über extra Konstrukte jedesmal auszurechnen.
    Sobald du konstante Bereiche hast, wie hier z.B. die konstant lange Zeile, kannst du mit Zeigern auf dieses konstante Array (ein Array ist immer konstant groß) arbeiten:

    enum{XY=20};
    
    int main(){
    
    int i,j,(*x)[XY]=calloc(50,sizeof*x);
    
    for(i=0; i<XY; i++)
      for(j=0; j<XY;j++)
        if(i==0||j==0||i==XY-1||j==XY-1)
          x[i][j]=1;
    
    for(i=0; i<XY; i++,puts(""))
      for(j=0; j<XY;j++)
        printf("%d",x[i][j]);
    
    free(x);
    
    return 0;
    }
    

    http://ideone.com/Er9wk0



  • Wutz schrieb:

    (ein Array ist immer konstant groß)

    amen.
    ⚠ das einzige was konstant ist, ist die varietät der konstanz. ⚠

    außderdem btw wohl noch nie was von dynamischen array gehört, wa?
    ***Link zensiert, weil Müll. SeppJ***



  • mr dynamic schrieb:

    Wutz schrieb:

    (ein Array ist immer konstant groß)

    amen.
    ⚠ das einzige was konstant ist, ist die varietät der konstanz. ⚠

    außderdem btw wohl noch nie was von dynamischen array gehört, wa?
    ***Link zensiert, weil Müll. SeppJ***

    Alleine schon für die Verlinkung von diesem Schund (bei 14.5 wird free(3) erklärt, aber hier bei 14.7 wird es nicht verwendet) gehört dein Beitrag entfernt.



  • Deppen, die ahnungslos irgendwas nachplappern und irgendwelchen Netzmüll als gottgegeben ansehen, gibt es leider überall. Und leider nicht nur im pubertierenden Alter.


Anmelden zum Antworten