Οδηγός Μελέτης - Εισαγωγή στον Προγραμματισμό

Διάλεξη 9 · 31/10/2025 · Διαφάνειες (PDF) · Σημειώσεις 1 · Σημειώσεις 4 · Σημειώσεις 5 · Σημειώσεις 9 · Εργαστήριο 4

Κεφάλαιο 9: Δεδομένα Εισόδου

Στόχοι: μετά από αυτό το κεφάλαιο θα μπορείτε να εξηγείτε γιατί η σύγκριση float με == είναι επικίνδυνη, να ονομάζετε τις τέσσερις πηγές δεδομένων εισόδου, να διαβάζετε χαρακτήρες με getchar μέχρι το EOF και να τους γράφετε με putchar, να εξηγείτε τον ρόλο του buffer και του Ctrl+D, και να διαβάζετε αριθμούς με scanf ελέγχοντας την τιμή επιστροφής της.

Προαπαιτούμενα: Κεφάλαιο 2, Κεφάλαιο 6, Κεφάλαιο 8

Χρόνος μελέτης: ~2 ώρες

Σύνοψη

Ένα πρόγραμμα παίρνει δεδομένα εισόδου, τα επεξεργάζεται και παράγει δεδομένα εξόδου. Η διάλεξη ξεκινά με δύο διευκρινίσεις (γιατί ένα float δεν είναι «ίσο» με το 3.1 και πώς ονομάζουμε συναρτήσεις) και περνάει στις τέσσερις πηγές εισόδου: ορίσματα γραμμής εντολών, πρότυπη είσοδο (stdin), αρχεία και δίκτυο. Εστιάζει στην πρότυπη είσοδο: στη getchar, που διαβάζει έναν χαρακτήρα τη φορά και επιστρέφει EOF στο τέλος, στην αδελφή της putchar, και στη scanf, τη «συμμετρική» της printf για διάβασμα. Στην πορεία βλέπουμε τρεις κλασικές παγίδες: char αντί για int για την τιμή της getchar, scanf χωρίς &, και scanf χωρίς έλεγχο της τιμής επιστροφής. Σχεδόν κάθε εργασία του μαθήματος διαβάζει είσοδο, οπότε αυτά τα εργαλεία θα τα χρησιμοποιείτε συνέχεια.

Θεωρία

§9.1 Σύγκριση αριθμών κινητής υποδιαστολής με ==

Ο τελεστής == ελέγχει αν δύο τιμές είναι ακριβώς ίσες. Οι αριθμοί κινητής υποδιαστολής (floating point) αποθηκεύονται σε δυαδική μορφή, και οι περισσότεροι δεκαδικοί, όπως το 3.1, δεν αναπαρίστανται ακριβώς: αποθηκεύεται η πλησιέστερη τιμή που χωράει. Το float (συνήθως 4 bytes) κρατά λιγότερα ψηφία από το double (8 bytes), και μια σταθερά όπως το 3.1 είναι double. Έτσι, μετά το float a = 3.1; το a κρατά περίπου 3.0999999046, ενώ στο a == 3.1 η σύγκριση γίνεται σε double με το 3.1000000000…: οι τιμές διαφέρουν και η συνθήκη είναι ψευδής (δείτε το παράδειγμα).

Κανόνας: μη συγκρίνετε αριθμούς κινητής υποδιαστολής με ==. Ελέγξτε αν η απόλυτη διαφορά τους είναι μικρότερη από μια μικρή ανοχή, π.χ. fabs(a - 3.1) < 1e-6 (η fabs είναι στο math.h).

§9.2 Ονόματα: camelCase και snake_case

Για ονόματα από πολλές λέξεις υπάρχουν δύο συνηθισμένα στυλ: camelCase, όπου κάθε λέξη μετά την πρώτη ξεκινά με κεφαλαίο (piApprox), και snake_case, με μικρά γράμματα και κάτω παύλα (pi_approx). Για κώδικα C (και Python) η διάλεξη συνιστά snake_case: το pi_approx είναι (υποκειμενικά) καλύτερο από το piApprox. Ο μεταγλωττιστής δέχεται και τα δύο· σημασία έχει να τηρείτε ένα στυλ.

§9.3 Δεδομένα εισόδου και εξόδου

Κάθε πρόγραμμα παίρνει δεδομένα εισόδου (input data), τα επεξεργάζεται και παράγει δεδομένα εξόδου (output data).

flowchart LR
  I["Input Data"] --> P["Program"] --> O["Output Data"]

Σχήμα: το πρόγραμμα μετατρέπει δεδομένα εισόδου σε δεδομένα εξόδου.

Τα δεδομένα εισόδου είναι μια σειρά από χαρακτήρες (bytes) που δίνει ο χρήστης στο πρόγραμμα. Όταν πληκτρολογείτε τον «αριθμό» 42, το πρόγραμμα λαμβάνει δύο χαρακτήρες, '4' και '2'· η μετατροπή τους σε ακέραιο είναι δική του δουλειά.

§9.4 Οι τέσσερις πηγές εισόδου

  1. Ορίσματα στη γραμμή εντολών (command-line arguments), π.χ. ./grade 80 100 90.
  2. Πρότυπη είσοδος (standard input, stdin): κείμενο που γράφουμε, συνήθως με το πληκτρολόγιο, ενώ το πρόγραμμα τρέχει. Είναι το θέμα αυτής της διάλεξης.
  3. Αρχεία από το σύστημα αρχείων, όπως κάνει η cat hello.txt (επόμενες διαλέξεις).
  4. Δίκτυο ή άλλες πηγές, π.χ. ένα User Interface (επόμενα εξάμηνα). Η curl, για παράδειγμα, διαβάζει μια σελίδα από το δίκτυο.

Με τα δύο πρώτα έχουμε καλύψει το «50%». Η πρότυπη είσοδος δεν είναι υποχρεωτικά το πληκτρολόγιο: με ανακατεύθυνση (<) ή σωλήνωση (|) το ίδιο πρόγραμμα διαβάζει από αρχείο ή από την έξοδο άλλου προγράμματος, χωρίς να το «ξέρει».

§9.5 Η συνάρτηση getchar

Η getchar, με μορφή int getchar();, ορίζεται στο stdio.h. Δεν παίρνει όρισμα· διαβάζει έναν χαρακτήρα από το stdin, εάν υπάρχει, και τον επιστρέφει ως ακέραιο (τον κωδικό ASCII του). Αν δεν υπάρχει άλλος, επιστρέφει την ειδική τιμή EOF (End-Of-File, -1). Ο τύπος επιστροφής είναι int και όχι char ώστε να χωράει, εκτός από όλους τους δυνατούς χαρακτήρες, και το EOF, που δεν μπερδεύεται με κανέναν από αυτούς. Για τη συμπεριφορά μιας έτοιμης συνάρτησης της βιβλιοθήκης ανοίγουμε ένα τερματικό και τρέχουμε man getchar.

Κάθε κλήση διαβάζει τον επόμενο χαρακτήρα, οπότε το βασικό μοτίβο ανάγνωσης όλης της εισόδου είναι:

int ch;
while ((ch = getchar()) != EOF) {
  /* επεξεργασία του ch */
}

Οι παρενθέσεις γύρω από την ανάθεση είναι απαραίτητες: το != έχει μεγαλύτερη προτεραιότητα από το =, και χωρίς αυτές το ch θα έπαιρνε το αποτέλεσμα της σύγκρισης (0 ή 1).

flowchart TD
  A["ch = getchar()"] --> B{"ch != EOF;"}
  B -- "ναι" --> C["επεξεργασία του ch"]
  C --> A
  B -- "όχι" --> D["τέλος εισόδου"]

Σχήμα: ο βρόχος ανάγνωσης χαρακτήρων μέχρι το EOF.

§9.6 Buffer, Enter και Ctrl+D

Όταν πληκτρολογείτε, οι χαρακτήρες αποθηκεύονται προσωρινά σε έναν buffer (ενδιάμεση μνήμη) και προωθούνται στο πρόγραμμα όταν πατήσετε Enter, μαζί με την αλλαγή γραμμής '\n'. Αυτή η λειτουργία του τερματικού, με είσοδο ανά γραμμή, λέγεται canonical mode. Γι’ αυτό η getchar «περιμένει» το Enter, και γι’ αυτό η γραμμή BBB φτάνει ως τέσσερις χαρακτήρες: 'B', 'B', 'B', '\n'.

flowchart LR
  K["Πληκτρολόγιο"] --> B["buffer: 'B' 'B' 'B' και αλλαγή γραμμής"]
  B -- "Enter ή Ctrl+D" --> P["Program"]

Σχήμα: οι χαρακτήρες περιμένουν στον buffer μέχρι το Enter ή το Ctrl+D.

Για να δηλώσετε ότι τελείωσαν τα δεδομένα, στο Linux πατάτε συνήθως Ctrl+D. Το Ctrl+D προωθεί ό,τι υπάρχει στον buffer, χωρίς αλλαγή γραμμής. Αν ο buffer είναι άδειος (στην αρχή γραμμής), το πρόγραμμα δεν παίρνει τίποτα και η getchar επιστρέφει EOF· άρα, αν έχετε γράψει κάτι χωρίς Enter, χρειάζεται δεύτερο Ctrl+D. Όταν η είσοδος έρχεται από αρχείο (./prog < file) ή σωλήνωση, το EOF έρχεται μόνο του στο τέλος των δεδομένων.

§9.7 Η συνάρτηση putchar

Η putchar, με μορφή int putchar(int c);, ορίζεται επίσης στο stdio.h. Παίρνει έναν χαρακτήρα, τον τυπώνει στο stdout και τον επιστρέφει ως ακέραιο· αν κάτι πάει στραβά στο τύπωμα, επιστρέφει EOF. Για να τυπώσετε το C γράφετε putchar('C');. Είναι απλούστερο υποσύνολο της printf: το putchar(ch) κάνει ό,τι και το printf("%c", ch).

§9.8 Η τιμή της getchar πάει σε int, όχι σε char

Ένα char κρατά μόνο 256 τιμές, οπότε δεν μπορεί να ξεχωρίσει το EOF από κάθε πραγματικό χαρακτήρα. Στα συνηθισμένα συστήματα, όπου το char είναι προσημασμένο, το byte 0xff (255) αποθηκεύεται ως -1, δηλαδή ίσο με το EOF: ένα έγκυρο byte μοιάζει με τέλος εισόδου και το πρόγραμμα σταματά πρόωρα (δείτε την cat με char). Όπου το char είναι απρόσημο, το EOF γίνεται 255 και η σύγκριση με EOF δεν αληθεύει ποτέ, οπότε ο βρόχος δεν τελειώνει.

Κανόνας της διάλεξης: η μεταβλητή που δέχεται την τιμή της getchar δηλώνεται int, εκτός αν είμαστε σίγουροι για το τι κάνουμε.

§9.9 Διάβασμα αριθμών χαρακτήρα-χαρακτήρα

Με τη getchar μπορούμε να διαβάσουμε και αριθμούς, χτίζοντας την τιμή ψηφίο-ψηφίο: αν val είναι η τιμή των ψηφίων ως τώρα, ένα νέο ψηφίο d σε βάση base δίνει \(val \leftarrow base \cdot val + d\). Η τιμή του ψηφίου είναι ch - '0', επειδή τα '0'…'9' έχουν διαδοχικούς κωδικούς ASCII (48…57), και ένας χαρακτήρας είναι έγκυρο ψηφίο σε βάση έως 10 αν ch >= '0' && ch <= '0' + base - 1. Αυτό κάνει η getinteger. Υπάρχει όμως και έτοιμος τρόπος: η scanf.

§9.10 Η συνάρτηση scanf

Η scanf ορίζεται στο header file stdio.h και διαβάζει δεδομένα εισόδου πολλών τύπων από το stdin, αποθηκεύοντας τις τιμές τους σε μεταβλητές. Είναι η συμμετρική της printf, για διάβασμα αντί για εκτύπωση:

int scanf(const char *restrict format, ...);
int printf(const char *restrict format, ...);

Το πρώτο όρισμα είναι μια συμβολοσειρά μορφοποίησης (format string) με προδιαγραφές όπως %d (int) ή %f (float)· τα ... σημαίνουν ότι δέχεται όσα ορίσματα της περάσουμε, ένα για κάθε προδιαγραφή (θα το δούμε σε άλλο μάθημα).

Η μεγάλη διαφορά: στην printf δίνουμε τιμές, ενώ στη scanf τις διευθύνσεις των μεταβλητών, με τον τελεστή &: scanf("%d", &n). Η C περνάει τα ορίσματα με τιμή· με scanf("%d", n) η scanf θα έπαιρνε ένα αντίγραφο της τιμής του n και δεν θα μπορούσε να το αλλάξει. Με το &n μαθαίνει τη θέση του n στη μνήμη και γράφει εκεί την τιμή που διάβασε. Οι διευθύνσεις είναι το θέμα του Κεφαλαίου 11.

§9.11 Κενά και πολλές τιμές

Μία κλήση μπορεί να διαβάσει πολλές τιμές: scanf("%d %d", &n1, &n2). Καθώς ψάχνει για δεκαδικό ψηφίο, η %d προσπερνά κενούς χαρακτήρες και αλλαγές γραμμής πριν από τον αριθμό, οπότε η είσοδος ` 2 4 δίνει n1 = 2 και n2 = 4`, όπως και αν οι αριθμοί ήταν σε διαφορετικές γραμμές.

§9.12 Η τιμή επιστροφής της scanf

Η scanf επιστρέφει πόσα δεδομένα εισόδου διάβασε και αποθήκευσε. Αν η είσοδος τελειώσει πριν διαβάσει οτιδήποτε, επιστρέφει EOF. Για scanf("%d", &n):

Τιμή επιστροφής Σημασία Το n
1 διαβάστηκε ακέραιος έχει τη νέα τιμή
0 η είσοδος δεν ξεκινά με αριθμό (π.χ. hello) δεν άλλαξε
EOF τέλος εισόδου (π.χ. Ctrl+D) δεν άλλαξε

Αν δεν ελέγξουμε την τιμή επιστροφής και η ανάγνωση αποτύχει, το πρόγραμμα συνεχίζει με τα «σκουπίδια» μιας μη αρχικοποιημένης μεταβλητής. Άρα ένα πρόγραμμα που δεν ελέγχει τι επέστρεψε η scanf δεν είναι σωστό. Γράφουμε, για παράδειγμα, if (scanf("%d", &n) != 1) { printf("Invalid input\n"); return 1; }.

Παραδείγματα

§9.13 OK ή Not OK;

Εφαρμόζει τη σύγκριση με ==. Τι θα τυπώσει το παρακάτω πρόγραμμα;

#include <stdio.h>
int main() {
    float a = 3.1;

    if(a == 3.1)
       printf("OK\n");
    else
       printf("Not OK\n");
    return 0;
}
$ ./one
Not OK

Το a κρατά το 3.1 στρογγυλεμένο σε float, ενώ το 3.1 της σύγκρισης είναι double με μεγαλύτερη ακρίβεια. Με a == 3.1f (σταθερά float) θα τυπωνόταν OK, αλλά η ασφαλής λύση είναι η σύγκριση με ανοχή.

§9.14 Διαβάζω και τυπώνω έναν χαρακτήρα

Εφαρμόζει τη getchar και τον έλεγχο για EOF.

#include <stdio.h>
int main() {
  printf("Gimme a char: ");
  int ch = getchar();
  if (ch != EOF) {
    printf("You gave the char: %c\n", ch);
  } else {
    printf("input ended\n");
  }
  return 0;
}
$ ./chartest
Gimme a char: BBB
You gave the char: B

Η getchar διαβάζει μόνο έναν χαρακτήρα, το πρώτο B· τα BB\n μένουν αδιάβαστα. Αν πατήσετε αμέσως Ctrl+D, τυπώνεται input ended.

§9.15 Μετρητής χαρακτήρων

Διαδοχικές κλήσεις της getchar διαβάζουν διαδοχικούς χαρακτήρες. Τι κάνει το παρακάτω πρόγραμμα;

#include <stdio.h>
int main() {
  int ch, sum = 0;
  printf("Enter characters: ");
  while( (ch = getchar()) != EOF ) {
    printf("%c", ch);
    sum++;
  }
  printf("\nTotal characters: %d\n", sum);
  return 0;
}
$ ./charcount
Enter characters: we'll always have paris
we'll always have paris
Total characters: 24

Τυπώνει ξανά ό,τι διαβάζει και στο τέλος το πλήθος των χαρακτήρων. Η φράση έχει 23 χαρακτήρες· ο 24ος είναι το '\n' του Enter. Η γραμμή επαναλαμβάνεται μόλις πατήσετε Enter (τότε φτάνει ο buffer στο πρόγραμμα) και το σύνολο τυπώνεται με το Ctrl+D.

§9.16 Μια cat με char

Εφαρμόζει τις getchar/putchar και τον κανόνα «int, όχι char». Τι πρόβλημα έχει η παρακάτω υλοποίηση της cat;

#include <stdio.h>

int main() {
  char c;
  while((c = getchar()) != EOF)
    putchar(c);
  return 0;
}
$ echo -e "hello\xffworld" | ./cat
hello
$ echo -e "hello\xffworld" | cat
hello�world

Το echo -e βάζει το byte 0xff ανάμεσα στις δύο λέξεις. Η πραγματική cat το αντιγράφει (το τερματικό το δείχνει ως �). Η δική μας το αποθηκεύει στο char c ως -1, το βρίσκει ίσο με EOF και σταματά. Η διόρθωση είναι μία λέξη: int c;.

§9.17 Η συνάρτηση getinteger

Εφαρμόζει το διάβασμα αριθμών χαρακτήρα-χαρακτήρα. Θέλουμε ένα πρόγραμμα addnums που διαβάζει δύο αριθμούς και τους προσθέτει:

$ ./addnums
Give me a number: 40
Give me another number: 2
Total: 42

Ένας τρόπος είναι με τη getchar, φτιάχνοντας μια συνάρτηση getinteger που διαβάζει τους χαρακτήρες έναν-έναν και τους μετατρέπει σε αριθμό. Τι κάνει;

#define ERROR -1          // Return value for illegal character

int getinteger(int base) {
  int ch;                 // No need to declare ch as int - no EOF handling
  int val = 0;                               // Initialize return value
  while ((ch = getchar()) != '\n')           // Read up to new line
    if (ch >= '0' && ch <= '0' + base - 1)   // Legal character?
      val = base * val + (ch - '0');         // Update return value
    else
      return ERROR;                          // Illegal character read
  return val;   // Everything OK - Return value of number read
}

Διαβάζει μέχρι την αλλαγή γραμμής· για κάθε έγκυρο ψηφίο της βάσης ενημερώνει το val, και με τον πρώτο μη έγκυρο χαρακτήρα επιστρέφει ERROR (-1). Με είσοδο 42 σε βάση 10 το val γίνεται 4 και μετά 10 · 4 + 2 = 42· με getinteger(2) και είσοδο 101 γίνεται 1, 2, 5. Το addnums προκύπτει καλώντας τη δύο φορές. Ο άλλος τρόπος για το ίδιο αποτέλεσμα είναι η scanf. Στις σημειώσεις η ίδια συνάρτηση μετατρέπει δυαδικούς σε δεκαδικούς και αντίστροφα.

§9.18 Τετράγωνο με scanf

Εφαρμόζει τη scanf. Τι κάνει το παρακάτω πρόγραμμα;

#include <stdio.h>
int main() {
  int n;
  printf("Gimme a number: ");
  scanf("%d", &n);
  printf("Square: %d\n", n * n);
  return 0;
}

Περνάμε τη διεύθυνση της n (&n), ώστε η scanf να μπορέσει να αναθέσει την τιμή που διάβασε, και τυπώνουμε στο stdout το τετράγωνο του αριθμού που γράψαμε στο stdin. Τι θα γινόταν αν γράφαμε scanf("%d", n);;

$ ./scanf
Gimme a number: 3
Segmentation fault

Η scanf θα χρησιμοποιούσε την (μη αρχικοποιημένη) τιμή του n σαν διεύθυνση, και η εγγραφή σε μια τυχαία διεύθυνση που δεν ανήκει στο πρόγραμμα προκαλεί Segmentation fault. Ο gcc -Wall προειδοποιεί για αυτό το λάθος.

§9.19 Είναι σωστό αυτό το πρόγραμμα;

Εφαρμόζει την τιμή επιστροφής της scanf. Το τετράγωνο της προηγούμενης ενότητας δεν είναι σωστό, καθώς δεν ελέγχουμε την τιμή επιστροφής της scanf (EOF ή ίσως 0):

$ ./scanf
Gimme a number: 16
Square: 256
$ ./scanf
Gimme a number: Square:
1068701481
$ ./scanf
Gimme a number: hello
Square: 1072038564

Στη δεύτερη εκτέλεση πατήσαμε Ctrl+D (η scanf επέστρεψε EOF), στην τρίτη γράψαμε hello (επέστρεψε 0). Και στις δύο το n έμεινε με την τυχαία αρχική του τιμή και τυπώθηκε ένα «τετράγωνο» χωρίς νόημα.

§9.20 Δύο αριθμοί με μία scanf

Εφαρμόζει τα κενά και τις πολλές τιμές.

#include <stdio.h>
int main() {
  int n1, n2;
  printf("Gimme two numbers: ");
  scanf("%d %d", &n1, &n2);
  printf("Result: %d\n", n1 * n2);
  return 0;
}
$ ./scanf2
Gimme two numbers:   2   4
Result: 8

Τα επιπλέον κενά δεν ενοχλούν, αφού η %d τα προσπερνά ψάχνοντας για ψηφίο. Ένα σωστό πρόγραμμα θα έλεγχε και εδώ ότι η scanf επέστρεψε 2.

§9.21 Συχνότητες γραμμάτων

Εφαρμόζει τον βρόχο ανάγνωσης μέχρι το EOF και «προλαβαίνει» τους πίνακες του Κεφαλαίου 10. Τι κάνει ο κώδικας;

int i, ch, total = 0;
int letfr[26];  // Letter occurrences and frequencies array
for (i=0 ; i < 26 ; i++)
  letfr[i] = 0;
while ((ch = getchar()) != EOF) {
  if (ch >= 'A' && ch <= 'Z') {
    letfr[ch-'A']++;            // Found upper case letter
    total++;
  }
  if (ch >= 'a' && ch <= 'z') {
    letfr[ch-'a']++;            // Found lower case letter
    total++;
  }
}

Μετρά πόσες φορές εμφανίζεται κάθε λατινικό γράμμα στην είσοδο, χωρίς διάκριση πεζών-κεφαλαίων. Ο πίνακας letfr έχει 26 μετρητές, αρχικά 0, και το ch - 'A' (ή ch - 'a') δίνει τη θέση του γράμματος στο αλφάβητο (0 για A/a, 25 για Z/z). Το total μετρά όλα τα γράμματα, για να υπολογιστούν αργότερα συχνότητες. Το πλήρες πρόγραμμα, που τυπώνει και ιστόγραμμα, είναι στις σημειώσεις.

§9.22 Για το εργαστήριο και τις εργασίες

Κύρια σημεία

  1. Οι αριθμοί κινητής υποδιαστολής δεν αναπαρίστανται ακριβώς και ένα float δεν είναι ίσο με την ίδια σταθερά σε double· δεν τους συγκρίνουμε με ==.
  2. Για ονόματα σε κώδικα C η διάλεξη συνιστά snake_case (pi_approx) αντί για camelCase (piApprox).
  3. Τα δεδομένα εισόδου είναι μια σειρά από χαρακτήρες (bytes) που δίνει ο χρήστης στο πρόγραμμα, από τέσσερις πηγές: ορίσματα, πρότυπη είσοδο, αρχεία και δίκτυο.
  4. Η getchar διαβάζει έναν χαρακτήρα από το stdin και τον επιστρέφει ως int, ή EOF (-1) αν δεν υπάρχει άλλος.
  5. Η putchar τυπώνει έναν χαρακτήρα στο stdout και είναι απλούστερο υποσύνολο της printf.
  6. Η είσοδος από το πληκτρολόγιο περνά από buffer και φτάνει στο πρόγραμμα με το Enter (μαζί με το '\n')· το Ctrl+D δηλώνει στο Linux το τέλος της εισόδου.
  7. Η τιμή επιστροφής της getchar αποθηκεύεται σε int, όχι σε char, αλλιώς το byte 0xff μπερδεύεται με το EOF.
  8. Για να μάθετε πώς συμπεριφέρεται μια συνάρτηση της βιβλιοθήκης, τρέξτε man getchar, man scanf κ.λπ.
  9. Η scanf είναι η συμμετρική της printf για διάβασμα και παίρνει τις διευθύνσεις των μεταβλητών (&n)· χωρίς & το πρόγραμμα καταρρέει.
  10. Η scanf επιστρέφει πόσα δεδομένα διάβασε ή EOF· ένα πρόγραμμα που δεν ελέγχει την τιμή επιστροφής της δεν είναι σωστό.
  11. Η %d της scanf προσπερνά κενά και αλλαγές γραμμής πριν από τον αριθμό.

Ορολογία

Ελληνικά English Σύντομος ορισμός
δεδομένα εισόδου / εξόδου input / output data Ό,τι δίνεται στο πρόγραμμα / ό,τι παράγει.
πρότυπη είσοδος standard input (stdin) Η προεπιλεγμένη είσοδος, συνήθως το πληκτρολόγιο.
πρότυπη έξοδος standard output (stdout) Η προεπιλεγμένη έξοδος, συνήθως η οθόνη.
τέλος αρχείου End-Of-File (EOF) Τιμή (-1) που δηλώνει ότι δεν υπάρχει άλλη είσοδος.
ενδιάμεση μνήμη buffer Όπου περιμένουν οι χαρακτήρες πριν φτάσουν στο πρόγραμμα.
κανονική λειτουργία canonical mode Το τερματικό στέλνει την είσοδο ανά γραμμή.
συμβολοσειρά μορφοποίησης format string Το πρώτο όρισμα της printf/scanf, π.χ. "%d %d".
διεύθυνση address Η θέση μιας μεταβλητής στη μνήμη, &n.
τιμή επιστροφής return value Η τιμή που δίνει πίσω μια συνάρτηση.
κινητή υποδιαστολή floating point Αναπαράσταση πραγματικών (float, double), κατά προσέγγιση.
camelCase / snake_case camelCase / snake_case Στυλ ονομάτων: piApprox / pi_approx.

Διάβασμα

Συχνά λάθη

Τι δυσκόλεψε την τάξη

Από τα Kahoot των διαλέξεων: οι ερωτήσεις όπου μια λάθος απάντηση μάζεψε πολλές ψήφους, με το ποσοστό σωστών απαντήσεων.

Ερωτήσεις κατανόησης

Kahoot από το αμφιθέατρο (Κ9.1–Κ9.9)

Ερωτήσεις που παίχτηκαν στις διαλέξεις, με το ποσοστό των φοιτητών που απάντησαν σωστά.

Ασκήσεις

Ζέσταμα: από τις διαφάνειες (Α9.1–Α9.10)

Εργαστήριο (Α9.11–Α9.14)

Εργασίες (Α9.15–Α9.17)

Θέματα εξετάσεων (Α9.18–Α9.31)

Σχετικές ασκήσεις από άλλα κεφάλαια

  1. Για να χωράει, εκτός από όλους τους δυνατούς χαρακτήρες, και την τιμή EOF (-1), που δεν πρέπει να συμπίπτει με κανέναν χαρακτήρα. ↩

  2. Ορίσματα στη γραμμή εντολών, πρότυπη είσοδος (stdin), αρχεία, και δίκτυο ή άλλες πηγές. ↩

  3. Τέσσερις: 'a', 'b', 'c' και '\n'. ↩

  4. Οι χαρακτήρες μένουν στον buffer του τερματικού και προωθούνται στο πρόγραμμα όταν πατήσετε Enter (ή Ctrl+D). ↩

  5. Η scanf πρέπει να αλλάξει τη μεταβλητή, άρα χρειάζεται τη διεύθυνσή της· η printf μόνο διαβάζει την τιμή της. ↩

  6. 1: διαβάστηκε το a = 7, ενώ το x δεν είναι αριθμός, οπότε το b δεν άλλαξε. ↩

  7. ERROR, δηλαδή -1, γιατί το 'a' δεν είναι έγκυρο ψηφίο στη βάση 10. ↩

Κατεβάστε το κεφάλαιο: PDF · Markdown · GitHub