Η C είναι απλή/Δομή/"struct" - typedef

Από Βικιβιβλία

Ας υποθέσουμε ότι θέλουμε να συγκρατήσουμε πληροφορίες για φοιτητές. Ένας φοιτητής έχει ονοματεπώνυμο, αριθμό μητρώου, αριθμό εξαμήνου στο οποίο σπουδάζει, ίσως αριθμό μαθημάτων που έχει περάσει, μέσο όρο βαθμολογίας κτλ. Πώς μπορούμε να αποθηκεύσουμε αυτές τις πληροφορίες σε ένα πρόγραμμα?

Σε ένα μεγάλο πίνακα? Όχι επειδή δεν έχουν όλες οι πληροφορίες τον ίδιο τύπο πχ το ονοματεπώνυμο θα ήταν αλφαριθμητικό, οι αριθμοί μητρώου/εξαμήνου/μαθημάτων ακέραιοι και ο μέσος όρος πραγματικός.

Σε επιμέρους πίνακες, το καθένα για διαφορετικά δεδομένα? Είναι εφικτό, αλλά έχουμε πληροφορίες διασκορπισμένες σε πολλά διαφορετικά σημεία, το οποίο δε είναι πολύ καλό.

Δε θα ήταν καταπληκτικό εάν η γλώσσα μας άφηνε να δημιουργήσουμε νέους τύπους, οι οποίοι θα περιείχαν όλα τα διαφορετικά κομμάτια κάτω απ' το ίδιο όνομα?! Μα, αυτό κάνει η εντολή "struct". Χρησιμοποιείται έτσι:

struct όνομα_τύπου
{
    /* Εδώ μέσα δηλώνονται όλα τα μέλη της δομής, αλλά πάντα χωρίς ανάθεση τιμών */
}; /* Το ελληνικό ερωτηματικό εδώ είναι πολύ σημαντικό! */


τώρα, όταν θέλουμε να δηλώσουμε μια καινούργια μεταβλητή ( πάντα αφού έχουμε δηλώσει τη δομή ):

struct όνομα_τύπου όνομα_μεταβλητής;
/* Το παρακάτω θέτει αρχικές τιμές στα μέλη της */
struct όνομα_τύπου όνομα_μεταβλητής = { /* όλες οι αρχικές τιμές, διαχωρισμένες με κόμμα */ };


όταν θέλω να αναφερθώ σε κάποιο συγκεκριμένο μέλος χρησιμοποιώ την τελεία, έτσι:

όνομα_μεταβλητής.όνομα_μέλους = κάτι;


όταν έχω δείκτη σε δομή, χρησιμοποιώ το βέλος ( -> ) για να αναφερθώ σε κάποιο μέλος της:

δείκτης_μεταβλητής->όνομα_μέλους = κάτι;
/* Ίδιο με το παραπάνω */
(*δείκτης_μεταβλητής).όνομα_μέλους = κάτι;


Επίσης, μπορείτε να χρησιμοποιήσετε το τελεστή ανάθεσης τιμής μεταξύ δύο δομών( του ίδιου τύπου ), αλλά ΜΟΝΟ αυτόν!


Τέλος, μήπως δεν σας αρέσει να γράφετε συνέχεια "struct structName"? Η C έχει έναν ωραίο μηχανισμό με τον οποίο μπορείτε να δώσετε νέα ονόματα σε τύπους που θέλετε, πχ:

typedef struct structName newName;
/* Τώρα μπορείτε να δηλώσετε μεταβλητές και με τους δύο τρόπους */
newName struct1;
struct structName struct2;

μπορεί να χρησιμοποιηθεί με οποιοδήποτε τύπο, ενσωματωμένο ή μη.


Ας κλείσω με ένα προγραμματάκι που δείχνει όσα ανέφερα στην αρχή:

#include <stdio.h>

struct CollegeStudent
{
    char Name[64]; /* Πίνακας χαρακτήρων για το ονοματεπώνυμο */
    int ID; /* Αριθμός μητρώου */
    int semester; /* Εξάμηνο */
    int classesPassed; /* Περασμένα μαθήματα */
    float gradeAverage; /* Μ.ο. μαθημάτων */
};
typedef struct CollegeStudent Foititis; /* Δίνω ένα μικρότερο όνομα */

int main(void)
{
    int i;
    Foititis array[3];

    for (i = 0; i < 3; i++){
        printf("Requesting info about the #%d college student:\n", i+1);
        printf("Name: ");
        /* Αυτή είναι μια συνάρτηση που λαμβάνει όλη τη γραμμή και θέτει το αλφαριθμητικό */
        gets(array[i].Name); /* Σε επόμενο άρθρο θα εξηγήσω γιατί ΔΕΝ πρέπει να την χρησιμοποιείτε */

        printf("ID: ");
        scanf("%d", &array[i].ID);

        printf("Semester: ");
        scanf("%d", &array[i].semester);

        printf("Classes passed: ");
        scanf("%d", &array[i].classesPassed);

        printf("Grade average: ");
        scanf("%f", &array[i].gradeAverage);

        putchar('\n'); /* Prints a single character */
        while (getchar() != '\n');
    }

    /* Σε παρακάτω άρθρο θα εξηγήσω πώς μπορείτε να αποθηκεύσετε δεδομένα σε αρχεία */
    printf("All student information saved on memory.");
    getchar();

    return 0;
}

Μη ξεχνάτε να πειραματίζεστε! Happy Coding! ;-)