dynamische arrays und pointer



  • Hallo,

    Ich komm gerade nicht weiter. Aufgabe ist es :

    Der Funktion filter werden ein Zeiger auf ein Array von Integer-Werten als Parameter values, sowie die Größe des Arrays als Integer-Parameter size übergeben.
    Aus diesem Array sollen alle Werte ausgewählt werden, bei denen das Bit an der durch pos angegebenen Bitposition gesetzt ist(d.h. den Wert 1 hat).
    Hierbei soll die Zählung mit der höchstwertigsten Bitposition der Zahl beginnen.
    Die ausgewählten Werte sollen über den Rückgabeparameter result als neu angelegtes Array an die aufrufende Funktion übergeben werden. Die Größe des neuen Arrays soll zudem als Rückgabewert der Funktion zurückgegeben werden. Die Anzahl der Bits lässt sich Plattformunabh durch sizeof(int)*8 bestimmen.

    Funktion:

    unsigned int filter(unsigned int pos, int *values, unsigned int size, int **result)
    

    So und ich hab schon mal überlegt, dass ich in der main erstmal ein beispiel array anlege

    a[]= {1,2,3};
    

    danach dann diese durch

    filter(4, a, sizeof(a)/sizeof(int),...)
    

    übergebe. Ich muss aber noch in filter speicher reservieren mit malloc und die bitposition bestimmen, das habe ich auch noch nicht ganz verstanden. Desweiteren brauch ich wahrscheinlich noch eine Hilfsfunktion, der ein neues Array anlegt und es an filter übergibt.

    Bitte um Rat:)



  • Xeno1987 schrieb:

    werden ein Zeiger auf ein Array von Integer-Werten als Parameter values,

    Wo ist der Parameter für einen Zeiger auf ein int-Array deklariert?

    Xeno1987 schrieb:

    Die Anzahl der Bits lässt sich Plattformunabh durch sizeof(int)*8 bestimmen.

    Auch wieder falsch. Hat dir dein Professor das so vorgegeben?



  • hallo

    also der Funktionskopf filter wurde uns so exakt vorgegben als auch das mit sizeof*8, was ich aber anders kenne mit sizeof(variable)/sizeof(int).

    das array muss ich selber erst mal in der main erzeugen und an value übergeben, wenn ich die aufgabe richtig verstanden habe.



  • Wie wärs erstmal mit so etwas in der Art, ohne malloc und co:

    unsigned int filter ( unsigned pos, int *values, unsigned size, int *result )	
    {
    	unsigned i, j=0;
    	for ( i = 0; i < size; i++ );
    	{
    
    		if ( ... ) // Wenn Bit an pos in values[i] gesetzt
    		{
    			result[j] = values[i]; 
    			j++;
    		}
    	}
    	return j;
    }
    int main(void)
    {
    	int a[] = {1,2,3};
    	int result [ sizeof(a) / sizeof(*a) ];
    	int pos = 4;
    	unsigned anzahl_gefilterter_integer = filter ( pos, a, sizeof(a) / sizeof(*a), result );
    }
    


  • Wutz schrieb:

    Xeno1987 schrieb:

    Die Anzahl der Bits lässt sich Plattformunabh durch sizeof(int)*8 bestimmen.

    Auch wieder falsch. Hat dir dein Professor das so vorgegeben?

    Was ist daran denn bitte falsch? Der Satz ist richtig, denn sizeof gibt die Größe in Bytes des übergebenen Datentyps bzw. des Datentyps der übergebenen Variable zurück (mit Ausnahme statisch deklarierter Arrays) und 8 Bit sind ein Byte. Du hast den Kontext vielleicht missverstanden, weil damit die Bit-Größe eines Elements des Arrays bestimmt werden soll, was im Nachhinein relevant ist.

    Wutz schrieb:

    Xeno1987 schrieb:

    werden ein Zeiger auf ein Array von Integer-Werten als Parameter values,

    Wo ist der Parameter für einen Zeiger auf ein int-Array deklariert?

    Xeno1987 schrieb:

    a[]= {1,2,3};
    

    Deiner Array-Definition fehlt noch der Datentyp.

    Xeno1987 schrieb:

    Ich muss aber noch in filter speicher reservieren mit malloc und die bitposition bestimmen, das habe ich auch noch nicht ganz verstanden. Desweiteren brauch ich wahrscheinlich noch eine Hilfsfunktion, der ein neues Array anlegt und es an filter übergibt.

    Das Bit eines Array-Elements kannst du mit einer Bitmaske überprüfen, welche du mit Bit-Verschiebung erstellst. Speicher musst du in filter gar nicht reservieren. Den Ausgabe-Array erstellst du an gleicher Stelle und mit gleicher Größe wie den Eingabe-Array und übergibt dessen Adresse (siehe Referenzen) an filter.

    Xeno1987 schrieb:

    Bitte um Rat:)

    Die Aufgabenstellung ist ziemlich klar und genauere Erklärungen würden der Lösung zu nahe kommen, daher stelle bitte die richtigen Fragen und vermeide die "keine Ahnung, erklärt mal alles"-Richtung.





  • Youka schrieb:

    Wutz schrieb:

    Xeno1987 schrieb:

    Die Anzahl der Bits lässt sich Plattformunabh durch sizeof(int)*8 bestimmen.

    Auch wieder falsch. Hat dir dein Professor das so vorgegeben?

    Was ist daran denn bitte falsch? Der Satz ist richtig, denn sizeof gibt die Größe in Bytes des übergebenen Datentyps bzw. des Datentyps der übergebenen Variable zurück (mit Ausnahme statisch deklarierter Arrays) und 8 Bit sind ein Byte. Du hast den Kontext vielleicht missverstanden

    Ich nicht aber du. Du hast keine Ahnung, wovon du redest.

    Youka schrieb:

    Wutz schrieb:

    Xeno1987 schrieb:

    werden ein Zeiger auf ein Array von Integer-Werten als Parameter values,

    Wo ist der Parameter für einen Zeiger auf ein int-Array deklariert?

    Xeno1987 schrieb:

    a[]= {1,2,3};
    

    Deiner Array-Definition fehlt noch der Datentyp.

    Und wieder hast du keine Ahnung wovon du redest.
    a ist hier definiert als Array und nicht als Zeiger auf ein Array wie oben genannt. Lesen kannst du auch nicht.



  • @Wutz
    Hast du in deinen letzten >2.6k Beiträgen auch nur rumgemault statt zu helfen?
    Gib mal vernünftige Antworten, wo ich oder andere genau falsch liegen, und halt dich mal mit deiner beleidigenden Art zurück.



  • hallo leute,

    habe mich heute nochmal damit beschäftigt und habe das problem mit der position jetzt hinbekommen. Jetzt hackst bei mir mit den pointer.
    Hier mal meine korrigierte Version:

    #include <stdio.h>
    #include <stdlib.h>
    
    unsigned int filter(unsigned int pos, int *values, unsigned int size, int **result){
    
       for(unsigned int i = sizeof(int)*8;i > 0;i--){
    
          if(pos&1){
    
             **result = values[i];
             printf("pos: %d\n", i);
          }
          pos = pos >> 1;
    
       }
    
    return 0;
    
    }
    
    int main(int argc, char **argv){
    
    unsigned int source[] = {1, 2, 3, 4 ,5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
    
    unsigned int *destination;
    
    destination = (unsigned int*) malloc(sizeof(source));
    //printf("destination size: %d\n", sizeof(destination));
    
    filter(4, source, 4, **destination);
    
    }
    


  • so hier noch mal die pointer korrigierte version, spuckt aber nicht das aus was aufgabe war.

    #include <stdio.h>
    #include <stdlib.h>
    
    unsigned int filter(unsigned int pos, int *values, unsigned int size, int **result){
    
       for(unsigned int i = size;i > 0;i--){
    
          if(pos&1){
    
             **result = values[i];
             printf("pos: %d\n", i);
          }
          pos = pos >> 1;
    
       }
    for(int i = 0; i <= sizeof(result); i++){
    
       printf("Werte: %d\t", **result);
    }
    return 0;
    
    }
    
    int main(int argc, char **argv){
    
    int source[] = {1, 2, 3, 4 ,5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
    
    int **destination;
    
    destination = (int**) malloc(sizeof(source));
    //printf("destination size: %d\n", sizeof(destination));
    
    filter(7, source, 32, destination);
    
    }
    


  • Xeno1987 schrieb:

    ..., **destination); /* LOL */
    
    }
    

  • Mod

    Nun, entweder machst du es, wie es richtig ist, d.h.

    unsigned int filter(unsigned int pos, const int *values, unsigned int size, int *result);
    

    oder du machst es so wie dein Lehrer (falsch) vorgibt, also

    unsigned int filter(unsigned int pos, int *values, unsigned int size, int **result)
    

    .
    Beides gleichzeitig geht nicht.

    Außerdem scheinst du noch folgende Dinge nicht verstanden zu haben und solltest sie dir nochmal angucken:
    - Dereferenzierung und Adressoperator (sehr wichtig! Falsch benutzt in Zeilen 11, 20)
    - Felder (wichtig! Falsch benutzt in Zeilen 11, 18, 20, 31, 33)
    - Implizite Konvertierungen zwischen Pointertypen. Wann greifen sie, wann nicht? (nicht ganz so dringend. Falsch benutzt in 33)
    - Bitmanipulation (für diese Aufgabe sehr wichtig! Falsch benutzt in 9-14)
    - erstaunlicherweise Schleifen und andere Kontrollstrukturen (absolute Grundlagen für alles! Falsch benutzt in 7-22)



  • hi,

    das mit den bits überprüfen stimmt aber so, Weiss ich nicht was du meinst. das mit dem dereferenzieren war so gewollt, da ich die neuen werte in das neue array schreiben soll.


  • Mod

    Xeno1987 schrieb:

    das mit den bits überprüfen stimmt aber so, Weiss ich nicht was du meinst. das mit dem dereferenzieren war so gewollt, da ich die neuen werte in das neue array schreiben soll.

    Komisch, wieso es nicht funktioniert, obwohl doch alles richtig ist. Findest du nicht?



  • hi,

    ja da hast du recht, aber ich würd mich um unterstützung freuen.


  • Mod

    Xeno1987 schrieb:

    hi,

    ja da hast du recht, aber ich würd mich um unterstützung freuen.

    Eigentlich hatte ich gedacht, eine Auflistung der Fehler wäre Unterstützung. Mach dich über die angesprochenen Themen schlau, sonst verstehst du unsere Antworten nicht. Teile die Funktionalität auf, die du zur Problemlösung benötigst, so dass du die einzelnen Teile der Lösung unabhängig testen kannst. Derzeit merkst du gar nicht, dass dein Bitgefummel falsch ist, da du das falsche Ergebnis nicht aus der Funktion heraus bekommst.

    Daher konkrete Vorschläge:
    -Schreibe eine Funktion int get_bit(unsigned int value, unsigned int pos) , die dir zurück gibt, ob das pos'te Bit in value gesetzt ist oder nicht (Ruckgabewert 0 (ungesetzt) oder nicht 0 (gesetzt)).
    -Teste diese Funktion ausgiebig!
    -Schreibe eine Funktion void filter(unsigned int* values, unsigned int size, unsigned int pos) , die dir alle Werte aus values auf dem Bildschirm ausgibt, bei denen das pos'te Bit gesetzt ist.
    -Teste diese Funktion ausgiebig!

    Das ist dann schon einmal die halbe Miete. Danach musst du die oben von mir erwähnte Entscheidung treffen, ob du es machst wie vom Lehrer verlangt oder so wie man es richtig machen würde. Bis dahin ist es aber noch eine Weile hin, denn ich denke für die beiden beschriebenen Funktionen wirst du einiges an Zeit brauchen.



  • Schreib auch noch eine Funktion
    void print(const int * base, size_t nmemb);
    Diese gibt ein Array von nmemb ints aus. base zeigt auf den ersten dieser ints.

    Nach Diktat in den Biergarten gegangen.



  • so hab die erste function fertig und auch erfolgreich getestet.
    die zweite mach ich gleich auch noch.

    #include <stdio.h>
    #include <stdlib.h>
    
    int get_bit(unsigned int value, unsigned int pos){
    
       if(value & (1<<pos)) return 1;
    
    return 0;
    
    }
    
    int main(int argc, char **argv){
    
    printf("test: %d\n", get_bit(15,7));
    
    }
    

  • Mod

    Sieht ok aus. Nächste!



  • so die zweite habe ich auch hinbekommen. Wenn ich die Aufgabe richtig verstanden habe, soll das program gucken, ob bei pos z.b. pos = 7 sind binary gesehen von rechts MSB angefangen 0, 1 ,2 position gesetzt also hol dir vom array die werte an genau diesen positionen und gib sie aus.

    #include <stdio.h>
    #include <stdlib.h>
    
    void filter(unsigned int *values, unsigned int size, unsigned int pos){
    
       for(unsigned int i = size-1;i > 0;i--){
    
          if(pos&1){
    
             printf("Werte: %d\nPosition: %d\n", values[i], i);
          }
          pos = pos >> 1;
    
       }
    
    }
    
    int main(int argc, char **argv){
    
    unsigned int val[] = {5, 20, 18, 45, 50};
    filter(val, 5, 8);
    
    }
    


  • warum veränderst du pos?
    was hat if(pos&1) mit dem array inhalt zu tun?


Anmelden zum Antworten