C Onlinetest: Listenoperationen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • C Onlinetest: Listenoperationen

    Hallo, ich möchte in diesem Thread Fragen bezüglich dem Onlinetest am Montag klären und Probleme mit dem 3. Übungsblatt diskutieren.

    Hier meine bisherige Lösung zur ersten Aufgabe. Bis auf copy und custom snd alle Funktionen implementiert und eine kleine main testet diese. Was mir noch nichtklar ist, ist die custom Funktion. Was macht diese und soll sie inkludiert werden oder muss man sie implementieren?
    Des Weiteren frage ich mich, wie man mit dem "void-Inhalt" umgehen soll, sobald er ausgegeben wird, da man ja gar nicht weiß, welche Inhalte in der Liste gespeichert sind.

    Hier erst mal der code, soweit ich ihn habe:

    Quellcode

    1. #include<stdlib.h>
    2. #include<stdio.h>
    3. typedef struct _node{
    4. int *content;
    5. struct _node *prev;
    6. struct _node *next;
    7. } node;
    8. const int nsize = sizeof(node);
    9. node* add( node *firstnode, void *cont ) {
    10. node *newnode = malloc( nsize );
    11. newnode->content = cont;
    12. if( firstnode == NULL ) { /*Wenn Liste leer*/
    13. newnode->prev = NULL;
    14. newnode->next = NULL;
    15. return newnode;
    16. }
    17. else{ /*fuege in bestehende Liste ein*/
    18. newnode->next = firstnode;
    19. newnode->prev = NULL;
    20. firstnode->prev= newnode;
    21. return newnode;
    22. }
    23. }
    24. node* add_ith( node *firstnode, void *cont, int pos ) {
    25. int i;
    26. node *newnode = malloc( nsize );
    27. newnode->content = cont;
    28. node *itnode = firstnode; /*suche i-1te Position*/
    29. for( i=1 ; i< pos-1 ; i++ ) {
    30. itnode = itnode->next;
    31. }
    32. if( itnode == NULL) /*Position ausserhalb, nicht einfuegen*/
    33. return firstnode;
    34. else{
    35. newnode->next = itnode->next; /*fuege neuen Knoten ein*/
    36. newnode->prev = itnode;
    37. newnode->next->prev = newnode;
    38. itnode->next = newnode;
    39. return firstnode;
    40. }
    41. }
    42. node* add_last( node *firstnode, void *cont ){
    43. node *newnode = malloc( nsize );
    44. newnode->content = cont;
    45. node *itnode = firstnode; /*suche letzten Knoten*/
    46. while( itnode->next != NULL ) {
    47. itnode = itnode->next;
    48. }
    49. itnode->next = newnode;
    50. newnode->prev = itnode;
    51. newnode->next = NULL;
    52. return firstnode;
    53. }
    54. node* del( node *firstnode){
    55. if( firstnode == NULL || firstnode->next == NULL) /*Wenn kein oder nur ein Konten vorhanden*/
    56. return NULL;
    57. else{
    58. node *newfirstnode = firstnode->next;
    59. newfirstnode->prev = NULL;
    60. free(firstnode);
    61. return newfirstnode;
    62. }
    63. }
    64. node* del_ith( node *firstnode, int pos ){
    65. int i;
    66. node *itnode = firstnode;
    67. for( i=1 ; i< pos-1 ; i++ ){ /*suche i-1te Position*/
    68. itnode = itnode->next;
    69. }
    70. if( itnode == NULL || itnode->next == NULL) /*wenn knoten nicht vorhanden*/
    71. return firstnode;
    72. else{
    73. node *delnode = itnode->next; /*merke zu loeschenden Knoten*/
    74. itnode->next = delnode->next;
    75. delnode->next->prev = itnode;
    76. free(delnode);
    77. return firstnode;
    78. }
    79. }
    80. node* del_last( node *firstnode){
    81. node *itnode = firstnode;
    82. while( itnode->next->next != NULL ) /*suche vorletzten Knoten*/
    83. itnode = itnode->next;
    84. free(itnode->next);
    85. itnode->next = NULL;
    86. return firstnode;
    87. }
    88. void del_all( node *firstnode ) {
    89. node *delnode = firstnode;
    90. while( firstnode->next != NULL ){
    91. firstnode = firstnode->next;
    92. free( delnode );
    93. delnode = firstnode;
    94. }
    95. free( delnode );
    96. }
    97. int main(void){
    98. int i1 = 0;
    99. int i2 = 1;
    100. int i3 = 2;
    101. void *eins = &i1;
    102. void *zwei = &i2;
    103. void *drei = &i3;
    104. node *dvlist = NULL;
    105. dvlist = add(dvlist,eins);
    106. dvlist = add(dvlist,zwei);
    107. dvlist = add_ith(dvlist,drei,2);
    108. printf("%d,%d,%d\n", *(dvlist->content), *(dvlist->next->content), *(dvlist->next->next->content));
    109. del_all(dvlist);
    110. return 1;
    111. }
    Alles anzeigen
    >: 4 8 15 16 23 42
  • Hi,
    grundsätzlich ist es schonmal schweinegefährlich in der Liste nur Zeiger auf den Inhalt zu halten.Da besteht immer die Gefahr dass der Zeiger im Laufe des Programms ungültig wird.
    Ansonsten sieht es so aus dass durch denn void* Typ die Listenverwaltungsfunktionen nen generischen Character bekommen sollen.
    Dann muss der C Programmierer natürlich schon einiges an Disziplin mitbringen und wirklich nur Daten in die Liste schieben die dem aktuellen Typ von _node->content entsprechen.Durch reines austauschen des Typs von node->content ist diese Listenimplementierung auch für andere Typen verwendbar(zumindest soweit ich dass auf die Schnelle überflogen habe).
    Was soll denn custom sein?

    Gruß void
    "Probleme kann man niemals mit derselben Denkweise lösen,
    durch die sie entstanden sind." (A. Einstein)
  • Es handelt sich hierbei um eine Aufgabe der Lehrveranstaltung Programmieren 3. Ziel ist eine dopelt verkettete Liste mit beliebigem Datensatz (Zeiger auf void). Da ist mir auch schon ein Fehler aufgeallen:

    In dem _node Struct müsste natürlich: "void *content" stehen.
    Habe nur zum ausprobieren int angegeben. Daher ergibt sich auch das Problem mit dem vaiablen Inhalt der Liste.
    Was die Custom-Funktion bewirken soll ist mir leider auch nicht klar, daher frage ich ja. Falls es dich interssiert, kannst du dir die Aufgabe hier ansehen:

    http://www.mi.fh-wiesbaden.de/~barth/prog3/prakt/Prog3PraktPB3.pdf
    >: 4 8 15 16 23 42
  • Naja,
    für del_all_custom ist custom nen Funktionszeiger auf ne beliebige Funktion die nen void Zeiger entgegen nimmt und void zurück gibt.
    Kennst du for_each und transform aus C++? Prinzipiell sollen die Funktionen del_all_custom und copy_custom ähnlich arbeiten.
    copy_all_custom soll ne neue Liste aufbauen deren Elemente aber aus den Rückgabewerten der Funktion bestehen,die du als custom übergeben hast.
    del_all_custom soll die Liste löschen aber vorher noch für jeden Wert der Liste die als custom übergebene Funktion(mit dem Wert als Parameter) ausführen.
    Ich küsse Bjarne Stroustrup den Arsch dass es C++ gibt.....

    Gruß void
    "Probleme kann man niemals mit derselben Denkweise lösen,
    durch die sie entstanden sind." (A. Einstein)
  • hi void, hi sebastian (zu dem Trupp an der FH Wiesbaden gehör ich übrigens auch...)

    ich bin auch froh, wenn wir ab Montag bei Python sind.

    Im Vergleich zur void del_all( node *firstnode ) würd ich in der _custom einfach diesen custom() aufruf mit content als Parameter ergänzen.. ist ja noch alles void.

    Quellcode

    1. void del_all_custom(node *firstnode , void (∗custom)(void ∗)) {
    2. node *delnode = firstnode;
    3. while( firstnode->next != NULL ){
    4. firstnode = firstnode->next;
    5. custom(firstnode->content);
    6. free( delnode );
    7. delnode = firstnode;
    8. }
    9. free( delnode );
    10. }
    Alles anzeigen


    Hast du mal mit valgrind gecheckt ob du das letzt free( delnode ) überhaupt noch aufrufen musst?
    Denn eigentlich ist ja alles gelöscht, oder?

    Aber diese custom() leuchtet mir nicht ein... was soll sie denn nun tun.. übergeben tu ich den content und zurückliefern tu ich einen pointer auf den content?

    Was soll denn das Ziel der Funktion sein?
    Wenn ich die liste mit copy_custom kopiere, könnte ich beide listen am ende unabhängig weiter befüllen/sortieren/...
    Wenn ich aber den content eines objekts aus liste A ändere, dann ändert sich auch der content des entsprechenden objekt in liste B.

    Steh da irgendwie auf dem schlauch...
  • Hi,
    ich hab heute abend zwar schon nen paar Bier auf aber ich hab mal ne Beispielimplementierung geschrieben.Zumindest so wie ich die Aufgabenstellung verstehe..... :) .
    Das Ganze baut auf DjRasts bisheriger Lösung auf(obwohl ich glaube dass da noch Fehler drin sind).

    Quellcode

    1. //Beispiel custom Funktion
    2. void print_as_int(void* arg)
    3. {
    4. printf("Der Wert des Knotens ist %d\n",*((int*)arg));
    5. }
    6. void del_all_custom( node *firstnode ,void(*custom)(void*))
    7. {
    8. node *delnode = firstnode;
    9. while( firstnode->next != NULL ){
    10. firstnode = firstnode->next;
    11. custom(delnode->content);
    12. free( delnode );
    13. delnode = firstnode;
    14. }
    15. free( delnode );
    16. }
    17. node* copy_custom(node* _original_list,void*(*custom)(void*))
    18. {
    19. node *head = NULL;
    20. void* temp_content;
    21. if(_original_list != NULL)
    22. {
    23. head = (node*)malloc(sizeof(node));
    24. head->content = custom(_original_list->content);
    25. head->next=NULL;
    26. head->prev=NULL;
    27. while(_original_list->next != NULL)
    28. {
    29. _original_list = _original_list->next;
    30. temp_content = custom(_original_list->content);
    31. add_last(head,temp_content);
    32. }
    33. }
    34. return head;
    35. }
    36. //manipulierende "custom" Funktion
    37. void* add2(void* _value)
    38. {
    39. int* new_value = (int*)malloc(sizeof(int));
    40. *new_value = *((int*)_value)+2;
    41. return new_value;
    42. }
    43. int main(void){
    44. int i1 = 0;
    45. int i2 = 1;
    46. int i3 = 2;
    47. void *eins = &i1;
    48. void *zwei = &i2;
    49. void *drei = &i3;
    50. node *dvlist = NULL;
    51. node *list = NULL;
    52. dvlist = add(dvlist,eins);
    53. dvlist = add(dvlist,zwei);
    54. dvlist = add_ith(dvlist,drei,2);
    55. list = copy_custom(dvlist,add2);
    56. del_all_custom(dvlist,print_as_int);
    57. del_all_custom(list,print_as_int);
    58. return 1;
    59. }
    Alles anzeigen


    Gruß void
    "Probleme kann man niemals mit derselben Denkweise lösen,
    durch die sie entstanden sind." (A. Einstein)