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

table2.c :
http://ideone.com/hVnHWΕίμαι πολύ κουρασμένος τώρα για να κάνω πλήρη ανάλυση (από αύριο) αλλά τον ανέβασα σε ξεχωριστή διεύθυνση για να μπορείτε να τον συγκρίνετε με τον κώδικα του table.c που είχαμε μέχρι τώρα.
Λειτουργικά κάνουν ακριβώς το ίδιο πράγμα, αλλά το table2.c έχει ήδη την υποδομή να δέχεται πολύ πιο εύκολα μελλοντικές αλλαγές και μας βοηθάει να γράψουμε κώδικα που θα εκτελείται πιο γρήγορα.
Για παράδειγμα η συνάρτηση tablen() δεν υπάρχει πλεόν, γιατί το πλήθος των μη κενών στοιχείων έχει μπει ως πεδίο μέσα στη δομή (buflen το λέω). Οπότε αφενός μπορούμε να το χρησιμοποιούμε απευθείας ως: table->buflen (ή table.buflen) και αφετέρου το υπολογίζουμε μια φορά στην αρχή και τέρμα (θα το ενημερώνουμε δυναμικά και όταν προσθαφαιρούμε στοιχεία στο buffer αργότερα). Ενώ η tablen() κάθε φορά που την καλούσαμε μέτραγε κάθε φορά από την αρχή όλα τα στοιχεία του πίνακα.
Με λίγα λόγια, όλες τις βασικές μεταβλητές που τις είχαμε "ξέμπαρκες" πριν, τώρα έχουν μαζευτεί σε ένα μέρος, ως πεδία της δομής Table... οπότε στις συναρτήσεις μας περνάμε μονάχα την μεταβλητή table που την έχω ορίσει τύπου Table (και άρα έχουμε άμεση πρόσβαση σε όλα της τα πεδία ανά πάσα στιγμή, χωρίς να χρειάζεται να τα περνάμε ως ξεχωριστά ορίσματα).
Πιστεύω πως το μεγαλύτερο πρόβλημα που θα αντιμετωπίσετε θα είναι να συνηθίσετε την ιδέα πως το Table δεν είναι πια ένα κλασικό array, είναι μια ευρύτερη δομή που περιέχει και το array (το buffer) και τις μεταβλητές που κρατάνε κρίσιμες πληροφορίες για το buffer.
Δηλαδή όπου στο table.c λέγαμε table, τώρα λέμε table->buffer (ή table.buffer )... όπου λέγαμε tabsize τώρα λέμε table->bufsize (ή table.bufsize) κλπ κλπ.
Ελπίζω να μην τρομάξετε από την 1η ματιά και απογοητευτείτε. Αν το καλοσκεφτείτε μας είναι πολύ εύκολο όπως είναι τώρα. Δείτε για παράδειγμα πόσο πιο ανθρώπινα διαβάζεται η main()

Περιμένω απορίες, και μετά η επόμενη άσκηση θα είναι να γράψουμε μια συνάρτηση που θα γεμίζει το buffer με τυχαίους αριθμούς

Θα σας πω ακριβώς όταν βεβαιωθούμε πρώτα πως έχουμε καταλάβει τον νέο κώδικα.