τι περιέχει αυτό το κεφάλαιο...
Τα structs δεν είναι τίποτα άλλο απο ένα σύνθετο τύπο δεδομένων. Θα ήταν χρήσιμο όταν έχουμε να αντιμετωπίσουμε ένα struct, να το σκεφτόμαστε σαν κουτιά το ένα μέσα στο άλλο. Γραφικά, είναι η αποθήκευση όλων των μεταβλητών που περιέχονται σε κάποιο ξεχωριστό χώρο ώστε να μπορούν να είναι προσβάσιμες οπουδήποτε. Η διαφορά με τον "κλασικό" τρόπο ορισμού των μεταβλητών είναι οτι με πολλές μεταβλητές που κάνουν την ίδια δουλειά χρησιμοποιώντας structs μπορούμε να εξικονομήσουμε χρόνο-χώρο και να κάνουμε ποιό κατανοητό και ευκολοδιάβαστο το πρόγραμμά μας.
Στο παρακάτω struct σκεφτείτε πως έχουμε ένα μεγάλο κουτί και μέσα του ένα πίνακα όπου θα βρίσκεται το όνομα(σε κάθε καλί ένας χαρακτήρας) και ένα άλλο κουτί για την ηλικία...
Που τα υλοποοιούμε...
Tα structs συνήθως ορίζονται στην αρχή, μετά απο την δήλωση των βιβλιοθηκών και πρίν απο τις συναρτήσεις. Βέβαια, αυτό είναι εντελώς τυπικό. Στην ουσία μπορείτε να τα βάλετε όπου θέλετε εσείς.
- Κώδικας: Επιλογή όλων
#include <library1>
#include <library2>
#define N 10
/* Συνήθως τα structs ορίζονται ακριβώς μετά */
struct Foo{
char name[32];
int age;
};
void function{...}
int main(void){...}
Πως τα υλοποοιούμε...
Ένα struct είναι απλά μια δομή που περιέχει μέσα του διάφορες μεταβλητές η και πίνακες. Κάθε struct έχει το δικό του όνομα(αυθαίρετο) και ένα τυπικό tag που θα το ξεχωρίζει απο τα υπόλοιπα μέσα στο πρόγραμμά μας. Παρακάτω μπορείτε να δείτε πως γράφετε σε γενική μορφή ένα struct! Προσέξτε οτι με τον παρακάτω κώδικα δεν είμαστε έτοιμοι να το χρησιμοποιήσουμε. Απλά το έχουμε φτιάξει και έχουμε ορίσει τα πεδία του αλλα δεν μπορούμε να το χρησιμοποιήσουμε ακόμη. Δείτε παρακάτω γιατί...
- Κώδικας: Επιλογή όλων
struct <tag>{
char name[32];
int age;
// and other variables...
}; /* Προσέξτε το ερωτηματικό */
Τελική δημιουργία των struct...
Στην ουσία όμως αυτό που είδατε παραπάνω είναι μόνο ο ορισμός, η αλλιώς "καθορισμός των μεταβλητών". Για να δημιουργηθεί ένα struct και να μπορεί κάθε στιγμή να είναι προσβάσιμο απο οπουδήποτε θα πρέπει να χρησιμοποιήσουμε άλλη μια γράμμη συνήθως κάτω απο την main( )...
- Κώδικας: Επιλογή όλων
int main(void){
struct <tag> <name>;
}
με αυτόν τον τρόπο δημιουργούμε ένα struct που ονοομάζεται <name>! Το επόμενο βήμα είναι να δούμε πως μπορούμε να προσπελάσουμε τις τιμές του.
Ένας δεύτερος εναλακτικός τρόπος που μπορεί να γίνει αυτό είναι να μην βάλουμε τίποτα στην main και απλά όταν υλοποιούμε το stuct να του δώσουμε και ένα όνομα. Δείτε παρακάτω τι εννοώ...
- Κώδικας: Επιλογή όλων
struct <tag>{
char name[32];
int age;
// and other variables...
}new_name; /* Εδώ μπορούμε να δώσομε ένα όνομα αντί για αυτό που θα γράφαμε στην main */
Σε αυτό το σημείο θα κάνω μια παρένθεση για να σας δείξω σχηματικά πως μπορεί κάποιος να κάνει ένα struct. Αυτό γιατί, όταν υπάρχει και κάποιο σχήμα στο μυαλό μας η υλοποίηση γίνεται πιο εύκολα!
Το παρακάτω struct έχει όνομα Data(case-sensitive) και έχει μέσα του ένα πινακάκι και δυο ακεραίους.
- Κώδικας: Επιλογή όλων
struct Data{
char name[81];
int age;
int AM;
};
σχηματικά θα μπορούσαμε να το αναπαριστήσουμε κάπως έτσι...
Προσπέλαση των πεδίων...
Για να μπορέσουμε να χρησιμοποιήσουμε μια μεταβλητή που έχει οριστεί μέσα σε ένα struct χρησιμοποιούμε την 'τελεία' '.' . Δηλαδή βάζουμε το όνομα <name> του struct ακολουθούμενο απο μια τελεία και μια μεταβλητή που περιέχει το συγκεκριμένο struct...
Ας υποθέσουμε οτι υπάρχει το ακόλουθο struct,
- Κώδικας: Επιλογή όλων
struct Data{
int x;
}A;
για να δώσουμε μια αυθαίρετη τιμή θα πρέπει να κάνουμε το εξής:
- Κώδικας: Επιλογή όλων
A.x = αυθαίρετη_τιμή;
δείτε ένα δεύτερο παράδειγμα παρακάτω, έχοντας άλλο ένα struct εκχωρουμε αρχικές τιμές...
- Κώδικας: Επιλογή όλων
struct Foo{
char name[32];
int age;
}f;
η εκχώρηση τιμών γίνεται ως εξής:
- Κώδικας: Επιλογή όλων
f.name="Alex";
f.age=14;
Structs & Συναρτήσεις...
Όταν στην άστκηση συμπεριλαμβάνονται και συναρτήσεις γίνεται λίγο ποιό πολύπλοκο το θέμα αλλά δεν το βάζουμε κάτω! Ένα struct περνά σαν παράμετρος σε μια άλλη συνάρτηση ως εξής...
- Κώδικας: Επιλογή όλων
int function(struct <tag> <struct_name>){...}
και στην main() γράφεται το εξής:
- Κώδικας: Επιλογή όλων
int main(void){
// commands...
function_name(<struct_name>);
}
για παράδειγμα,
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
struct Info{
int age;
};
void init(struct Info info){
char buf[81];
gets(buf);
puts(buf);
}
int main(void){
struct Info info;
init(info);
return 0;
}
Χρήση του typedef...
- Κώδικας: Επιλογή όλων
typedef struct <tag>{
//variables;
}<struct_name>;
με την χρήση του typedef μπορούμε να παραλείψουμε την λέξη struct
έτσι, αντί να χρησιμοποιούμε συνεχώς την λέξη struct, struct, struct μέσα στο πρόγραμμά μας, μπορούμε με αυτό τον τρόπο να χρησιμοποιούμε το όνομα <struct_name> όπως φαίνεται και παραπάνω
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h
typedef struct Foo{
int buf[81];
int age;
}f;
int fuction(f){
f.age=32;
return f.age;
}
int main(void){
int n;
foo.age=12;
printf("1: foo.age: %d\n", foo.age);
n=fuction(foo);
printf("2: foo.age: %d\n", n);
return 0;
}
Πέρασμα παραμέτρων μέσα απο struct...
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
struct Foo{
int x;
int array[6];
};
void func(struct Foo *p_foo){
p_foo->x = 56;
p_foo->array[3]=55;
}
int main(void){
struct Foo foo;
foo.x=11;
foo.array[6]=5;
printf("foo.x: %d\nfoo.array[6]: %d\n", foo.x, foo.array[6]);
func(&foo);
printf("foo.x: %d\nfoo.array[6]: %d\n", foo.x, foo.array[6]);
// -> is short-hand for (*foo).x=56
// & returns the address of a variable
// Note that -> is used to get to the fields of a pointer to a struct
return 0;
}
Struct μέσα σε πίνακα...
Είναι πιθανό μέσα σε κάποια άσκηση να συναντίσουμε κάποιο struct μέσα σε πίνακα. Τι σημαίνει αυτό? Έχοντας κάποιο πίνακα A, κάθε κελί του περιέχει ένα struct. Τώρα, το struct(που περιέχεται σε κάθε κελί του πίνακα) μπορεί να έχει πολλά μέσα αλλα δεν μας ενδιαφέρουν. Μπορεί να περιέχει 25.000 άλλους πίνακες και πολλές μεταβλητές. Δεν θα αναλύσω περισσότερο γιατί ότι και αν περιέχει είναι μια απο τα ίδια Ας δούμε τώρα πως θα κάναμε κάτι τέτοιο...
Καταρχήν θα πρέπει να δημιουργήοσυμε ένα struct. Αυτό κάνουμε παρακάτω...
- Κώδικας: Επιλογή όλων
struct Family{
char father_name;
char mother_name;
int father_age;
int mother_age;
};
στην main ο τύπος του πίνακα θα είναι, το struct που μόλις ορίσαμε...
- Κώδικας: Επιλογή όλων
int main() {
struct Family f;
struct Family A[20];
...
return 0;
}
Ολοκληρωμένα μπορούμε να κάνουμε το παρακάτω παράδειγμα όπου τεστάραμε το πρόγραμμά μας μόνο στο πρώτο κελί.
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
struct Family{
char father_name;
char mother_name;
int father_age;
int mother_age;
};
int main() {
struct Family f;
struct Family A[20];
A[0].father_age = 52;
printf("My father age is: %d\n", A[0].father_age);
return 0;
}
Παράδειγμα: Γράψτε ένα πρόγραμμα που θα ζητά δυο συντεταγμένες απο το χρήστη και θα τις εκτυπώνει μέσα στην main() κάνοντας χρήση των struct.
Ενδεικτική Λύση:
- Κώδικας: Επιλογή όλων
#include <stdio.h>
struct Info(
int x;
int y;
};
int main(void){
struct Info f;
printf("Please type a number for the first coordinate:\n");
scanf("%d", &f.x);
printf("Please type a number for the first coordinate:\n");
scanf("%d", &f.y);
printf("The two coordinates (x, y) are: (%d, %d)\n", f.x, f.y);
return 0;
}
Καλή συνέχεια και ελπίζω να βοήθησα!