Προεπεξεργαστής της C. C Preprocessor. Προγραμματισμός II 1

Σχετικά έγγραφα
Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

Προεπεξεργαστής C. Προγραμματισμός Ι 1

Προγραμματισμός Ι. Προεπεξεργαστής. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός Ι (HY120)

Προγραμματισμός σε C. Πράξεις με bits (bitwise operators)

Προγραμματισμός Υπολογιστών με C++

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

Εισαγωγή στον Προγραμματισμό

Μεταγλώττιση και σύνδεση πολλαπλών αρχείων κώδικα. Προγραμματισμός II 1

Προγραµµατισµός Ι (ΗΥ120)

Κεφάλαιο : Εισαγωγή στην C: (Διαλέξεις 3-4)

Η γλώσσα προγραμματισμού C

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Ι (ΗΥ120)

double sum(double a, double b) { return(a+b); } double my_avg(double a, double b) { return(sum(a, b)/2.0); }

Δομημένος Προγραμματισμός

Προγραμματισμός Ι (ΗΥ120)

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Προγραμματισμός Ι (HY120)

Εισαγωγή στην γλώσσα προγραμματισμού C

Εισαγωγή στο Bison. Μεταγλωττιστές, Χειμερινό εξάμηνο

Διαδικασία Ανάπτυξης Λογισμικού

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Βιβλιοθήκες Αφηρημένοι τύποι δεδομένων. Προγραμματισμός II 1

Εισαγωγή στο Flex. Μεταγλωττιστές, Χειμερινό εξάμηνο

που θα δώσει αποτέλεσµα 48, λόγω της αριστερής προσεταιριστικότητας των τελεστών / και *, ενώ η επιθυµητή αντικατάσταση θα ήταν η

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ Ενδεικτικές Απαντήσεις Εξετάσεων Β' Περιόδου Θέµα 1. (α')

make Προγραμματισμός II 1

Δομημένος Προγραμματισμός (ΤΛ1006)

Εισαγωγή στον Προγραμματισμό

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Κεφάλαιο : Εισαγωγή στην C. ( ιαλέξεις 3-4) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Εξοικείωση με το πρόγραμμα DEV C++ Επικοινωνία Χρήστη - Υπολογιστή

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Κεφάλαιο 4: Συνθήκες Έλεγχου (if-else, switch) και Λογικοί τελεστές / παραστάσεις. (Διάλεξη 8)

TMHMA TEXNΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΤΗΛ/ΝΙΩΝ Προγραμματισμός Ι ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ , Α ΕΞΑΜΗΝΟ Βασίλης Μποζαντζής. Βασίλης Μποζαντζής

Αρχεία Κεφαλίδων ΑΡΧΕΙΑ ΚΕΦΑΛΙΔΩΝ. Γεώργιος Παπαϊωάννου ( )

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Γλώσσα Προγραμματισμού C

Προγραμματισμός Ι (ΗΥ120)

Ανάπτυξη Μεγάλων Εφαρµογών στη Γλώσσα C (2)

Προγραμματισμό για ΗΜΥ

ΕΡΓΑΣΤΗΡΙΟ 1 ΕΙΣΑΓΩΓΗ ΣΤΗ C. Τµήµα Πληροφορικής και Τηλεπικοινωνιών

Δομημένος Προγραμματισμός (ΤΛ1006)

ΠΑΝΕΠΙΣΤΗΜΙΟ ΚΥΠΡΟΥ ΕΠΛ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΕΘΟΔΩΝ ΕΠΙΛΥΣΗΣ ΠΡΟΒΛΗΜΑΤΩΝ

int a[5]; a[0] a[1] a[2] a[3] a[4] 15/10/2009

Προγραμματισμός Ι. Πολλαπλά Αρχεία. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Επεξεργασία Αρχείων Κειµένου

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ. Ασκήσεις Επανάληψης

Διαδικασιακός Προγραμματισμός

ΕΙΣΑΓΩΓΗ ΣΤΟN ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Διαδικαστικός Προγραμματισμός

Παρακάτω δίνεται o σκελετός προγράμματος σε γλώσσα C. Σχολιάστε κάθε γραμμή του κώδικα.

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

3 &4. Εισαγωγήστη C Ιωάννης Κατάκης

Προγραμματισμός Η/Υ (ΤΛ2007 )

Εργαστήριο 08 Εισαγωγή στo Yacc

Εισαγωγή στον Προγραμματισμό

Αρχές Προγραμματισμού

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

Ανάπτυξη και Σχεδίαση Λογισμικού

Η πρώτη παράμετρος είναι ένα αλφαριθμητικό μορφοποίησης

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

ΕΠΛ232 Προγραμματιστικές Τεχνικές και Εργαλεία Οργάνωση Προγραμμάτων σε Πολλαπλά Αρχεία (Κεφάλαιο , KNK-2ED)

Εισαγωγή στο Bison. Μεταγλωττιστές, Χειμερινό εξάμηνο

Προγραμματισμός I (Θ)

Εκφωνήσεις ασκήσεων εργαστηρίου 1

CE121 Προγραµµατισµός 2. Εισαγωγή σε Makefiles. CE121 -

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Γλώσσα Προγραμματισμού C++ Εισαγωγή - Μια πρώτη ματιά

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Στόχοι και αντικείμενο ενότητας. Προτάσεις επανάληψης. Έλεγχος ροής προγράμματος. #5.. Εντολές Επανάληψης

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Δομημένος Προγραμματισμός (ΤΛ1006)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Ασκήσεις σε Επαναληπτικούς Βρόχους και Συναρτήσεις. Επανάληψη για την ενδιάμεση εξέταση. (Διάλεξη 13)

Εισαγωγή στον Προγραµµατισµό. Πανεπιστήµιο Θεσσαλίας Τµήµα Ηλεκτρολόγων Μηχανικών και Μηχανικών Η/Υ

Διάλεξη 11: Οργάνωση Προγραμμάτων σε Πολλαπλά Αρχεία

Γλώσσα Προγραμματισμού C. Προγραμματισμός HY: Γλώσσα Προγραμματισμού C. Γρήγορος Πίνακας Αναφοράς Σύνταξης. Εισήγηση #4. Επαναληπτικές δομές:

Α' Εξάμηνο ΕΙΣΑΓΩΓΗ ΣΤΟ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

Κεφάλαιο 1 Εισαγωγή στη C

Μεταγλωττιστές. Εργαστήριο 5. Εισαγωγή στο BISON. Γεννήτρια Συντακτικών Αναλυτών. 2 η Φάση Μεταγλώττισης Συντακτική Ανάλυση

Παράμετροι 19/9/2007. Πέρασμα παραμέτρων. Περιεχόμενα. Θέσεις και ονόματα στο ταίριασμα παραμέτρων. Ταίριασμα παραμέτρων μέσω ονομάτων

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Ανάπτυξη και Σχεδίαση Λογισμικού

Λειτουργικά Συστήματα

Διδάσκων: Δημήτριος Βαρσάμης

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Transcript:

Προεπεξεργαστής της C C Preprocessor Προγραμματισμός II 1 lalis@inf.uth.gr

Τι κάνει ο προεπεξεργαστής; Ο προεπεξεργαστής (pre-proccesor) της C είναι ένα πρόγραμμα που μετασχηματίζει τον πηγαίο κώδικα προτού περαστεί στον μεταγλωττιστή (gcc -E) Πραγματοποιεί αλλαγές σε επίπεδο κειμένου, με την μορφή «απλών» αντικαταστάσεων χαρακτήρων Δεν γίνεται έλεγχος της συντακτικής ορθότητας Οι πιο χαρακτηριστικές χρήσεις: μακροεντολές εισαγωγή κειμένου υπό συνθήκη αντιγραφή κειμένου από άλλα αρχεία Προγραμματισμός II 2 lalis@inf.uth.gr

Px preproc P x compiler x -> y P y CPU y Προγραμματισμός II 3 lalis@inf.uth.gr

Ορισμός μακροεντολών #define <macro> <expr> Ορίζει μακροεντολή <macro> που θα αντικατασταθεί (κάθε φορά που εντοπίζεται στον κώδικα του προγράμματος) με την έκφραση <expr> Οι μακροεντολές δεν είναι συναρτήσεις Σημείωση 1: χρειάζεται προσοχή (παρενθέσεις) έτσι ώστε να αποφεύγονται λάθη με τελεστές που ακολουθούν στο κείμενο του προγράμματος Σημείωση 2: χρειάζεται προσοχή με «παραμέτρους» των macros καθώς αυτές αποτιμώνται κάθε φορά που εμφανίζονται στην έκφραση Προγραμματισμός II 4 lalis@inf.uth.gr

/* symbolic constant */ #define N 100 int t[n]; for (i=0; i < N; i++ ) { if (i == N) { Προγραμματισμός II 5 lalis@inf.uth.gr

/* symbolic constant, one more time */ #define N 10*10 int t[n]; for (i=0; i < N; i++ ) { if (i == N) { Προγραμματισμός II 6 lalis@inf.uth.gr

/* sequence of symbolic constants */ #define A 10 #define B 20 #define C (A+B) #define D (C*Β) Προγραμματισμός II 7 lalis@inf.uth.gr

/* macro */ #define LOWERCASE(a) (a- 'A' + 'a') int main(int argc, char *argv[]) { char c; do { c=getchar(); if ((c >= 'A') && (c <= 'Z')) { c=lowercase(c); putchar(c); while (c!= '\n'); return(0); Προγραμματισμός II 8 lalis@inf.uth.gr

/* macro, differently */ #define LOWERCASE(a) (((a>='a') && (a<='z'))? a-'a'+'a' : a) int main(int argc, char *argv[]) { char c; do { c=getchar(); putchar(lowercase(c)); while (c!= '\n'); return(0); Προγραμματισμός II 9 lalis@inf.uth.gr

/* macro, yet another option */ #define PUTLOWERCASE(a) ( \ { if ((a<'a') (a>'z')) { putchar(a); \ else { puchar(a-'a'+'a'); \ \ ) int main(int argc, char *argv[]) { char c; do { c=getchar(); PUTLOWERCASE(c); while (c!= '\n'); return(0); Προγραμματισμός II 10 lalis@inf.uth.gr

/* the wrong way: too lazy to use brackets */ #define PLUSONE(x) x+1 int main(int argc, char *argv[]) { int i,j; scanf("%d",&i); j=plusone(i)*2; printf("%d\n",j); return(0); Προγραμματισμός II 11 lalis@inf.uth.gr

/* the right way */ #define PLUSONE(x) (x+1) int main(int argc, char *argv[]) { int i,j; scanf("%d",&i); j=plusone(i)*2; printf("%d\n",j); return(0); Προγραμματισμός II 12 lalis@inf.uth.gr

/* repeated evaluation of pseudo-parameters */ #define SQUARE(a) ((a)*(a)) int main(int argc, char *argv[]) { int i,j; scanf("%d",&i); j=square(++i); printf("%d\n",j); return(0); Προγραμματισμός II 13 lalis@inf.uth.gr

Προ-ορισμένες μακροεντολές DATE TIME FILE func LINE STDC date of compilation as a string literal in "MMM DD YYYY" format time of compilation as a string literal in "HH:MM:SS" format source code filename as a string literal function name as a string literal line number in the source file as a decimal constant equal to the decimal value 1 if the compiler complies with the ANSI standard Προγραμματισμός II 14 lalis@inf.uth.gr

#include <stdio.h> int main (int argc, char *argv[]) { printf("file: %s\n", FILE ); printf("date: %s\n", DATE ); printf("time: %s\n", TIME ); printf("function:%s\n", func ); printf("line: %d\n", LINE ); printf("ansi: %d\n", STDC ); return(0); File: predefined.c Date: Dec 21 2014 Time: 23:57:58 Function: main Line: 8 ANSI: 1 Προγραμματισμός II 15 lalis@inf.uth.gr

Stringize (#) Μετατρέπει παράμετρο μακροεντολής σε string #include <stdio.h> #define message_for(a, b, c) \ printf(#a " and " #b " and " #c ": hello\n") int main(int argc, char *argv[]) { message_for(carole, Debra, 42); return 0; Carole and Debra and 42: hello Προγραμματισμός II 16 lalis@inf.uth.gr

Συνένωση tokens (##) Συνενώνει παραπάνω από μία παραμέτρους της μακροεντολής σε μία #include <stdio.h> #define tokenpaster(n) \ printf ("token%s = %d\n", #n, token##n) int main(int argc, char *argv[]) { int token34 = 40; tokenpaster(34); return 0; token34 = 40 Προγραμματισμός II 17 lalis@inf.uth.gr

Εισαγωγή υπό συνθήκη #if, #else, #elif, #endif #ifdef, #ifndef Συνθήκες πάνω σε συμβολικά ονόματα Αν μια συνθήκη ισχύει τότε το αντίστοιχο κείμενο συμπεριλαμβάνεται για μετάφραση, διαφορετικά όχι το κείμενο που συμπεριλαμβάνεται / αφαιρείται μπορεί να είναι οτιδήποτε (δεν χρειάζεται να αντιστοιχεί σε κάποια συντακτική ενότητα) Κλασικές χρήσεις: επιλογή ανάμεσα σε διαφορετικές εκδόσεις του κώδικα (κώδικας αποσφαλμάτωσης, υποστήριξη για διαφορετικές πλατφόρμες κλπ) αποφυγή διπλής εισαγωγής κειμένου (βλέπε #include) Προγραμματισμός II 18 lalis@inf.uth.gr

#define DEBUG #ifdef DEBUG /* ή #if defined(debug) */ /* my debugging code */ #endif Προγραμματισμός II 19 lalis@inf.uth.gr

#define DEBUG aaaaaaaaa #ifdef DEBUG bbbbbbbbb #endif aaaaaaaaa bbbbbbbbb ccccccccc ccccccccc Προγραμματισμός II 20 lalis@inf.uth.gr

#define DEBUG #ifdef DEBUG /* ή #if defined(debug) */ /* my debugging code */ #endif Προγραμματισμός II 21 lalis@inf.uth.gr

#define DEBUG aaaaaaaaa #ifdef DEBUG bbbbbbbbb #endif aaaaaaaaa ccccccccc ccccccccc Προγραμματισμός II 22 lalis@inf.uth.gr

// test.c #include <stdio.h> int main(int argc, char *argv[]) { #ifdef DEBUG printf("debug code\n"); #else printf("release code\n"); #endif $ gcc -D DEBUG test.c -o test $./test Debug code $ $ gcc test.c -o test $./test Release code $ Προγραμματισμός II 23 lalis@inf.uth.gr

// test.c #include <stdio.h> int main(int argc, char *argv[]) { #if OPTION == 1 printf("code option 1\n"); #elif OPTION == 2 printf("code option 2\n"); #else printf("default code\n"); #endif $ gcc -D OPTION=2 test.c -o test $./test Code option 2 $ $ gcc test.c -o test $./test Default code $ Προγραμματισμός II 24 lalis@inf.uth.gr

#ifndef INCL_X /* ή #if!defined(incl_x) */ #define INCL_X /* avoid recursive inclusion */ /* my code */ #endif Προγραμματισμός II 25 lalis@inf.uth.gr

Εισαγωγή αρχείων #include "filename" Τα περιεχόμενα του αρχείου filename εισάγονται ακριβώς στο σημείο που εμφανίζεται η εντολή αν το αρχείο δεν βρίσκεται στον κατάλογο εργασίας, ο κατάλογος πρέπει να δίνεται ως μέρος του ονομάτος αν το όνομα δίνεται σε < > αντί " ", ο προεπεξεργαστής θεωρεί ότι το αρχείο βρίσκεται στον κατάλογο όπου υπάρχουν τα header files της C, π.χ. /usr/include Αν το αρχείο που εισάγεται περιέχει και αυτό με την σειρά του εντολές #include τότε γίνεται εισαγωγή και αυτών των αρχείων μέσα στο αρχείο Προγραμματισμός II 26 lalis@inf.uth.gr

/* αρχείο file1 */ /* αρχείο file2 */ #include "file1" /* αρχείο file2 */ /* αρχείο file1 */ Προγραμματισμός II 28 lalis@inf.uth.gr

/* αρχείο file1 */ /* αρχείο file2 */ #include "file1" /* αρχείο file3 */ #include "file2" cccccccccc cccccccccc cccccccccc /* αρχείο file3 */ /* αρχείο file2 */ /* αρχείο file1 */ cccccccccc cccccccccc cccccccccc Προγραμματισμός II 29 lalis@inf.uth.gr

/* myprog_min.h */ #define min(a,b) ((a)<(b)? (a) : (b)) /* myprog_max.h */ #define max(a,b) ((a)>(b)? (a) : (b)) /* myprog_main.c */ #include "myprog_min.h" #include "myprog_max.h int main(int argc, char *argv[])) { int a,b; scanf("%d %d",&a,&b); printf("%d %d\n",min(a,b),max(a,b)); return(0); Προγραμματισμός II 30 lalis@inf.uth.gr

Αποφυγή επανειλημμένης εισαγωγής Ένα αρχείο μπορεί να εισάγει με την σειρά του (έμμεσα) επιπλέον αρχεία, τα οποία μπορεί να εισάγονται ξανά από το κυρίως πρόγραμμα Η διπλή εισαγωγή μπορεί να είναι ανεπιθύμητη π.χ. διπλή εισαγωγή μεταβλητών και συναρτήσεων που οδηγεί (στη μετάφραση) σε συντακτικά λάθη Λύση 1: ο προγραμματιστής πρέπει να γνωρίζει ποιά αρχεία εισάγουν (έμμεσα) τα αρχεία που εισάγει στο πρόγραμμα του (άμεσα) μη πρακτικό, άκομψο Λύση 2: το ίδιο το αρχείο φροντίζει να μην μπορεί να εισαχθεί δύο φορές στο ίδιο κείμενο κλασική περίπτωση χρήσης του #ifndef Προγραμματισμός II 31 lalis@inf.uth.gr

/* αρχείο file1 */ /* αρχείο file2 */ #include "file1" /* αρχείο file3 */ #include "file2" #include "file1" cccccccccc cccccccccc /* αρχείο file3 */ /* αρχείο file2 */ /* αρχείο file1 */ /* αρχείο file1 */ cccccccccc cccccccccc Προγραμματισμός II 32 lalis@inf.uth.gr

#ifndef INC_FILE1 #define INC_FILE1 /* αρχείο file1 */ #endif /* αρχείο file2 */ #include "file1" /* αρχείο file3 */ #include "file2" #include "file1" /* αρχείο file3 */ /* αρχείο file2 */ /* αρχείο file1 */ cccccccccc cccccccccc cccccccccc cccccccccc Προγραμματισμός II 33 lalis@inf.uth.gr

/* myprog_min.h */ #ifndef INCL_MYPROGMIN #define INCL_MYPROGMIN #define min(a,b) ((a)<(b)? (a) : (b)) #endif /* myprog_max.h */ #include "myprog_min.h" #define max(a, b) ({\ int res;\ if ((a) == min((a),(b))) res = (b); else res = (a); \ res; \ ) /* myprog_main.c */ #include "myprog_min.h" #include "myprog_max.h" int main(int argc, char *argv[]) { int a,b; scanf("%d %d",&a,&b); printf("%d %d\n",min(a,b),max(a,b)); return(0); Προγραμματισμός II 34 lalis@inf.uth.gr