You are not logged in.

  • Login

1

Saturday, November 11th 2006, 4:06pm

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:

C Quellcode

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include<stdlib.h>
#include<stdio.h>
 
typedef struct _node{
	int *content;
	struct _node *prev;
	struct _node *next;
} node;
 
const int nsize = sizeof(node);
 
node* add( node *firstnode, void *cont ) {
 
	node *newnode = malloc( nsize );
	newnode->content = cont;
 
	if( firstnode == NULL ) { 	/*Wenn Liste leer*/
		newnode->prev = NULL;
		newnode->next = NULL;
		return newnode;
	}
 
	else{			/*fuege in bestehende Liste ein*/
		newnode->next = firstnode;
		newnode->prev = NULL;
		firstnode->prev= newnode;
		return newnode;
	}
}
 
node* add_ith( node *firstnode, void *cont, int pos ) {
 
	int i;
 
	node *newnode = malloc( nsize );
	newnode->content = cont;
 
	node *itnode = firstnode;	/*suche i-1te Position*/
	for( i=1 ; i< pos-1 ; i++ ) {
		itnode = itnode->next;
	}
 
	if( itnode == NULL)	/*Position ausserhalb, nicht einfuegen*/
		return firstnode;
 
	else{
		newnode->next = itnode->next;	/*fuege neuen Knoten ein*/
		newnode->prev = itnode;
		newnode->next->prev = newnode;
		itnode->next = newnode;
 
		return firstnode;
	}
}
 
node* add_last( node *firstnode, void *cont ){
 
	node *newnode = malloc( nsize );
	newnode->content = cont;
 
	node *itnode = firstnode;	/*suche letzten Knoten*/
	while( itnode->next != NULL ) {
		itnode = itnode->next;		
	}
	itnode->next = newnode;
	newnode->prev = itnode;
	newnode->next = NULL;
 
	return firstnode;
}
 
node* del( node *firstnode){
 
	if( firstnode == NULL || firstnode->next == NULL)	/*Wenn kein oder nur ein Konten vorhanden*/
		return NULL;
 
	else{
		node *newfirstnode = firstnode->next;
		newfirstnode->prev = NULL;
		free(firstnode);
		return newfirstnode;
	}
}
 
node* del_ith( node *firstnode, int pos ){
 
	int i;
 
	node *itnode = firstnode;
 
	for( i=1 ; i< pos-1 ; i++ ){	/*suche i-1te Position*/
		itnode = itnode->next;
	}
 
	if( itnode == NULL || itnode->next == NULL)	/*wenn knoten nicht vorhanden*/
		return firstnode;
 
	else{
		node *delnode = itnode->next;	/*merke zu loeschenden Knoten*/
		itnode->next = delnode->next;
		delnode->next->prev = itnode;
		free(delnode);
		return firstnode; 
	}
}
 
node* del_last( node *firstnode){
 
	node *itnode = firstnode;
 
	while( itnode->next->next != NULL )	/*suche vorletzten Knoten*/
		itnode = itnode->next;
 
	free(itnode->next);
	itnode->next = NULL;
	return firstnode;
}
 
void del_all( node *firstnode ) {
	node *delnode = firstnode;
 
	while( firstnode->next != NULL ){
		firstnode = firstnode->next;
		free( delnode );
		delnode = firstnode;
	}
 
	free( delnode );
}
 
int main(void){
	int i1 = 0;
	int i2 = 1;
	int i3 = 2;
	void *eins = &i1;
	void *zwei = &i2;
	void *drei = &i3;
 
	node *dvlist = NULL;
	dvlist = add(dvlist,eins);
	dvlist = add(dvlist,zwei);
	dvlist = add_ith(dvlist,drei,2);
 
	printf("%d,%d,%d\n", *(dvlist->content), *(dvlist->next->content), *(dvlist->next->next->content));
 
	del_all(dvlist);
 
	return 1;
}

2

Saturday, November 11th 2006, 4:32pm

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

3

Saturday, November 11th 2006, 4:45pm

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

Saturday, November 11th 2006, 5:12pm

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

5

Saturday, November 11th 2006, 5:39pm

Ach so, ein Zeiger auf eine Funktion! Danke für die Antwort. C ist wirklich ziemlich ätzend :roll: aber zum Glück fangen wir nächste Woche mit Python an. :wink:

Gruß, DjRAST

6

Saturday, November 11th 2006, 7:21pm

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.

C Quellcode

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


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...

7

Saturday, November 11th 2006, 8:52pm

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).

C Quellcode

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//Beispiel custom Funktion 
void print_as_int(void* arg)
{
	printf("Der Wert des Knotens ist %d\n",*((int*)arg));
}
 
void del_all_custom( node *firstnode ,void(*custom)(void*))
{
	node *delnode = firstnode;
 
        while( firstnode->next != NULL ){
                firstnode = firstnode->next;
		custom(delnode->content);
                free( delnode );
                delnode = firstnode;
        }     
        free( delnode );
}
 
 
node* copy_custom(node* _original_list,void*(*custom)(void*))
{
	node *head = NULL;
	void* temp_content;
 
	if(_original_list != NULL)
	{
		head = (node*)malloc(sizeof(node));
		head->content = custom(_original_list->content);
		head->next=NULL;
		head->prev=NULL;
 
		while(_original_list->next != NULL)
		{
			_original_list = _original_list->next;
			temp_content = custom(_original_list->content);
			add_last(head,temp_content);
		}
	}
	return head;
}
//manipulierende "custom" Funktion
void* add2(void* _value)
{
	int* new_value = (int*)malloc(sizeof(int));
	*new_value = *((int*)_value)+2;
 
	return new_value;
}
 
int main(void){
        int i1 = 0;
        int i2 = 1;
        int i3 = 2;
        void *eins = &i1;
        void *zwei = &i2;
        void *drei = &i3;
 
        node *dvlist = NULL;
	node *list = NULL;
        dvlist = add(dvlist,eins);
        dvlist = add(dvlist,zwei);
        dvlist = add_ith(dvlist,drei,2);
 
	list = copy_custom(dvlist,add2);
 
        del_all_custom(dvlist,print_as_int);
	del_all_custom(list,print_as_int);
 
        return 1;
}


Gruß void

8

Sunday, November 12th 2006, 1:32pm

aha.. ein Lichtblick ;-)
Jetzt wo ich deinen Code sehe, verstehe ich auch die Aufgabe.
Also wird add2 in copy_custom >>als parameter<< übergeben und augerufen..
Eben ein Zeiger auf eine Funktion - wie DjRAST schon vor mir begriffen hat

Logisch!

Vielen Dank void!

Similar threads

Social bookmarks