1. Η πορεία της C μέχρι σήμερα
1.1 Ιστορική αναδρομή στη γλώσσα C
Η γλώσσα C αναπτύχθηκε από τους Dennis Ritchie και Ken Thompson στα Bell Telephone Laboratories. Αποτέλεσε εξέλιξη της γλώσσας Β που είχε αναπτύξει ο Thompson η οποία ήταν μια απλούστερη έκδοση της γλώσσας BCPL (Basic Combined Programming Language) και χρησιμοποιήθηκε στα πλαίσια της ανάπτυξης του λειτουργικού συστήματος MULTICS. Τελικά, η εξέλιξη του MULTICS, το Unix, γράφτηκε στη C το 1972 και έκτοτε η γλώσσα είναι στενά συνδεδεμένη μαζί του καθώς και με το Linux, που επίσης αναπτύχθηκε στη C αρχικά το 1991 από τον Linus Torvalds. Σήμερα αποτελεί μια από τις πλέον δημοφιλείς γλώσσες προγραμματισμού, επιδεικνύοντας αξιοπρόσεκτη αντοχή στον χρόνο ως κυρίαρχη γλώσσα ιδιαίτερα για προγραμματισμό συστημάτων (systems programming) καθώς και για προγραμματισμό ενσωματωμένων συστημάτων (embedded systems) 1. Αξίζει επίσης να σημειωθεί ότι γλώσσες όπως η C++, η Java, η JavaScript, η Perl και η Python καθώς και διάφορα άλλα λογισμικά που χρήστες υπολογιστικών συστημάτων χρησιμοποιούν σε καθημερινή βάση, έχουν γραφεί στη γλώσσα C.
1.2 Η φιλοσοφία της C
Η C θεωρείται ότι είναι μια γλώσσα προγραμματισμού σχετικά «χαμηλού επιπέδου». Για παράδειγμα, ο προγραμματιστής στη C είναι υπεύθυνος για τη δέσμευση και την αποδέσμευση μνήμης στον σωρό (heap). Δηλαδή, εφόσον απαιτείται δυναμική δέσμευση μνήμης (π.χ. δέσμευση μνήμης για έναν πίνακα ακεραίων που δεν είναι γνωστό το μέγεθός του κατά τη συγγραφή του προγράμματος, αλλά αυτό προσδιορίζεται κατά τον χρόνο εκτέλεσης) ο προγραμματιστής πρέπει να καλέσει τη συνάρτηση malloc() και, όταν η μνήμη που έχει δεσμευθεί δεν είναι πλέον απαραίτητη για την εκτέλεση της λογικής του προγράμματος, ο προγραμματιστής πρέπει να θυμηθεί να την αποδεσμεύσει. Γλώσσες προγραμματισμού υψηλότερου επιπέδου, όπως η Python, διαθέτουν μηχανισμούς συλλογής σκουπιδιών (garbage collection), όπου η δέσμευση και η αποδέσμευση μνήμης γίνονται αυτόματα από την ίδια τη γλώσσα, φροντίζοντας ταυτόχρονα για την αποφυγή κατακερματισμού του χώρου μνήμης του σωρού. Ένα άλλο παράδειγμα είναι ότι γλώσσες υψηλού επιπέδου παρέχουν μηχανισμούς που ελέγχουν αν πραγματοποιείται προσπέλαση εκτός των ορίων ενός πίνακα, ενώ η C δεν προσφέρει, λόγω σχεδιασμού, αυτήν τη δυνατότητα. Στη γλώσσα Java, αν επιχειρηθεί κατά την εκτέλεση πρόσβαση εκτός των ορίων ενός πίνακα, τότε θα προκύψει μια εξαίρεση ArrayIndexOutOfBoundsException και το πρόγραμμα θα τερματίσει την εκτέλεσή του. Αν ο κώδικας που προκαλεί την εξαίρεση βρίσκεται μέσα σε try...catch, τότε θα εκτελεστεί ο κώδικας που θα έχει ορίσει ο προγραμματιστής για τον χειρισμό της εξαίρεσης και το πρόγραμμα θα συνεχίσει την εκτέλεσή του κανονικά. Στη C δεν υπάρχουν τέτοιοι μηχανισμοί και ο προγραμματιστής είναι υπεύθυνος, έτσι ώστε ο κώδικας που συντάσσει να μην πραγματοποιεί πρόσβαση εκτός των ορίων πινάκων. Συνεπώς, περιπτώσεις προγραμματιστικών λαθών που όντως γίνεται πρόσβαση εκτός των ορίων ενός πίνακα κατά την εκτέλεση του κώδικα, δεν ανιχνεύονται από τη γλώσσα και είτε στην καλύτερη περίπτωση οδηγούν στην κατάρρευση του προγράμματος (λόγω πρόσβασης σε «απαγορευμένες» θέσεις μνήμης) είτε στη χειρότερη περίπτωση προκαλούν αλλοίωση σε χρήσιμα δεδομένα, που είναι δύσκολο να εντοπιστεί και να διορθωθεί στη συνέχεια. Ένα τελευταίο παράδειγμα, από τα πολλά άλλα που θα μπορούσαν να αναφερθούν, που δείχνει τη διαφορά στη φιλοσοφία της C σε σχέση με άλλες γλώσσες υψηλού επιπέδου είναι ο τρόπος με τον οποίο συγκρίνονται δύο λεκτικά για ισότητα. Σε γλώσσες όπως η Python, για τη σύγκριση δύο λεκτικών s1 και s2, αρκεί κανείς να γράψει s1 == s2 και το αποτέλεσμα θα είναι είτε true είτε false. Στη C, όμως, θα πρέπει να συμπεριληφθεί το αρχείο επικεφαλίδας string.h και, στη συνέχεια να κληθεί η συνάρτηση strcmp() με ορίσματα τα δύο λεκτικά και να εξεταστεί το αποτέλεσμα που επιστρέφει, το οποίο, εάν είναι 0, θα σημαίνει ότι τα λεκτικά είναι όμοια μεταξύ τους.
Από τα παραπάνω προκύπτει ότι η C αντιμετωπίζει τον προγραμματιστή ως κάποιον που γνωρίζει τι πρέπεινα κάνει και δεν του προσφέρει περιττές βοήθειες. Ενθαρρύνει τη συγγραφή κώδικα που αποτελείται από μικρά ανεξάρτητα προγράμματα που το καθένα κάνει ένα πράγμα καλά. Επιβάλλει ελάχιστους περιορισμούς στον προγραμματιστή και δίνει έμφαση στην υψηλή ταχύτητα εκτέλεσης
Σχετικά με το εάν η C κατατάσσεται στις γλώσσες υψηλού επιπέδου ή στις γλώσσες χαμηλού επιπέδου, η απάντηση είναι ότι η C είναι σαφώς μια γλώσσα υψηλού επιπέδου, αλλά, ταυτόχρονα, έχει και χαρακτηριστικά γλώσσας χαμηλού επιπέδου. Είναι υψηλού επιπέδου, καθώς ο προγραμματιστής δεν χρειάζεται να ασχολείται με τις λεπτομέρειες της αρχιτεκτονικής του υπολογιστή στον οποίο θα εκτελεστεί το πρόγραμμά του και συνεπώς, μπορεί να εστιάζει στην επίλυση του πραγματικού προβλήματος που καλείται να επιλύσει. Εξάλλου ένας από τους βασικούς στόχους της γλώσσας C κατά τη σχεδίασή της ήταν η δυνατότητα ο κώδικας να είναι φορητός από έναν τύπο υπολογιστή και λειτουργικού συστήματος σε άλλους τύπους υπολογιστών και λειτουργικών συστημάτων. Για παράδειγμα, ο προγραμματιστής μπορεί να γράφει ένα πρόγραμμα σε C σε έναν υπολογιστή με λειτουργικό σύστημα Windows και με επεξεργαστή Intel και στη συνέχεια να μεταφέρει τον πηγαίο κώδικα, να τον μεταγλωττίζει και να τον εκτελεί χωρίς προβλήματα σε έναν υπολογιστή με λειτουργικό σύστημα MacOS και επεξεργαστή ARM. Από την άλλη μεριά, η C βρίσκεται πλησιέστερα στο υλικό από ό,τι άλλες γλώσσες προγραμματισμού, όπως αυτές που αναφέρθηκαν στις προηγούμενες παραγράφους, καθώς ο προγραμματιστής έχει σε κάποιον βαθμό απευθείας πρόσβαση στο υλικό (π.χ. σε θέσεις μνήμης) και δεν του δίνεται πρόσβαση στους πόρους του υπολογιστή μέσω μιας εικονικής μηχανής, όπως για παράδειγμα στη Java με το JVM ( Java Virtual Machine). Στο άρθρο 2 ο David Chisnall σχολιάζει την εγγύτητα της πραγματικής φυσικής μηχανής που εκτελεί τον κώδικα με την ιδεατή μηχανή εκτέλεσης που ο προγραμματιστής στη C θεωρεί ότι εκτελεί τα προγράμματα που συντάσσει. Ο συγγραφέας υποστηρίζει ότι η εξέλιξη στην τεχνολογία των επεξεργαστών και των μεταγλωττιστών έχει προχωρήσει σε τέτοιον βαθμό που η αντιστοίχιση μεταξύ της ιδεατής μηχανής της C και της φυσικής μηχανής είναι απλώς μια ψευδαίσθηση.
1.3 Προτυποποίηση της γλώσσας C
Μια από τις πρώτες εκδόσεις της γλώσσας έμεινε γνωστή ως K&R C, από τα αρχικά των συγγραφέων του δημοφιλούς βιβλίου “The C Programming Language” των Brian Kernighan και Dennis Ritchie 3, που κυκλοφόρησε στην πρώτη του έκδοση το 1978 και σε δεύτερη έκδοση το 1988. Στη συνέχεια, ακολουθήθηκε μια πορεία προτυποποίησης της γλώσσας από την οποία προέκυψε το 1989 η έκδοση ANSI C ή C89. Η ANSI C αποτέλεσε και την πρώτη έκδοση της προτυποποίησης της C από τους οργανισμούς ISO (International Standards Organization) και IEC (International Electrotechnical Commission), με το αναγνωριστικό C90.Η δεύτερη έκδοση της προτυποποίησης της C δημοσιεύθηκε το 1999 και ήταν η C99. Η τρίτη και η τέταρτη έκδοση του προτύπου C ακολούθησαν το 2011 και το 2018 με αναγνωριστικά C11 και C17, αντίστοιχα. Η πέμπτη έκδοση προτυποποίησης της γλώσσας, η C23 (ή C2x), βρίσκεται σε ανάπτυξη από τους ISO/IEC και το 2023 είναι το έτος της αναμενόμενης ανακοίνωσής της. Η ιστοσελίδα https://en.cppreference.com/w/c/language/history καταγράφει με λεπτομέρειες τα ορόσημα στην ιστορία της C, από το 1969 μέχρι και σήμερα.
1.4 Υλοποιήσεις της γλώσσας C
Ο όρος «υλοποίηση της γλώσσας C» αναφέρεται σε υλοποιήσεις μεταγλωττιστών της γλώσσας. Οι διάφοροι μεταγλωττιστές της C μπορούν να υλοποιούν διαφορετικές εκδόσεις των προτύπων της C. Σήμερα, μερικοί από τους πλέον δημοφιλείς μεταγλωττιστές της C είναι o GCC, ο Clang και ο μεταγλωττιστής MSVC από την εταιρεία Microsoft.
1.4.1 GCC
O GCC (GNU Compiler Collection) περιέχει μεταγλωττιστή για τη C καθώς και για άλλες γλώσσες προγραμματισμού (C++, Fortran, Ada). Έχει αναπτυχθεί από το GNU Project και είναι ελεύθερο λογισμικό που διατίθεται μέσω της άδειας χρήσης GPL (General Public License). Αποτελεί την προεπιλογή μεταγλωττιστή C για συστήματα Linux και υπάρχουν εκδόσεις του GCC για Windows, για MacOS και για άλλα λειτουργικά συστήματα. Ο μεταγλωττιστής της C, που περιλαμβάνεται στις νεότερες εκδόσεις του GCC, υποστηρίζει τα πρότυπα C89, C99, C11, C17 και μερικώς το υπό διαμόρφωση νέο πρότυπο C2x. Περισσότερες πληροφορίες για την υποστήριξη προτύπων από το GCC μπορούν να αναζητηθούν στο https://gcc.gnu.org/onlinedocs/gcc/Standards.html. Για τα περισσότερα παραδείγματα κώδικα που θα εξεταστούν στο παρόν σύγγραμμα θα χρησιμοποιηθεί ο μεταγλωττιστής GCC.
1.4.2 Clang
Ο Clang είναι ένας μεταγλωττιστής για τη C αλλά και για άλλες γλώσσες προγραμματισμού (C++, Objective C/C++ κ.ά.). Σχεδιάστηκε με στόχο να αντικαταστήσει τον GCC και υποστηρίζει πολλές από τις επιλογές μεταγλώττισης που χρησιμοποιεί και ο GCC. Είναι λογισμικό ανοικτού κώδικα και η ανάπτυξή του υποστηρίζεται από πολλές μεγάλες εταιρείες, συμπεριλαμβανομένων των Apple, Microsoft, Google, Intel και Sony. Ο Clang αποτελεί την προεπιλογή μεταγλωττιστή C για τους υπολογιστές της εταιρείας Apple στο λειτουργικό σύστημα macOS. Ο μεταγλωττιστής της C που περιλαμβάνεται στις νεότερες εκδόσεις του Clang υλοποιεί πλήρως το πρότυπο C89 καθώς και σημαντικά τμήματα των προτύπων C99, C11, C17, ενώ υλοποιεί μερικώς το νέο πρότυπο C2x. Περισσότερες πληροφορίες σχετικά με την υποστήριξη προτύπων από τον Clang μπορούν να εντοπισθούν στο https://clang.llvm.org/c_status.html.
1.4.3 MSVC
Ο μεταγλωττιστής MSVC (cl.exe) έχει αναπτυχθεί από την εταιρεία Microsoft για τις γλώσσες C και C++ καθώς και για επεκτάσεις των γλωσσών που καθιστούν εφικτή τη δημιουργία εφαρμογών στις διάφορες εκδόσεις των λειτουργικών συστημάτων Windows. Για μεγάλο χρονικό διάστημα ο MSVC υποστήριζε μόνο το πρότυπο C89. Σταδιακά, από το 2013 και μετά άρχισε να υποστηρίζει τμηματικά το πρότυπο C99 και C11.Τον Σεπτέμβριο του 2020 η εταιρεία ανακοίνωσε την υποστήριξη των προτύπων C11 και C17.
1.4.4 Άλλοι μεταγλωττιστές της C
Εκτός από τους μεταγλωττιστές που αναφέρθηκαν, υπάρχουν και άλλοι μεταγλωττιστές, τόσο ελεύθερα διαθέσιμοι όσο και εμπορικοί, που σε ορισμένες περιπτώσεις είναι σχεδιασμένοι για συγκεκριμένη υπολογιστική υποδομή. Μερικά παραδείγματα είναι o Intel C/C++ compiler (icc), ο NVIDIA HPC C compiler (nvc), ο Tiny C compiler (tcc), ο Pelles C compiler, o Ch compiler, o OpenWatcom C/C++ compiler κ.ά.
1.5 Η σχέση της C με τη C++
Η C++ αναπτύχθηκε από τον Bjarne Stroustrup στα Bell Laboratories το 1979. Η αρχική της ονομασία ήταν “C with Classes”, αλλά το 1983 μετονομάστηκε σε C++. Ως γλώσσα προγραμματισμού δέχθηκε σημαντική επιρροή από τη γλώσσα προγραμματισμού Simula και ιδιαίτερα στο θέμα της οργάνωσης του κώδικα σε κλάσεις και στην υποστήριξη ιεραρχιών μεταξύ κλάσεων. Οι ιδέες της Simula μεταφέρθηκαν στη νέα γλώσσα, τη C++, η οποία χρησιμοποιούσε το συντακτικό της C αλλά και τον χαρακτήρα της C ως γλώσσα χαμηλού επιπέδου. Έτσι, η C++ επέτρεπε τον προγραμματισμό με κλάσεις, όπως η Simula και, ταυτόχρονα, την εκτέλεση του κώδικα με την ταχύτητα της γλώσσας C. Έκτοτε οι γλώσσες C και C++ ακολούθησαν διαφορετικά μονοπάτια εξέλιξης. Αν και ένα πρόγραμμα σε C++ μπορεί να περιέχει κώδικα C, η συμβατότητα με τη C περιορίζεται μόνο μέχρι το πρότυπο C89. Έτσι, ένα πρόγραμμα σε C που είναι γραμμένο σύμφωνα με το πρότυπο C99 ή κάποιο από τα επόμενα είναι πιθανό να μην μεταγλωττίζεται από μεταγλωττιστές της C++. Είναι λοιπόν, σημαντικό να γίνει κατανοητό ότι η C δεν είναι υποσύνολο της C++ και ότι η C++ δεν είναι μια εξελιγμένη έκδοση της C, αλλά πρόκειται για δύο διαφορετικές γλώσσες προγραμματισμού που έχουν ακολουθήσει ανεξάρτητες πορείες εξέλιξης.
Η σημαντικότερη διαφορά ανάμεσα στις δύο γλώσσες είναι η διαφορετική προσέγγιση που ακολουθούν στον προγραμματισμό. Η C είναι μια διαδικασιακή (procedural) γλώσσα προγραμματισμού, που δίνει έμφαση στο πώς γίνεται κάτι και πώς η εργασία επιμερίζεται σε συναρτήσεις. Από την άλλη μεριά, η C++ είναιμια γλώσσα προγραμματισμού πολλαπλών υποδειγμάτων (multi-paradigm), που υποστηρίζει - επιπλέον του διαδικασιακού προγραμματισμού - τον αντικειμενοστραφή αλλά και άλλους τρόπους προγραμματισμού.
1.6 Συγγραφή μεταγλώττιση και εκτέλεση απλών προγραμμάτων
Ένα πρόγραμμα σε C μπορεί να είναι διαμερισμένο σε πολλά αρχεία. Στην απλούστερη περίπτωση ο κώδικας βρίσκεται σε ένα μόνο αρχείο πηγαίου κώδικα, όπως στο ακόλουθο παράδειγμα (κώδικας 1.1), που απλώς εμφανίζει στην οθόνη το κείμενο Hello World!, ως είθισται για εναρκτήριο παράδειγμα στα βιβλία εκμάθησης προγραμματισμού.
Κώδικας 1.1: ch1_p1.c - το πρόγραμμα “hello world” στη C. | |
---|---|
Μεταγλώττιση και εκτέλεση σε Linux
Το εκτελέσιμο εκτελείται με απλή παράθεση του ονόματός του στη γραμμή εντολών. Σε συστήματα Linux ή MacOS πρέπει να προηγηθεί του ονόματος το ./, που υποδηλώνει τον τρέχοντα φάκελο, έτσι ώστε να εντοπιστεί η σωστή διαδρομή προς το αρχείο.
Μεταγλώττιση και εκτέλεση σε MacOS
Μεταγλώττιση και εκτέλεση σε Windows
Αν υπάρχει συντακτικό σφάλμα στον κώδικα, τότε ο μεταγλωττιστής θα εμφανίσει μήνυμα σφάλματος και δεν θα δημιουργήσει το εκτελέσιμο. Στο ακόλουθο παράδειγμα (κώδικας 1.2) έχει σκόπιμα παραλειφθεί το δεξί διπλό εισαγωγικό στην printf(), με αποτέλεσμα να υπάρχει σφάλμα στον κώδικα.Κώδικας 1.2: ch1_p1_error.c - ένα εσκεμμένο συντακτικό σφάλμα. | |
---|---|
$ gcc ch1_p1.c
ch1_p1_error.c: In function 'main':
ch1_p1_error.c:5:12: warning: missing terminating " character
5 | printf("Hello World!\n);
| ^
ch1_p1_error.c:5:12: error: missing terminating " character
5 | printf("Hello World!\n);
| ^~~~~~~~~~~~~~~~~
ch1_p1_error.c:6:1: error: expected expression before '}' token
6 | }
| ^
ch1_p1_error.c:5:12: error: expected ';' before '}' token
5 | printf("Hello World!\n);
| ^
| ;
6 | }
1.6.1 Μεταγλώττιση με ενεργοποίηση warnings, διακόπτες μεταγλώττισης
Κατά τη μεταγλώττιση μπορούν να οριστούν διάφορες επιλογές. Για παράδειγμα ο διακόπτης (switch) -o επιτρέπει να οριστεί το όνομα του εκτελέσιμου που θα παραχθεί. Ένας άλλος σημαντικός διακόπτης είναι ο διακόπτης -Wall, που ενεργοποιεί την εμφάνιση «όλων» των προειδοποιήσεων (warnings) που υποδεικνύουν την πιθανή δημιουργία προβλημάτων. Έτσι αν συμπεριληφθεί στην εντολή μεταγλώττισης ο διακόπτης -Wall, τότε η μεταγλώττιση θα παράγει μηνύματα σχετικά με μεταβλητές που δεν έχουν αρχικοποιηθεί, μεταβλητές που δεν χρησιμοποιούνται και άλλα. Επιπλέον warnings μπορούν να ενεργοποιηθούν με τον διακόπτη
-Wextra, ενώ η εμφάνιση μηνυμάτων για παραβίαση των κανόνων που επιβάλλει το πρότυπο της C μπορεί να ενεργοποιηθεί με τον διακόπτη ‐pedantic. Η εμφάνιση warnings κατά τη μεταγλώττιση δεν εμποδίζει τον μεταγλωττιστή από το να δημιουργήσει το τελικό εκτελέσιμο. Αν, όμως, χρησιμοποιηθεί ο διακόπτης ‐Werror, τότε τα warnings θεωρούνται ως σφάλματα μεταγλώττισης και δεν παράγεται εκτελέσιμο. Επιπλέον, μπορεί να οριστεί το πρότυπο της γλώσσας που θα χρησιμοποιηθεί για τη μεταγλώττιση με τον διακόπτη ‐std. Οι επιλογές φαίνονται στον Πίνακα 1.1.
Πίνακας 1.1: Επιλογή προτύπου της γλώσσας με τον διακόπτη μεταγλώττισης -std.
Πρότυπο (standard) | Τιμή για τον διακόπτη μεταγλώττισης -std |
---|---|
ISO C 1990 |
c89 ή c90 |
ISO C 1999 |
c99 |
ISO C 2011 |
c11 |
ISO C 2017 |
c17 ή c18 |
Working Draft for ISO C2x |
c2x |
Ένα παράδειγμα μεταγλώττισης, που χρησιμοποιεί τους διακόπτες μεταγλώττισης που αναφέρθηκαν, παρουσιάζεται στη συνέχεια και αφορά τον κώδικα 1.3.
Αν, όμως, χρησιμοποιηθεί η ακόλουθη εντολή μεταγλώττισης τότε το εκτελέσιμο θα λάβει το όνομα ch1_p2, η μεταγλώττιση θα γίνει σύμφωνα με το πρότυπο C17 και θα εμφανιστούν 5 warnings, που προειδοποιούν για τις επικίνδυνες καταστάσεις που περιγράφονται στα σχόλια του κώδικα.
$ gcc ch1_p2.c -o ch1_p2 -std=c17 -Wall -Wextra -pedantic
./ch1_p2
ch1_p2.c:3:20: warning: unused parameter 'b' [-Wunused-parameter]
int fun(int a, int b) {
^
ch1_p2.c:11:9: warning: zero size arrays are an extension [-Wzero-length-array]
int z[0]; // πίνακας με μέγεθος μηδέν (εντοπίζεται με το -pedantic)
^
ch1_p2.c:10:7: warning: unused variable 'y' [-Wunused-variable]
int y = 1729; // μεταβλητή που δεν χρησιμοποιείται (εντοπίζεται με το -Wall)
^
ch1_p2.c:11:7: warning: unused variable 'z' [-Wunused-variable]
int z[0]; // πίνακας με μέγεθος μηδέν (εντοπίζεται με το -pedantic)
^
ch1_p2.c:13:18: warning: variable 'x' is uninitialized when used here [-Wuninitialized]
printf("x=%d", x);
^
ch1_p2.c:9:8: note: initialize the variable 'x' to silence this warning
int x; // μεταβλητή που δεν έχει αρχικοποιηθεί (εντοπίζεται με το -Wall)
^
= 0
5 warnings generated.
1.7 Πηγές πληροφόρησης για τη C
Οι πηγές πληροφόρησης για τη C είναι πάρα πολλές, σε βαθμό που είναι πραγματικά δύσκολο να εντοπιστούν αυτές που θα έδιναν το καλύτερο δυνατό αποτέλεσμα σε οποιονδήποτε επιθυμεί να μάθει τη γλώσσα. Η κατάσταση περιπλέκεται, καθώς η αποτελεσματικότητα του υλικού εξαρτάται από τις προσωπικές προτιμήσεις του κάθε μαθητευόμενου. Το τελευταίο διάστημα δημοφιλής γίνεται η υποβοηθούμενη εκμάθηση από LLMs (Large Language Models), όπως το chatGPT της OpenAI, όπου μπορεί κανείς να θέσει ερωτήσεις προγραμματισμού και να λάβει απαντήσεις σε κώδικα C (ή σε κώδικα άλλων γλωσσών προγραμματισμού) μαζί με την επεξήγησή του. Επίσης, πλατφόρμες όπως το Discord, φιλοξενούν ενεργές κοινότητες για προγραμματισμό με τη C (π.χ. Together C & C++), ενώ πολλοί επιλέγουν να μάθουν μια γλώσσα προγραμματισμού, όπως η C, μέσα από βίντεο κυρίως στο YouTube αλλά και από άλλες πλατφόρμες, όπως το Twitch. Μαζικά online μαθήματα προσφέρουν διαδρομές εκμάθησης που προσομοιάζουν παραδοσιακά ακαδημαϊκά μαθήματα και που συνδυάζουν παρακολούθηση μαθημάτων, μελέτη εκπαιδευτικού υλικού, υποβολή προγραμματιστικών εργασιών, κουίζ κ.ά. (π.χ. CS50: Introduction to Computer Science on EdX). Σημαντική είναι η βοήθεια που μπορούν να προσφέρουν έμπειροι προγραμματιστές και με τις συμβουλές τους να επιταχύνουν τη διαδικασία μετατροπής αρχάριων προγραμματιστών σε επαγγελματίες προγραμματιστές C. Πέρα από ό,τι ήδη αναφέρθηκε, οι πηγές πληροφόρησης που αναφέρονται στις ακόλουθες παραγράφους μπορούν να βοηθήσουν στην εκμάθηση της γλώσσας C, αλλά και στην υιοθέτηση κουλτούρας καλλιέργειας ενδιαφέροντος για την ποιότητα του λογισμικού που παράγεται αλλά και συνεχούς επικαιροποίησης και βελτίωσης των γνώσεων για τη γλώσσα C.
1.7.1 Βιβλία
Το κλασικό βιβλίο εκμάθησης της γλώσσας αναφέρθηκε ήδη και είναι το “The C Programming Language”3, ενώ ένα ακόμα εξαιρετικό βιβλίο είναι το “Expert C Programming: deep C secrets” από τον Peter van der Linden 4. Επίσης, το βιβλίο “C: A reference manual” των Samuel Harbison και Guy Steele 5 αποτελεί μια πολύ καλή πηγή για τη βιβλιοθήκη της γλώσσας. Μερικά νεότερα βιβλία που περιγράφουν και τα νέα χαρακτηριστικά της C, όπως αυτή έχει εξελιχθεί είναι το “21st century C: C tips from the new school” 6 από τον Ben Klemens, το “Effective C: An Introduction to Professional C Programming” του Robert Seacord 7 και το “Modern C” του Jens Gustedt 8 που είναι για προχωρημένους.
1.7.2 Ο οργανισμός ACCU
Ο οργανισμός ACCU (Association of C and C++ Users) έχει ιδρυθεί το 1987, αρχικά, ως ομάδα χρηστών με ενδιαφέρον στην ποιοτική ανάπτυξη κώδικα. Διοργανώνει το ετήσιο συνέδριο ACCU και εκδίδει δύο περιοδικά, το Overload και το CVu, που περιέχουν πληθώρα άρθρων σχετικών με τη C και, κυρίως, τη C++. Το Overload διατίθεται δωρεάν, όπως δωρεάν είναι και η πρόσβαση σε φόρουμς (π.χ. accu-general). Το CVu έχει διάφορες στήλες που παρουσιάζουν κώδικα σε C ή C++ μαζί με σχολιασμό.
1.7.3 WG14
H ISO/IEC JTC1/SC22/WG14 είναι η διεθνής ομάδα εργασίας προτυποποίησης της C. Η σελίδα της ομάδας εργασίας, όπου δημοσιεύεται οτιδήποτε σχετικό με την πορεία προτυποποίησης, είναι η https://www.open‐std.org/JTC1/SC22/wg14/. Εκεί μπορεί κανείς να εντοπίσει χρήσιμες πληροφορίες αλλά και λεπτομέρειες για τα πρότυπα της γλώσσας C.
1.7.4 Ιστοσελίδες
Το stackoverflow έχει δικαίως αποκτήσει τη φήμη της κοινότητας στην οποία οι προγραμματιστές μπορούν να αναζητούν απαντήσεις υψηλής ποιότητας σε δικά τους ερωτήματα ή σε ερωτήματα άλλων ακόμα και για τα πλέον απαιτητικά θέματα τεχνολογίας. Μάλιστα, η stackoverflow ιστοσελίδα https://stackoverflow.com/tags/c/info αφορά ερωτήσεις αποκλειστικά για τη C. Ενδιαφέρουσες συζητήσεις για τη C διεξάγονται στο φόρουμ https://groups.google.com/g/comp.lang.c, ενώ απαντήσεις σε συχνές ερωτήσεις για τη C μπορούν να εντοπιστούν στο https://c‐faq.com/. To reddit έχει, επίσης, κοινότητες αφιερωμένες στη C, όπως την https://www.reddit.com/r/C_Programming/, που αξίζει κανείς να επισκεφτεί. Μια ακόμα χρήσιμη ιστοσελίδα είναι η https://en.cppreference.com/w/c, που αποτελεί σημείο αναφοράς για την πρότυπη βιβλιοθήκη της C και τις δυνατότητές της. Τέλος, αξίζει να αναφερθεί η εξαιρετική προσπάθεια του Brian Hall τόσο στο “Beej’s Guide to C Programming” (https://beej.us/guide/bgc/)όσο και στο “Beej’s Guide to C Programming—Library Reference” (https://beej.us/guide/bgclr/), που περιγράφει τόσο τη γλώσσα C όσο και την πρότυπη βιβλιοθήκη της.
1.7.5 Blogs
Χρήσιμες και ενδιαφέρουσες είναι και οι τακτικές δημοσιεύσεις σε blogs με θέμα τη C, που γίνονται από τους Chris Wellons στο https://nullprogram.com/, Jens Gustedt στο https://gustedt.wordpress.com/, JeanHeyd Meneide στο https://thephd.dev/, Jakub Łukasiewicz στο https://jorengarenar.github.io/#blog, Dan Gookin στο https://c‐for‐dummies.com/blog/ και άλλους.
1.8 Ασκήσεις
Άσκηση 1
Γράψτε πρόγραμμα που να εμφανίζει σε διαδοχικές γραμμές το όνομά σας και τη διεύθυνσή σας. Μεταγλωττίστε και εκτελέστε το πρόγραμμα. Εξετάστε τα μεγέθη σε bytes του αρχείου πηγαίου κώδικα και του αρχείου εκτελέσιμου κώδικα.
- Τι παρατηρείτε;
Άσκηση 2
Μεταγλωττίστε και εκτελέστε τον κώδικα της παραγράφου 1.6. Δοκιμάστε να εισαγάγετε ένα προς ένα τα ακόλουθα λάθη στον κώδικα:
- Διαγραφή μιας από τις δύο αγκύλες του κώδικα.
- Διαγραφή μιας από τις δύο παρενθέσεις της printf.
- Διαγραφή της γραμμής που περιέχει το #include.
- Εισαγωγή τυπογραφικού σφάλματος στη γραφή του main (π.χ. εισάγετε mian).
- Εισαγωγή τυπογραφικού σφάλματος στη γραφή του printf.
- Διαγραφή του ερωτηματικού στο τέλος της εντολής printf
Παρατηρήστε τα μηνύματα που εμφανίζει ο μεταγλωττιστής. Καταγράψτε ποια από αυτά, κατά τη γνώμη σας, περιγράφουν με σαφήνεια την πηγή του λάθους και ποια είναι δυσνόητα ή ακόμα και παραπλανητικά.
-
Stephen Kell. “Some were meant for C: the endurance of an unmanageable language”. Στο: Proceedings of the 2017 ACM SIGPLAN International Symposium on New Ideas, New Paradigms, and Reflections on Programming and Software. 2017, σσ. 229–245. ↩
-
David Chisnall. “C is not a low-level language”. Στο: Communications of the ACM 61.7 (2018), σσ. 44–48. ↩
-
D.M. Ritchie και B.W. Kernighan. The C programming language, 2nd edition. Pearson, 1988. ↩↩
-
Peter Van der Linden. Expert C programming: deep C secrets. Prentice Hall Professional, 1994. ↩
-
Samuel P Harbison και Guy L Steele. C: A reference manual. Prentice Hall PTR, 2002. ↩
-
Ben Klemens. 21st century C: C tips from the new school. ” O’Reilly Media, Inc.”, 2014. ↩
-
Robert C Seacord. Effective C: An Introduction to Professional C Programming. No Starch Press, 2020. ↩
-
Jens Gustedt. Modern C. Manning, 2019. ↩