imitheos Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Δεν ξέρω αν ο φίλος nikmyt έχει σχέση με τον κ. Χατζηγιαννάκη παρόλα αυτά θα γράψω. Το username του σίγουρα παραπέμπει αλλά πέταξε ένα link χωρίς κανένα σχόλιο και από τότε δεν έχει δώσει σημεία ζωής. Γράφω λοιπόν μήπως διαβάζει ο κ. Χατζηγιαννάκης το φόρουμ. Μερικές φορές συμφορουμίτες μας ζητάνε να προτείνουμε βιβλίο εκμάθησης της γλώσσας αλλά απαραίτητα να είναι γραμμένο στα Ελληνικά. Πολλά άτομα προτείνουμε το βιβλίο σας γιατί το θεωρούμε πολύ καλή επιλογή. Παρόλα αυτά όμως υπάρχουν κάποια πράγματα που μου κάθονται άσχημα και με δυσκολεύουν να το προτείνω. Ίσως να μην είναι σημαντικά πράγματα κιόλας και να είναι παραξενιές δικές μου αλλά μια και βλέπω ότι ετοιμάζεται η 4η έκδοση του βιβλίου, παίρνω το θάρρος να κάνω κάποιες καλοπροαίρετες επισημάνσεις σε περίπτωση που δεν έχει ολοκληρωθεί η συγγραφή της έκδοσης. Η συνάρτηση main δηλώνεται τις περισσότερες φορές ως "main()" αντί του σωστού "int main(void)". Σε πολλά παραδείγματα της printf δεν υπάρχει \n. Στις περισσότερες πλατφόρμες δεν θα δημιουργήσει πρόβλημα και το μήνυμα θα εμφανιστεί σωστά αλλά γιατί να μην μπει το \n όπως είναι πιο σωστό ? Στη σελίδα 26 εκεί που αναφέρονται οι πραγματικοί τύποι μπορεί να αναφερθεί και ο long double εκτός του float και του double καθώς και ο long long int στους ακεραίους. Στη σελίδα 56 αναφέρει "Οι δηλωτικές προτάσεις πρέπει να είναι οι πρώτες προτάσεις στο κορμό μιας συνάρτησης .....". Επίσης στη σελίδα 72 αναφέρεται ως λάθος το παράδειγμα για αυτό το λόγο. Από την έκδοση C99 του προτύπου επιτρέπονται ανάμεικτες "δηλωτικές" και "εκτελέσιμες" προτάσεις. Στη σελίδα 62 αναφέρει σωστά ότι το μέγεθος των μεταβλητών, και κατά συνέπεια των τύπων, εξαρτάται από την πλατφόρμα και έπειτα αναφέρει τα μεγέθη σε ένα τυπικό 32bit σύστημα. Πιστεύω θα ήταν ωραίο ένα πινακάκι με τα μεγέθη των τύπων σε διάφορα τυπικά συστήματα όπως 32bit, 64bit unix/windows, κτλ Στη σελίδα 91 στο πινακάκι προτεραιότητας τελεστών αναφέρονται οι ++ και -- ως αύξηση και μείωση αντίστοιχα αλλά δεν αναφέρεται ότι αυτοί είναι οι prefix τελεστές ενώ οι postfix έχουν υψηλότερη προτεραιότητα. Επίσης δεν αναφέρονται κάποιοι άλλοι τελεστές όπως ο dereference τελεστής *. Στη σελίδα 96 η άσκηση 4.3 ζητάει, μεταξύ άλλων, να βρεθεί η παράσταση x = y = y++. Έχει νόημα αυτή η παράσταση ? Έχω την εντύπωση ότι είναι ίδια περίπτωση που αναφέρεται στην ερώτηση 3.3 του C-Faq και η συμπεριφορά της είναι αόριστη. Στις σελίδες 102,103,κτλ στις συναρτήσεις getchar, putchar, κτλ αναφέρεται ότι "η παράμετρος ch πρέπει να είναι τύπου char ή τύπου int" και σε πολλά παραδείγματα χρησιμοποιείται τύπος char. Καλό είναι να χρησιμοποιείται int και όχι char για να αποφευχθούν πιθανά προβλήματα με το EOF (η δήλωση των συναρτήσεων στο πρότυπο έχει int άλλωστε) Στη σελίδα 173 αναφέρει "Αν δεν οριστεί ο τύπος της συνάρτησης, η C υποθέτει ότι η συνάρτηση επιστρέφει τιμή τύπο int." Η έκδοση C99 του προτύπου ακύρωσε αυτή τη σύμβαση και πρέπει ρητά να ορίζεται ο τύπος επιστροφής κάθε συνάρτησης. Στη σελίδα 230 αναφέρεται "Παρόλο που φαίνεται το ίδιο, η ανάθεση του 0 αντί της NULL σε ένα δείκτη μπορεί να έχει καταστροφικά αποτελέσματα". Ίσως σε κάποια variadic συνάρτηση να μην αναγνωριστεί σωστά το 0 αλλά σχεδόν σε όλες τις περιπτώσεις είναι ακριβώς το ίδιο με το NULL. Στην περίπτωση που χρησιμοποιηθεί μια έμμεση μεταβλητή τότε _δεν_ θα έχουμε σωστό αποτέλεσμα αλλά αν χρησιμοποιήσουμε ένα Integer Constant είναι εγγυημένο ότι ο δείκτης θα έχει σωστή "τιμή". Σε πάρα πολλά σημεία έχουμε μεταβλητές που αρχικοποιούνται με Ελληνικά (πχ char lex[10]="ΝΙΚΟΣ"). Κατανοώ ότι το βιβλίο χρησιμοποιεί το DEV-C++ σεταρισμένο σε Windows-1253 οπότε δεν υπάρχει πρόβλημα αλλά μπορεί να δημιουργηθεί πρόβλημα αν ο αναγνώστης τρέχει κάποιο unixοειδές λειτουργικό που χρησιμοποιεί UTF-8 locale όπου κάθε χαρακτήρας θα καταλαμβάνει 2 bytes οπότε ο χώρος ενδέχεται να μην είναι αρκετός. Ερχόμαστε στο Dev-C++ αυτό καθεαυτό. Από ό,τι διαβάζω εδώ στο φόρουμ, το Dev-C++ δεν αναπτύσσεται εδώ και πολύ καιρό και έχει διάφορα προβλήματα. Σε αυτό το θέμα μπορεί να προτείνει μια καλύτερη λύση κάποιο από τα παιδιά που χρησιμοποιούν Windows όπως ο φίλος migf1 ο οποίος μάλιστα έχει γράψει το πακέτο εξελληνισμού για κάποια IDE. Στη σελίδα 255 παρουσιάζεται η συνάρτηση gets η οποία μετέπειτα χρησιμοποιείται σε πάρα πολλά παραδείγματα του βιβλίου. Η gets εκτός από (κατά γενική ομολογία) επικίνδυνη, θεωρούταν παρωχημένη στην έκδοση C99 του προτύπου και έχει αφαιρεθεί εντελώς από την τρέχουσα έκδοση C11. Στη σελίδα 257 που παρουσιάζεται η συνάρτηση strlen ίσως να ήταν καλό να αναφερθεί ότι η strlen δεν μετράει τον χαρακτήρα '\0'. Στη σελίδα 298 παρουσιάζεται μια δομή και αναφέρεται ότι με όποιο τρόπο και να δηλωθούν τα πεδία της δομής, αυτή θα καταλαμβάνει 52 bytes που είναι και το άθροισμα των πεδίων. Ίσως πρέπει να αναφερθεί ότι σχεδόν σε όλους τους compilers θα υπάρχει κάποιο padding οπότε το μέγεθος της δομής θα είναι μεγαλύτερο. Στη σελίδα 399 και στη αναδρομική συνάρτηση rbinary ίσως να ήταν καλύτερο να μπει "meson=apo+(eos-apo)/2" αντί για το υπάρχον "meson=(apo+eos)/2". Στη σελίδα 423+ που παρουσιάζονται οι συναρτήσεις malloc, calloc, κτλ καλό είναι να αλλαχθεί ο τύπος της παραμέτρου από unsigned int σε size_t. Επίσης αναφέρεται "Απαραίτητη είναι η μετατροπή τύπου του δείκτη που επιστρέφει η malloc, ....." το οποίο λόγω της αυτόματης μετατροπής του (void *) δεν είναι απαραίτητο και μάλιστα αντενδείκνυται από πολλούς οδηγούς και βιβλία. Ίσως να μου διέφυγε κάτι αλλά στην περιγραφή της calloc αναφέρεται "η μόνη διαφορά μεταξύ malloc και calloc είναι στον τρόπο υπολογισμού του μεγέθους ......" και δεν αναφέρεται ότι η περιοχή που θα επιστρέψει η calloc θα έχει αρχικοποιηθεί με τιμή 0. Είχα και κάποιες παρατηρήσεις ακόμη αλλά ήταν πολύ τιτίζικες οπότε δεν τις βάζω. Ευχαριστώ.
defacer Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Κάτι που μου χτύπησε στο μάτι: Στη σελίδα 399 και στη αναδρομική συνάρτηση rbinary ίσως να ήταν καλύτερο να μπει "meson=apo+(eos-apo)/2" αντί για το υπάρχον "meson=(apo+eos)/2". Δεν ξέρω από πού προέρχεται η λίστα με τις διορθώσεις, αλλά αν αυτό το βρήκες ο ίδιος τα σέβη μου.
moukoublen Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Γιατί να μη του στείλεις ένα mail, imitheos;
migf1 Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 ... Σε πολλά παραδείγματα της printf δεν υπάρχει \n. Στις περισσότερες πλατφόρμες δεν θα δημιουργήσει πρόβλημα και το μήνυμα θα εμφανιστεί σωστά αλλά γιατί να μην μπει το \n όπως είναι πιο σωστό ? ... Ως "πιο σωστό" υποθέτω εννοείς πως θα αναγκαστεί να γίνει flushed το output στο stdout, λόγω του '\n', ναι; Αν ναι, προφανώς και είναι σωστή η επισήμανση, αλλά υπάρχουν πολλές περιπτώσεις που συνειδητά δεν θέλεις να αλλάξεις γραμμή στην printf(). Σε αυτές τις περιπτώσεις το σωστό είναι να κάνουμε χειροκίνητα flush το stdout, μετά την printf()... > printf( "...", ...); fflush( stdout ); Στις δημοφιλείς πλατφόρμες γίνεται αυτόματα έτσι κι αλλιώς flush το output της printf() με ή χωρίς '\n', αλλά αν ο κώδικάς μας προορίζεται για διάφορες πλατφόρμες, τότε είναι καλή ιδέα να φτιάξουμε έναν wrapper της printf() (είτε ως macro είτε ως συνάρτηση) που θα κάνει πάντα fflush(stdout) και να χρησιμοποιούμε αυτόν αντί της printf(). Προσωπικά θα το έκανα με variadic macro, κάπως έτσι (αν είναι σωστό, γιατί δεν το 'χω τσεκάρει)... > #define PRINTF( ... ) \ do { \ printf( __VA_ARGS__ ); \ fflush( stdout ); \ } while(0)
Star_Light Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 (επεξεργασμένο) @imitheos Στην getchar() δεν καταλαβαινω γιατι σκάλωσες . Οπου βλέπει char η C κολλαει το int . Ετσι θυμαμαι οτι γραφει και σε άλλο βιβλιο. Μπορεις ομως να κοιταξεις και το παράδειγμα εδω http://www.cplusplus...cstdio/getchar/ Δεν νομιζω να υπάρχει προβλημα αν εγω γράψω > ch = getchar(); putchar(ch); Και σε άλλα βιβλια χρησιμοποιούν αρκετα την gets παντως για λογους ευκολιας. Μολις την ριξεις στον Compiler θα παρεις Warning ομως . Επεξ/σία 15 Αυγούστου 2012 από Star_Light
imitheos Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Γιατί να μη του στείλεις ένα mail, imitheos; Δεν ξέρω αν ο nikmyt είναι όντως ο ίδιος για να του στείλω mail για αυτό το έστειλα εδώ. Άσε που μπορούν να γράψουν και άλλα άτομα εδώ τη γνώμη τους. Edit: /me μάπας. Δεν σκέφτηκα να στείλω κατευθείαν στο δικό του mail στο bytes.gr. Θα στείλω το παρόν url τώρα. Κάτι που μου χτύπησε στο μάτι: Δεν ξέρω από πού προέρχεται η λίστα με τις διορθώσεις, αλλά αν αυτό το βρήκες ο ίδιος τα σέβη μου. Η λίστα είναι από δικό μου διάβασμα του βιβλίου. Το παρόν θέμα με το πιθανό overflow το είχα διαβάσει πριν 5-6 χρόνια όταν το ανακάλυψε κατά τύχη ένας java developer ή κάτι τέτοιο οπότε τα εύσημα ανήκουν σε εκείνον. Εγώ απλά θυμόμουν ότι παίζει κάτι τέτοιο Ως "πιο σωστό" υποθέτω εννοείς πως θα αναγκαστεί να γίνει flushed το output στο stdout, λόγω του '\n', ναι; Αν ναι, προφανώς και είναι σωστή η επισήμανση, αλλά υπάρχουν πολλές περιπτώσεις που συνειδητά δεν θέλεις να αλλάξεις γραμμή στην printf(). Σε αυτές τις περιπτώσεις το σωστό είναι να κάνουμε χειροκίνητα flush το stdout, μετά την printf()... > printf( "...", ...); fflush( stdout ); Ναι αυτό εννοώ. Γνωρίζω ότι πολλές φορές συνειδητά δεν θέλεις να αλλάξεις γραμμή αλλά επίτηδες δεν πρότεινα το fflush γιατί μερικές περιπτώσεις τέτοιων printf είναι ακόμη και σε πρώτες σελίδες οπότε είναι πιο εύκολο πιστεύω να εξηγηθεί τι κάνει το \n από το τι κάνει η fflush. Όπως έγραψα, αυτό δεν είναι και τπτ ιδιαίτερο αλλά πιο πολύ politically-correct παραξενιά μου. Το έγραψα γιατί είναι απλό. Κάτι άλλα τιτίζικα που είχα (όπως ότι το fflush παίζει μόνο σε output streams ή και κάποια ακόμη χειρότερα) δεν τα έγραψα επίτηδες :Ρ Οπου βλέπει char η C κολλαει το int . Ετσι θυμαμαι οτι γραφει και σε άλλο βιβλιο. Διάβασε καλύτερα τα Integer Promotions. Στην getchar() δεν καταλαβαινω γιατι σκάλωσες . Μπορεις ομως να κοιταξεις και το παράδειγμα εδω http://www.cplusplus...cstdio/getchar/ Δεν νομιζω να υπάρχει προβλημα αν εγω γράψω > ch = getchar(); putchar(ch); Και σε άλλα βιβλια χρησιμοποιούν αρκετα την gets παντως για λογους ευκολιας. Μολις την ριξεις στον Compiler θα παρεις Warning ομως . > #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; f = fopen("test","w"); if (!f) return -1; fputs("Test\xFFHello World", f); fclose(f); return 0; } > #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; signed char ch; f = fopen("test", "r"); if (!f) return -1; while ((ch = fgetc(f)) != EOF) printf("%c\n", ch); return 0; } Έξοδος: > T e s t Που πήγε το Hello World, ωεω ? Σημείωση επίτηδες έβαλα fgetc αντί για getchar για να είναι πιο εύκολο και signed char γιατί δεν ξέρω σε τι πλατφόρμα θα το τρέξεις. Στους περισσότερους compilers, ο char θα υλοποιείται ως signed. Στην αντίθετη περίπτωση που θέλεις unsigned υπάρχει πάλι περίπτωση που δεν παίζει
Star_Light Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Κοιτα δεν καταλαβαινω που κολλας. Εγω ξερω πως οταν θές να πάρεις εισοδο με την getchar εκχωρεις την εισοδο σε μια μεταβλητη τυπου char. Εσυ αυτο λες οτι αυτη πρεπει να ειναι int ? Aυτη τη μεταβλητη ουτως η άλλως σαν int αποτιμάται λογω του ASCII της. Το γραφει και ο King στο βιβλιο του. Αποτιμάται και μετατρέπεται σε signed int ή σε unsigned σε ορισμενες περιπτώσεις. Το προβλημα ποιο ειναι και μου λες να μπλεξω παλι με τα implicit conversions ? Ολα τα παραδειγματα στο ιντερνετ σαν char δηλωνουν την μεταβλητή. Ο τυπος char έχει αριθμητικη φύση.
παπι Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Εσυ αυτο λες οτι αυτη πρεπει να ειναι int ? Δεν το λεει αυτος... Απλα ακολουθει το documentation της συναρτησης.
Star_Light Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Δεν το λεει αυτος... Απλα ακολουθει το documentation της συναρτησης. Η συνάρτηση getchar() επιστρέφει κάτι το οποίο εκχωρείται σε μια μεταβλητή τύπου char. Eπειδη μια char ομως αποτιμάται απευθειας στο ASCII code της λογω του τροπου αποθηκευσης χαρακτηρων στον υπολογιστη δεν δημιουργειται κανενα προβλημα αν τη δηλωσεις σαν char και της εκχωρησεις αυτο που ειναι int και επιστρεφεται μεσω της getchar ή και putchar κτλπ. (που και παλι χαρακτηρας ειναι) Ο υπολογιστης δεν ξέρει απο χαρακτηρες. Δυαδικες ακολουθιες επεξεργαζεται. Ολα τα παραδειγματα στο ιντερνετ ετσι δουλευουν http://www.cplusplus...cctype/toupper/ http://www.cplusplus...cctype/tolower/ http://www.cplusplus...cstdio/putchar/ EDIT : Τώρα ειδα το EOF που λεει.... και ειναι -1.
παπι Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Η συνάρτηση getchar() επιστρέφει κάτι το οποίο εκχωρείται σε μια μεταβλητή τύπου char. Η συναρτηση επιστρεφει integer. Αν αυτος ο integer εχει την τιμη EOF (xffffffff) τοτε εχει γινει καποιο σφαλμα ή εχει τελειωσει το stream. Eπειδη μια char ομως αποτιμάται απευθειας στο ASCII code της λογω του τροπου αποθηκευσης χαρακτηρων στον υπολογιστη δεν δημιουργειται κανενα προβλημα αν τη δηλωσεις σαν char και της εκχωρησεις αυτο που ειναι int και επιστρεφεται μεσω της getchar ή και putchar κτλπ. Ο υπολογιστης δεν ξέρει απο χαρακτηρες. Δυαδικες ακολουθιες επεξεργαζεται. Αποτιμαται σε ascii ; τροπος αποθηκευσης; Το char ειναι ενας 8bitος τυπος τιποτα αλλο. EDIT +1 στο τυπο με το βιβλιο που εβγαλε vids στο yt.
Super Moderators paredwse Δημοσ. 15 Αυγούστου 2012 Super Moderators Δημοσ. 15 Αυγούστου 2012 Οι προσωπικές αντιπαραθέσεις και οι χαρακτηρισμοί παρακαλώ να αποφεύγονται. Εάν έχετε προσωπικές διαφορές με άλλα μέλη, υπάρχουν τα pm ή και τα email, το forum δεν προσφέρεται. Αφαιρέθηκαν είκοσι (20) μηνύματα.
imitheos Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Οι προσωπικές αντιπαραθέσεις και οι χαρακτηρισμοί παρακαλώ να αποφεύγονται. Εάν έχετε προσωπικές διαφορές με άλλα μέλη, υπάρχουν τα pm ή και τα email, το forum δεν προσφέρεται. Αφαιρέθηκαν είκοσι (20) μηνύματα. Ευχαριστώ.
defacer Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 Η συνάρτηση getchar() επιστρέφει κάτι το οποίο εκχωρείται σε μια μεταβλητή τύπου char. Όπως λένε και τα παιδιά, το signature της συνάρτησης είναι >int getchar ( void ); Επομένως τέλος της συζήτησης. Γενικότερα όταν κάποιος σου λέει ότι η συνάρτησή μου επιστρέφει int και εσύ σκέφτεσαι να το αποθηκεύσεις αυτό σε char θα έπρεπε αυτομάτως να χτυπάνε συναγερμοί αεροπορικής επιδρομής μέσα στο κεφάλι σου. Το λιγότερο που θα έπρεπε να κάνεις σ' αυτή την περίπτωση είναι να διαβάσεις εξονυχιστικά το πώς συμπεριφέρεται η function και το τι επιστρέφει για να διαπιστώσεις για ποιό λόγο το signature λέει int και ανάλογα να δράσεις. Απο κει και πέρα αυτό που φαντάζομαι ότι έγραφε ο imitheos είναι "προφανές": εφόσον η getchar επιστρέφει όλες τις πιθανές τιμές ενός char αλλά και μια επιπλέον τιμή "end of file", δε θα ήταν δυνατόν να γίνεται κάτι τέτοιο με return type που δεν είναι "μεγαλύτερο" του char. Και τέλος στο end of file η getchar δεν επιστρέφει -1 αλλά EOF (macro). Το γεγονός ότι το EOF τυχαίνει να έχει την τιμή -1 άρα θεωρούμε ότι EOF == -1 είναι κλασική περίπτωση λάθους. Σήμερα τυχαίνει, αύριο δεν τυχαίνει. Το documentation λέει EOF άρα και πάλι τέλος της συζήτησης. Μη γίνεις αγύριστο κεφάλι γιατί ειδικά στον προγραμματισμό δε θα πας μπροστα. Φιλικά. 3
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα