Frage zu Bedingungen



  • Will mich mal hier an den Thread etwas anhängen....

    Ein 2 Dim Array könnte man auch so inintialisieren oder?
    Also funktionieren tut es bei mir, jetzt bin ich gespannt was alles "nicht soo" richtig ist... (Vor allem die Zuweisungen in Main ... )

    void fill2(int **arr, int zeile, int spalte){
    
    int i, j, value=2; 
    for (i=0; i<zeile; i++){
    	for(j=0; j<spalte; j++){
    	     *(*arr+(i*spalte)+j)=value;
    		value*=2;
    	}
    }
    
    }
    

    main.c

    int arr[3][3], *ptr;
    ptr=&arr[0][0];          //das ist irgendwie komisch....
    fill2(&ptr, 3, 3);
    

    Was für "kryptische" möglichkeite für 2Dim init gibt es noch so??



  • Nachtrag :
    Bietet der Doppelpointer irgendeinen Vorteil?

    MIt "einfach-Pointer" gings ja auch..

    void fill(int *arr, int zeile, int spalte){
    ...
    ...
    ..
    *(arr+(i*zeile)+j)=value++;
    ...
    


  • Das kommt darauf an, ob du das Argument typkompatibel zum Funktionsprototyp angibst.
    "Programm funktioniert bei mir..." ist jedenfalls kein Grund, von einem fehlerfreien Code auszugehen.
    Die Adresse sollte zwar (typunabhängig) meistens gleich sein (falls der Compiler nur eine feste Größe für alle Zeiger festlegt), entscheidend für UB oder nicht UB ist aber die Dereferenzierung bei Zeigern, und die ist eben für typinkompatible Zeiger wegen des auch noch zu berücksichtigenden Alignments (wird sehr oft wegen Unkenntnis vergessen) immer UB. (der Code kann funktionieren, muss es aber nicht...)

    int a[3][3], *ptr = &a[0][0];
    
    fill(int *a);
    OK: fill(&a[0][0])
    
    fill(int **a);
    OK: fill(&ptr)
    UB: fill(&a[0][0]);
    UB: fill(a);
    UB: fill(ptr);
    UB: fill(&a[0]);
    

    Das ganze Zeugs kannst du aber immer umgehen, wenn die 2.Dimension abwärts jeweils zur Compilezeit bekannt ist, so wie in deinem Fall, also:

    int a[3][3];
    
    fill(int a[3][3]);
    OK: fill(a);
    fill(int a[][3]);
    OK: fill(a);
    fill(int a[12345][3]);
    OK: fill(a);
    fill(int (*a)[3]);
    OK: fill(a);
    


  • "Programm funktioniert bei mir..." ist jedenfalls kein Grund, von einem fehlerfreien Code auszugehen.

    ... da kann ich ein Lied von singen 🙂

    Was ist die "beste" oder "eleganteste" Möglichkeit ein 2D Array zu übergeben und zu füllen?



  • Ps.:
    Was ist bei:

    fill(int *a);
    OK: fill(&a[0][0])
    

    mit

    int *ptr;
    ptr=&arr[0][0];
    fill(ptr);
    

    Kein UB ...?



  • Noch was...

    Wutz schrieb:

    Das ganze Zeugs kannst du aber immer umgehen, wenn die 2.Dimension abwärts jeweils zur Compilezeit bekannt ist, so wie in deinem Fall, also:

    int a[3][3];
    
    fill(int a[3][3]);
    OK: fill(a);
    fill(int a[][3]);     // Hier muss ich noch die Zeilen mit übergeben ?
    OK: fill(a);
    fill(int a[12345][3]);
    OK: fill(a);
    fill(int (*a)[3]);    // Hier ebenfalls #??
    OK: fill(a);
    


  • SAKRA SAKRA... Das Theme ist ja hochinteressant...

    Ist folegendes dann richtig??? Also man kann das bestimmt schönter, besser machen...

    void fill3(int (*arr)[3], int zeilen){         //ptr 2 an array of 3 int
    	int i, j;
    	int value=15; 
    
    	for(i=0; i<zeilen; i++){
    		for(j=0; j<3; j++){
    			//arr[i][j]=value++;
    			  (*arr)[j]=value++;   //gibt es eine Variante ganz ohne Index????
    		}
    	   arr++;	
    	}
    
    }
    

    ...Das waren jetzt viele Fragen, bin mal gespannt...



  • typedef struct {int a[3];} A3; /* Hilfstyp für blockweise int-Zuweisung */
    
    void fill3(int (*arr)[3], int zeilen)
    {
      A3 a={1,2,3};
      while( zeilen-- )
        *(A3*)arr[zeilen]=a;
    }
    void fill4(int (*arr)[3], int zeilen)
    {
      A3 a={1,2,3};
      while( zeilen-- )
        *(A3*)*arr++=a;  /* ganz ohne 'Index' */
    }
    


  • Wutz schrieb:

    typedef struct {int a[3];} A3; /* Hilfstyp für blockweise int-Zuweisung */
    
    void fill3(int (*arr)[3], int zeilen)
    {
      A3 a={1,2,3};
      while( zeilen-- )
        *(A3*)arr[zeilen]=a;
    }
    void fill4(int (*arr)[3], int zeilen)
    {
      A3 a={1,2,3};
      while( zeilen-- )
        *(A3*)*arr++=a;  /* ganz ohne 'Index' */
    }
    

    Ahhh...ja.
    Nicht von schlechten Eltern. Ich bin mir nicht ganz sicher ob ich das jetzt so kapiert habe...

    (A3)... =>castet das arr??



  • So ein Cast ist üblich für die struct-content-copy Zuweisung in ANSI C.
    Mit C99 und compound statements ginge das nochmal kürzer:

    void fill4(int (*arr)[3], int zeilen)
    {
      while( zeilen-- )
        *(A3*)*arr++=(A3){1,2,3}; /* ganz ohne 'Index' */
    }
    


  • Gehört der * nach (A3*) noch zum cast?

    Also

    (A3)*arr++=a;
    ------^ der hier? so quasi der Wert von A3 castet arr ist a ??


Anmelden zum Antworten