Τα πάντα για την C

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 21 Ιούλ 2011, 15:19

migf1 έγραψε:
stamatiou έγραψε:
Χωρίς παρεξήγηση αλλά μου φάνηκε αρκετά εύκολο! :eh:

Γιατί παρεξήγηση βρε συ; Ίσα-ίσα είναι πολύ καλό το ότι σου φάνηκε αρκετά εύκολο! Και χαίρομαι κιόλας :)

Δοκίμασες να φτιάξεις για εξάσκηση τις συναρτήσεις που προτείνω στο 6ο μέρος;

Κώδικας: Επιλογή όλων

Μερικές καλές ασκήσεις για να τεστάρουμε τις μέχρι τώρα γνώσεις μας είναι να φτιάξουμε συναρτήσεις για την αναζήτηση ή/και διαγραφή του πρώτου κόμβου που θα βρεθεί να έχει την τιμή: value μέσα στη λίστα, π.χ.: list_del1st( List *list, int value ) και list_find1st( List *list, int value ). Τις αφήνω να τις κάνετε μόνοι σας για εξάσκηση, ενώ αν θέλετε μπορείτε να τις επεκτείνετε σε πιο γενικές, π.χ. να βρίσκουν ή/και να διαγράφουν όλους του κόμβους που περιέχουν την τιμή: value ( list_delete( List *list, int value ) και list_search( List *list, int value ) ).

Πήγα να κάνω το del1st(χωρίς να χρησιμοποιήσω len) και μου έβγαλε ένα παράξενο error ο compiler.
Ο κώδικας είναι αυτός:
Κώδικας: Επιλογή όλων
int del1st(List **list,int value)
{
Node *dummy;
dummy = *(list->head);

while(dummy->data != value)
{
dummy = dummy -> next;
}
dummy->data = 0;
return 0;
}


και το error:
Κώδικας: Επιλογή όλων
error: request for member ‘head’ in something not a structure or union

Τι σημαίνει αυτό;
Άσε το βρήκα! Την ίδια κοτσάνα έκανα πάλι...
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 21 Ιούλ 2011, 15:25

Αυτήν την άσκηση δεν την έχω δει.... Την έχεις και στο GVRT(Greek Virtual Racing Team- Τώρα το σκέφτηκα :idea: ) ;
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 21 Ιούλ 2011, 15:28

Δεν έχω δώσει κώδικα για αυτές ;)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 21 Ιούλ 2011, 15:47

stamatiou έγραψε:
Πήγα να κάνω το del1st(χωρίς να χρησιμοποιήσω len) και μου έβγαλε ένα παράξενο error ο compiler.
Ο κώδικας είναι αυτός:
Κώδικας: Επιλογή όλων
int del1st(List **list,int value)
{
Node *dummy;
dummy = *(list->head);

while(dummy->data != value)
{
dummy = dummy -> next;
}
dummy->data = 0;
return 0;
}

και το error:
Κώδικας: Επιλογή όλων
error: request for member ‘head’ in something not a structure or union

Τι σημαίνει αυτό;
Άσε το βρήκα! Την ίδια κοτσάνα έκανα πάλι...

Πέρα από το error, που στο βγάζει γιατί κανονικά πρέπει να γράψεις:
Κώδικας: Επιλογή όλων

dummy = (*list)->head;

υπάρχουν και λογικά σφάλματα στον παραπάνω κώδικα:

1. το while δεν ελέγχει αν ο dummy γίνεται NULL, οπότε μόλις γίνει NULL (από το: dummy = dummy->next) θα πάει μετά να ελέγξει το: dummy->data != value και θα βαρέσει segmentation fault, γιατί βασικά πάει να ελέγξει το: NULL->data != value ( !!BOOOM!! )

2. Για να διαγράψεις τον κόμβο που έχει data == value δεν μηδενίζεις το πεδίο data. Πρέπει πρώτα να βάλεις το πεδίο next του προηγούμενου κόμβου να δείχνει στον επόμενο κόμβο και μετά να καταστρέψεις τον τρέχων κόμβο (με free).

Αυτό προϋποθέτει πως μέσα στο loop εκτός από τον dummy που δείχνει στον τρέχων κόμβο, πρέπει να χρησιμοποιήσεις κι άλλον βοηθητικό δείκτη (π.χ. prev), που θα δείχνει στον προηγούμενο κόμβο (να είναι δηλαδή πάντα ένα βήμα πίσω από τον dummy). Έτσι ώστε όταν ο dummy βρεθεί στον κόμβο προς διαγραφή, να μπορείς να κάνεις ένα:
Κώδικας: Επιλογή όλων
prev->next = dummy->next;

πριν καταστρέψεις τον κόμβο στον οποίον δείχνει ο dummy, με:
Κώδικας: Επιλογή όλων
free(dummy);
και να σταματήσεις το loop.

Αν θέλεις να συνεχίσεις το ψάξιμο και για άλλον κόμβο με τιμή value στο πεδίο data, τότε μετά από το παραπάνω θα πρέπει να βάλεις τον dummy να δείχνει στον κόμβο prev->next
Κώδικας: Επιλογή όλων

dummy = prev->next;
και να συνεχίσεις το loop.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 21 Ιούλ 2011, 15:53

Α, και αν μιλάμε για τις δομές του 5ου και 6ου μέρους, τότε τον list πρέπει να τον περάσεις με ένα αστέρι μέσα στη συνάρτηση:

Κώδικας: Επιλογή όλων

int del1st(List *list,int value)
{
Node *dummy;
dummy = list->head;

Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 21 Ιούλ 2011, 16:01

migf1 έγραψε:Δεν έχω δώσει κώδικα για αυτές ;)

Εννούσα τις εκφωνήσεις...
migf1 έγραψε:
stamatiou έγραψε:
Πήγα να κάνω το del1st(χωρίς να χρησιμοποιήσω len) και μου έβγαλε ένα παράξενο error ο compiler.
Ο κώδικας είναι αυτός:
Κώδικας: Επιλογή όλων
int del1st(List **list,int value)
{
Node *dummy;
dummy = *(list->head);

while(dummy->data != value)
{
dummy = dummy -> next;
}
dummy->data = 0;
return 0;
}

και το error:
Κώδικας: Επιλογή όλων
error: request for member ‘head’ in something not a structure or union

Τι σημαίνει αυτό;
Άσε το βρήκα! Την ίδια κοτσάνα έκανα πάλι...

Πέρα από το error, που στο βγάζει γιατί κανονικά πρέπει να γράψεις:
Κώδικας: Επιλογή όλων

dummy = (*list)->head;

υπάρχουν και λογικά σφάλματα στον παραπάνω κώδικα:

1. το while δεν ελέγχει αν ο dummy γίνεται NULL, οπότε μόλις γίνει NULL (από το: dummy = dummy->next) θα πάει μετά να ελέγξει το: dummy->data != value και θα βαρέσει segmentation fault, γιατί βασικά πάει να ελέγξει το: NULL->data != value ( !!BOOOM!! )

2. Για να διαγράψεις τον κόμβο που έχει data == value δεν μηδενίζεις το πεδίο data. Πρέπει πρώτα να βάλεις το πεδίο next του προηγούμενου κόμβου να δείχνει στον επόμενο κόμβο και μετά να καταστρέψεις τον τρέχων κόμβο (με free).

Αυτό προϋποθέτει πως μέσα στο loop εκτός από τον dummy που δείχνει στον τρέχων κόμβο, πρέπει να χρησιμοποιήσεις κι άλλον βοηθητικό δείκτη (π.χ. prev), που θα δείχνει στον προηγούμενο κόμβο (να είναι δηλαδή πάντα ένα βήμα πίσω από τον dummy). Έτσι ώστε όταν ο dummy βρεθεί στον κόμβο προς διαγραφή, να μπορείς να κάνεις ένα:
Κώδικας: Επιλογή όλων
prev->next = dummy->next;

πριν καταστρέψεις τον κόμβο στον οποίον δείχνει ο dummy, με:
Κώδικας: Επιλογή όλων
free(dummy);


Αν θέλεις να συνεχίσεις το ψάξιμο και για άλλον κόμβο με τιμή value στο πεδίο data, τότε μετά από το παραπάνω θα πρέπει να βάλεις τον dummy να δείχνει στον κόμβο prev->next
Κώδικας: Επιλογή όλων

dummy = prev->next;

και να συνεχίσεις το loop.

Επιτρέπεται να βάλω το prev σαν δείκτη αλλά στο Node;
migf1 έγραψε:Α, και αν μιλάμε για τις δομές του 5ου και 6ου μέρους, τότε τον list πρέπει να τον περάσεις με ένα αστέρι μέσα στη συνάρτηση:

Κώδικας: Επιλογή όλων

int del1st(List *list,int value)
{
Node *dummy;
dummy = list->head;


Οκ, θα το κάνω τώρα
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 21 Ιούλ 2011, 16:09

Έτσι είναι σωστή;
Off topic:
Μην περιμένεις απάντηση θαγυρίσω σε καμιά ωρίτσα και.... Σόρρυ
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 21 Ιούλ 2011, 16:10

stamatiou έγραψε:
[snip]
Οκ, θα το κάνω τώρα

Οκ, αλλά μη βιαστείς. Φτιάξε καφεδάκι, και πάρε χαρτί & μολύβι για να σχεδιάζεις τις περιπτώσεις αν θεωρείς πως θα σε βοηθήσει. Νομίζω πως δεν είναι τόσο εύκολο όσο ενδεχομένως νομίζεις.

Για να σε βοηθήσω λιγάκι, εξέτασε πρώτα σε ξεχωριστό if την περίπτωση που ο κόμβος προς διαγραφή είναι ο 1ος της λίστας (πριν ξεκινήσεις δηλαδή να ασχολείσαι με το loop). ;)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 21 Ιούλ 2011, 17:37

migf1 έγραψε:
stamatiou έγραψε:
[snip]
Οκ, θα το κάνω τώρα

Οκ, αλλά μη βιαστείς. Φτιάξε καφεδάκι, και πάρε χαρτί & μολύβι για να σχεδιάζεις τις περιπτώσεις αν θεωρείς πως θα σε βοηθήσει. Νομίζω πως δεν είναι τόσο εύκολο όσο ενδεχομένως νομίζεις.

Για να σε βοηθήσω λιγάκι, εξέτασε πρώτα σε ξεχωριστό if την περίπτωση που ο κόμβος προς διαγραφή είναι ο 1ος της λίστας (πριν ξεκινήσεις δηλαδή να ασχολείσαι με το loop). ;)

Κώδικας: Επιλογή όλων
int del1st(List *list,int value)
{
Node *dummy;
dummy = (*list).head;
while(dummy != NULL)
{
if(dummy->data == value)
{
dummy->prev = dummy->next;
free(dummy);

}
return 0;
}

Υ.Γ. Δεν πίνω καφέ :lol:
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 21 Ιούλ 2011, 18:44

Έκανα μια διόρθωση αλλά και πάλι δεν το διαγράφει:
Κώδικας: Επιλογή όλων
int del1st(List *list,int value)
{
Node *dummy;
dummy = (*list).head;
while(dummy != NULL)
{
if(dummy->data == value)
{
dummy->prev->next = dummy->next;
free(dummy);
}
dummy = dummy -> next;
}
return 0;
}

Μήπως μποείς να μου πεις πώς είναι; Δεν μπορώ να το βρω! :crazy:
Ελπίζω επειδή δεν μπορώ να λύσω την άσκηση να μην χρειάζεται να ξαναδιαβάσω structs και pointers από την αρχή :!: :crazy: :crazy: :crazy: :crazy:
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

ΠροηγούμενηΕπόμενο

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι