Σημειώσεις - Εισαγωγή στον Προγραμματισμό

Κεφάλαιο 5: Δείκτες και πίνακες

Δείκτες

Περί ανάγνωσης ακεραίων (και όχι μόνο)

Πίνακες

Ιστόγραμμα συχνοτήτων γραμμάτων στην είσοδο

/* File: histogram.c */
#include <stdio.h>
#define YAXISLEN 12                                 /* Y-axis length */

int main(void)
{ int i, j, ch, total;
  int letfr[26];         /* Letter occurrences and frequencies array */
  for (i=0 ; i < 26 ; i++)
    letfr[i] = 0;                                /* Initialize array */
  total = 0;       /* Initialize counter of total letter occurrences */
  while ((ch = getchar()) != EOF) {/* Well-known read-character loop */
    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++;
    }
  }
  printf("  |");  /* Start histogram printing - first Y-axis segment */
  for (i=0 ; i < 26 ; i++) {           /* Convert letter occurrences */
                        /* to frequencies rounded to nearest integer */
    letfr[i] = (int) ((100.0*letfr[i])/total+0.5);
    printf("%s", (letfr[i] > YAXISLEN) ? "^^" : "  ");    /* If i-th */
               /* letter frequency exceeds Y-axis length, print "^^" */
  }
  printf("\n");
  for (j=YAXISLEN ; j > 0 ; j--) {/* Print line at j-value of Y-axis */
    printf("%2d|", j);   /* Print frequency label and Y-axis segment */
    for (i=0 ; i < 26 ; i++)
      printf("%s", (letfr[i] >= j) ? "xx" : "  "); /* If i-th letter */
              /* frequency is greater than or equal to j, print "xx" */
    printf("\n");
  }                                /* Print X-axis and letter labels */
  printf("  +-----------------------------------------------------\n");
  printf("   AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz\n");
  return 0;
}
% gcc -o histogram histogram.c
% ./histogram < histogram.c
  |
12|
11|        xx                            xx
10|        xx      xx                    xx
 9|        xx      xx                xx  xx
 8|        xx      xx        xx      xx  xx
 7|        xx      xx        xx      xx  xx
 6|xx      xx      xx    xx  xx      xx  xx
 5|xx      xxxx    xx    xx  xxxx    xx  xx
 4|xx  xx  xxxx    xx    xx  xxxx    xxxxxx
 3|xx  xx  xxxx  xxxx    xx  xxxx    xxxxxx
 2|xx  xxxxxxxxxxxxxx    xx  xxxxxx  xxxxxxxx    xxxx
 1|xxxxxxxxxxxxxxxxxxxx  xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  +-----------------------------------------------------
   AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
% ./histogram < /usr/share/dict/words
  |
12|
11|        xx
10|        xx
 9|xx      xx
 8|xx      xx      xx
 7|xx      xx      xx        xxxx    xx  xx
 6|xx      xx      xx    xx  xxxx    xxxxxx
 5|xx  xx  xx      xx    xx  xxxx    xxxxxx
 4|xx  xx  xx      xx    xx  xxxx    xxxxxxxx
 3|xx  xxxxxx    xxxx    xxxxxxxxxx  xxxxxxxx
 2|xxxxxxxxxx  xxxxxx    xxxxxxxxxx  xxxxxxxx      xx
 1|xxxxxxxxxxxxxxxxxx  xxxxxxxxxxxx  xxxxxxxxxxxx  xx
  +-----------------------------------------------------
   AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
% ./histogram < /usr/include/stdio.h
  |        ^^
12|        xx
11|        xx
10|        xx                xx
 9|        xx      xx        xx
 8|        xxxx    xx        xx          xx
 7|        xxxx    xx        xx          xx
 6|      xxxxxx    xx        xx        xxxx
 5|      xxxxxx    xx        xxxx    xxxxxx
 4|      xxxxxx    xx    xx  xxxxxx  xxxxxx
 3|xx  xxxxxxxx    xx    xx  xxxxxx  xxxxxxxx    xx
 2|xx  xxxxxxxxxx  xx    xx  xxxxxx  xxxxxxxx    xx
 1|xxxxxxxxxxxxxxxxxx  xxxxxxxxxxxx  xxxxxxxx    xx
  +-----------------------------------------------------
   AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz
%
  1. Εκτός, ίσως, από τα θέματα της δυναμικής δέσμευσης μνήμης, που υπάρχει μία σχετική δυστοκία. ↩

  2. 6, 5, 'E' και 'D', αντίστοιχα ↩

  3. Ναι, γιατί όχι; ↩

  4. Όχι, ΔΕΝ σημαίνει ότι πρώτα θα αυξηθεί ο δείκτης px και μετά θα πάρουμε το περιεχόμενο της θέσης μνήμης που δείχνει η νέα, αυξημένη, τιμή του δείκτη. Οι παρενθέσεις δεν δείχνουν τη σειρά που θα γίνουν οι υπολογισμοί, αλλά το πού εφαρμόζονται οι τελεστές. Στο προκείμενο παράδειγμα, ο τελεστής ++ είναι μεταθεματικός, άρα πρώτα θα πάρουμε το περιεχόμενο της θέσης μνήμης που δείχνει ο δείκτης px και μετά θα αυξηθεί ο δείκτης. Αν θέλαμε πρώτα να αυξήσουμε τον δείκτη και μετά να κάνουμε την αναφορά, έπρεπε να γράψουμε *(++px). ↩

  5. 12, -4 και -16, αντίστοιχα ↩

  6. Έστω ότι πριν καλέσουμε την swap(a,b), οι τιμές των μεταβλητών a και b είναι 5 και 8, αντίστοιχα. Τότε, ουσιαστικά καλούμε swap(5,8), δηλαδή οι τυπικές παράμετροι x και y της swap, που είναι τοπικές/αυτόματες μεταβλητές για τη συνάρτηση, παίρνουν τις τιμές 5 και 8, αντίστοιχα, ανταλλάσσονται μέσα στην swap οι τιμές των x και y, αλλά οι μεταβλητές a και b της καλούσας συνάρτησης δεν επηρεάζονται καθόλου από την αλλαγή αυτή. ↩

  7. swap(&a,&b) ↩

  8. Για τον ίδιο λόγο που χρειαζόμαστε ένα τρίτο ποτήρι αν θέλουμε να ανταλλάξουμε τα περιεχόμενα δύο άλλων ποτηριών, εκτός κι αν είμαστε ταχυδακτυλουργοί (:-). ↩

  9. Προσοχή στην ορολογία! Τον όρο “δείκτης” εδώ, τον χρησιμοποιούμε σαν ελληνική απόδοση του Αγγλικού “index”. Πρόκειται για δείκτη πίνακα. Οι δείκτες όμως που είδαμε στην προηγούμενη ενότητα είναι δείκτες διευθύνσεων και αντιστοιχούν στον Αγγλικό όρο “pointer”. Για τη συνέχεια, δεν θα κάνουμε ιδιαίτερη αναφορά, όταν χρησιμοποιούμε τον όρο “δείκτης”, σε ποια εκδοχή αναφερόμαστε. Θα προκύπτει αυτό εύκολα από τα συμφραζόμενα. ↩

  10. Ευτυχώς, δηλαδή, γιατί έτσι μαθαίνουμε ότι το πρόγραμμά μας έχει σφάλματα, οπότε μπορούμε να μπούμε στη διαδικασία να τα διορθώσουμε. Όμως, αυτό δεν συμβαίνει πάντοτε. Υπάρχουν περιπτώσεις που να έχουμε κάνει λάθος διαχείρισης μνήμης, να μην πάρουμε κάποια ένδειξη γι’ αυτό και να νομίζουμε ότι το πρόγραμμά μας δουλεύει σωστά, ενώ αυτό θα κάνει άλλα αντ’ άλλων. ↩

  11. 4, 1, 4, 25, 1, 25, 16, 1 ↩

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