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

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

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

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

Δημοσίευσηαπό migf1 » 24 Μαρ 2012, 15:01

Ilias95 έγραψε:Δηλαδή αν κατάλαβα καλά θα την καλούμε κάπως έτσι:...

Γράφαμε μαζί, πόσταρα ένα πιθανό πρότυπο της συνάρτησης.

έγραψε:Μια άλλη άσκηση που έχω στο μυαλό μου να υλοποιήσω για να δω καλύτερα πως μπορώ να διαχειριστώ arrays με strings είναι η εξής:
Ένα πρόγραμμα στο οποίο θα μπορείς να προσθέσεις/αφαιρέσεις/εμφανίσεις ταξινομημένα τα ζώα ενός ζωολογικού κήπου (λέμε τώρα).

Ωραία άσκηση είναι, και δεν χρειάζεται να είναι για ζώα μόνο... μπορεί να είναι για οποιοδήποτε string. Αυτή όμως θα την καταφέρεις πολύ πιο εύκολα όταν θα μάθεις δυναμική διαχείριση μνήμης (και ακόμα πιο εύκολα όταν μάθεις linked-lists).

Βασικά την έχω βάλει κι εγώ σαν άσκηση στο τέλος, σε εκείνη τη σειρά από tutorials που είχα ποστάρει και στο φόρουμ (και τα έχω και στο site μου, εδώ: http://x-karagiannis.gr/prog/libs/conte ... 6.php#exer)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό Ilias95 » 24 Μαρ 2012, 15:20

migf1 έγραψε:Ωραία άσκηση είναι, και δεν χρειάζεται να είναι για ζώα μόνο... μπορεί να είναι για οποιοδήποτε string.

Ναι φυσικά. Γι' αυτό έγραψα το λέμε τώρα. :P
migf1 έγραψε:Αυτή όμως θα την καταφέρεις πολύ πιο εύκολα όταν θα μάθεις δυναμική διαχείριση μνήμης (και ακόμα πιο εύκολα όταν μάθεις linked-lists).

Προφανώς, γιατί τώρα θα αναγκαστώ να δεσμεύω εξαρχής όση μνήμη χρειάζεται για έναν συγκεκριμένο αριθμό "ζώων" που θα είναι ο μέγιστος.

Edit: Πολύ χρήσιμη και η ιδέα για hash tables που αναφέρεις στο site σου. Έτσι θα το υλοποιήσω. :)
Τελευταία επεξεργασία από Ilias95 και 24 Μαρ 2012, 15:24, έχει επεξεργασθεί 1 φορά/ες συνολικά
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 24 Μαρ 2012, 15:24

Με την ευκαιρία, μιας που μιλάμε για c-strings, δεν ξέρω αν το έχει θίξει ο King, αλλά όλες οι έτοιμες συναρτήσεις διαχείρισης strings προκαλούν seg-fault αν το string τους περαστεί NULL.

Πρόκειται για μια συνειδητή επιλογή του σχεδιασμού της γλώσσας, στο βωμό της ταχύτητας εκτέλεσης. Το αντίτιμο είναι πως αν έστω και κατά λάθος περάσεις το string ως NULL σε οποιαδήποτε έτοιμη συνάρτηση, θα προκληθεί seg-fault. Κάτι παρόμοιο συμβαίνει και με τον μηδενικό χαρακτήρα, ο οποίος αν δεν υπάρχει, οι περισσότερες έτοιμες συναρτήσεις "προχωράνε" έξω από το όριο του μέγιστου μήκους που έχει οριστεί για το string (ορισμένες δέχονται το μέγιστο μήκος ως έξτρα όρισμα, αλλά και πάλι είναι ευθύνη του προγραμματιστή να περάσει σωστό νούμερο εκεί ... και όχι π.χ. μεγαλύτερο).

Η 2η περίπτωση αντιμετωπίζεται με πολύπλοκο τρόπο, μιας και προϋποθέτει τη δημιουργία νέου τύπου (π.χ. String) που μπορεί να εξαρτάται ή όχι από την ύπαρξη μηδενικού χαρακτήρα, καθώς και μια συλλογή από συναρτήσεις που θα διαχειρίζονται strings του τύπου String, αντίστοιχες των έτοιμων, αλλά πιο ασφαλείς (αυτό ονομάζεται managed approach).

Η 1η περίπτωση όμως αντιμετωπίζεται πολύ εύκολα, με έναν εσωτερικό έλεγχο στην κάθε μας συνάρτηση, για το αν το string που της περνάμε είναι ή όχι NULL (το λεγόμενο "sanity check"). Αν είναι NULL, τότε πολύ απλά σηματοδοτούμε με κάποιον τρόπο το σφάλμα κι επιστρέφουμε άπραγοι από την συνάρτηση.

Π.χ. η συνάρτηση που "κεφαλοποιεί" όλα τα γράμματα ενός string...

Μορφοποιημένος Κώδικας: Επιλογή όλων
char *s_toupper( char *s )
{
char *cp = s;

/* sanity check */
if ( !s )
return NULL;

while ( (*cp = (char)toupper( (int)(*cp) )) )
cp++;

return s;
}

Και όταν την καλούμε...

Μορφοποιημένος Κώδικας: Επιλογή όλων
...
if ( NULL == s_toupper( string ) ) {
/* internal *error */
...
}
...
Τελευταία επεξεργασία από migf1 και 24 Μαρ 2012, 16:07, έχει επεξεργασθεί 1 φορά/ες συνολικά
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό Ilias95 » 24 Μαρ 2012, 15:28

Ναι. Βέβαια για το NULL macro ακόμα δεν ξέρω πολλά πολλά, παρά μόνο ότι είναι το τελευταίο στοιχείο της *argv[].
Ο King κάνει αναφορά σε αυτό σε επόμενα κεφάλαια...
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

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

Δημοσίευσηαπό Star_Light » 24 Μαρ 2012, 15:40

Παιδια σορρυ αν διακοπτω το θεματακι με τα strings... αν μπορει κανεις ας απαντησει

εδω μου πετάει ατέρμων βροχο επειδη καθε φορα η τιμη της if ειναι αληθης μιας και εχω δωσει 0 στο stdin
και ο ελεγχος περναει στην ex και φτου και απο την αρχη ετσι?

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

#include<stdio.h>
int main()
{
int n;

printf(" Give n : \n");
scanf("%d" , &n);

ex:

printf(" %d " , n);

if( n == 0 )
goto ex;


return 0;
}


Κανω ενα μικρο παραδειγματακι να καταλαβω την goto.
To καλυτερο θα ειναι να το κανω με ενα παραδειγματακι οπως εδω με loop

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

#include <stdio.h>
int main()
{
int n = 0;
loop:

printf("\n%d", n);
n++;

if (n<10) {
goto loop;

}

return 0;
}


Γιατι σε μερικους κώδικες θα ειχε ας πουμε

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

printf("\n%d", n);
n++;


Θα ειχε δηλαδη ερωτηματικο μετα την ετικετα loop χρειαζεται σε κατι συγκεκριμενο αυτο?
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 24 Μαρ 2012, 15:44

Ilias95 έγραψε:Ναι. Βέβαια για το NULL macro ακόμα δεν ξέρω πολλά πολλά, παρά μόνο ότι είναι το τελευταίο στοιχείο της *argv[].
Ο King κάνει αναφορά σε αυτό σε επόμενα κεφάλαια...

Το NULL στη C υλοποιείται συνήθως ως ένα απλό...
Μορφοποιημένος Κώδικας: Επιλογή όλων
#define (void *)0
ή ως...
Μορφοποιημένος Κώδικας: Επιλογή όλων
#define 0L

και χρησιμοποιείται στους δείκτες για να σηματοδοτήσει πως έχουν μια άκυρη μεν, γνωστή δε τιμή (το κενό). Ένα παράδειγμα είναι ο ορισμός ενός δείκτη, που μπορεί να γίνει με ή χωρίς αρχικοποίηση...

Μορφοποιημένος Κώδικας: Επιλογή όλων
char *cp;    /* χωρίς αρχικοποίηση, δείχνει σε undefined σημείο της μνήμης */
char *cp = NULL; /* με αρχικοποίηση, δείχνει στο γνωστό μας "κενό" */

Και στις 2 περιπτώσεις ο δείκτης δεν έχει περιεχόμενα (δεν τον έχουμε βάλει να δείχνει στη διεύθυνση κάποιας μεταβλητής, ή κάποιας άλλης γνωστής σε μας περιοχής της μνήμης) αλλά επειδή τον έχουμε αρχικοποιήσει σε NULL, μπορούμε με ασφάλεια να τσεκάρουμε αν έχει κενό περιεχόμενο ή όχι....

Μορφοποιημένος Κώδικας: Επιλογή όλων
if ( cp )...      // ή if (NULL != cp )

ή το πιο σύνηθες...

Μορφοποιημένος Κώδικας: Επιλογή όλων
if ( !cp )...      // ή if (NULL == cp )


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

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

Δημοσίευσηαπό migf1 » 24 Μαρ 2012, 16:00

@Starlight:

Σωστά τα γράφεις για το infinite loop. Το σκέτο ερωτηματικό είναι απλώς ένα κενό statement (δεν το χρειάζεσαι).

Τώρα, σε ότι αφορά τη χρήση της goto, είναι καλό να μην μάθεις καν πως χρησιμοποιείται ως εναλλακτική υλοποίηση ενός loop (διότι περί αυτού πρόκειται στο κώδικα που παρέθεσες)... όταν θες να υλοποιήσεις loop να το υλοποιείς με for, while ή do.

Η μόνη θεμιτή (και κυρίως ευανάγνωστη κι απροβλημάτιστη) χρήση της goto είναι όταν χρησιμοποιείται περίπου σαν υποσυνάρτηση μέσα σε συνάρτηση, τοποθετημένη στο τέλος της συνάρτησης.

Αν π.χ. έχεις μια bool συνάρτηση η οποία μπορεί να παράξει σφάλμα σε 5 διαφορετικές περιπτώσεις, και σε κάθε σφάλμα πρέπει να γίνει κάποιου είδους cleanup πριν επιστρέψει το σφάλμα η συνάρτηση, τότε αντί να γράφεις τον cleanup κώδικα μέσα στο if της κάθε μιας από τις 5 περιπτώσεις (+ return false) , τον γράφεις μια φορά στο τέλος της συνάρτησης (+return false), και μέσα στα if της κάθε περίπτωσης γράφεις: goto clean_and_ret.

Μορφοποιημένος Κώδικας: Επιλογή όλων
bool foo()
{
if ( err1)
goto clean_and_ret;
if ( err2 )
goto clean_and_ret;
if ( err3 )
goto clean_and_ret;
if ( err4 )
goto clean_and_ret;
if ( err5 )
goto clean_and_ret;

/* όλα είναι ok, νορμάλ κώδικας της συνάρτησης */
return true;

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

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

Δημοσίευσηαπό Star_Light » 24 Μαρ 2012, 16:14

Ευχαριστω migf1. ΣΥμφωνω δεν υπαρχει λογος να χρησιμοποιω την goto σαν προσομοιωση ενος loop μιας και υπάρχουν ηδη 3 καλοι βροχοι :P
απλα ηταν επισης ενα καλο παραδειγματακι γιατι ειδα οτι ατερμονες βροχοι δεν παιζουν μονο στα loops!!!!!!
ειπαμε να τρελαινομαστε μερικες φορες αλλα οχι και ετσι.... θελει και η τρελα ενα μετρο :P

Κοιταξε να δεις εγω χρησιμοποιησα αυτο το παραδειγμα αφενος γιατι ηταν το 1ο που βρηκα στο google και καταλαβα με γρηγορη αναζητηση
και αφετερου αν χρησιμοποιησω κατι τετοιο

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

#include<stdio.h>
int main()
{
int n;

printf(" Give n : \n");
scanf("%d" , &n);

if( n > 0 )
goto ex;

ex:
printf(" %d " , n);

return 0;
}

η goto δεν δουλευει... δεν μπορει το -2 που εδωσα να ειναι μεγαλυτερο απο το 0. Εκτος και αν εδω η C το αντιμετωπιζει απλα σαν statement δεν ξερω τωρα εδω τι γινεται..... το αντιμετωπιζει ισως σαν statement και εκτελει την printf.

Δεν θα κατσω να την κοιταξω παραπανω παντως.... αυτο το παραδειγμα και τελος. Νομιζω ισως να μην την χρησιμοποιησω και ποτε για τα επομενα 2-3 χρονια :lol: :lol:
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

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

Δημοσίευσηαπό Star_Light » 24 Μαρ 2012, 16:28

Καταλαβα παντως στην συναρτηση που δινεις αν προκυψει καποιο σφάλμα πεταγεται στο label clean_up κανει αυτα που πρεπει
και μολις επιστρεψει απο την goto επιστρεφει false αγνοωντας το true φυσικα το οποιο θα επιστραφει μονο αν καποια απο τις if δωσει λογικο 0. FALSE
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

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

Δημοσίευσηαπό Ilias95 » 24 Μαρ 2012, 16:29

Star_Light έγραψε:η goto δεν δουλευει...

Τι εννοείς δεν δουλεύει;
Στο παραπάνω παράδειγμα η goto δεν χρησιμεύει σε απολύτως τίποτα. Έτσι κι αλλιώς ο κώδικας της ex θα εκτελεστεί ανεξάρτητα της τιμής του n.
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

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

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

cron