Μεταβλητές, βασικοί τύποι δεδομένων και άλλα |
Τα δεδομένα
Τα δεδομένα (πληροφορίες-data) είναι απαραίτητα στοιχεία ενός προγράμματος, καθώς οι βασικές λειτουργίες ενός προγράμματος είναι η επεξεργασία αυτών των δεδομένων και η εξαγωγή αποτελεσμάτων (δηλαδή άλλα δεδομένα). Απαιτείται λοιπόν η δέσμευση κάποιων χώρων μνήμης για να αποθηκευτούν αυτά τα δεδομένα, κατα την διάρκεια της εκτέλεσης του προγράμματος. Αυτοί οι χώροι μνήμης που τους χρησιμοποιούμε για την φύλαξη δεδομένων όταν εκτελείται ένα πρόγραμμα, ονομάζονται ανάλογα με την χρήση τους σταθερές ή μεταβλητές και κάθε γλώσσα προγραμματισμού μας δίνει την δυνατότητα με διάφορους τρόπους να δηλώσουμε (καθορίσουμε) κάποιους τύπους μεταβλητών/σταθερών, τις οποίες θα χρησιμοποιήσουμε για την αποθήκευση δεδομένων, όταν εκτελείται ένα προγραμμα.
Οι σταθερές
Αρκετά πρόγραμματα απαιτούν ορισμένα δεδομένα τα οποία δεν αλλάζουν (ή δεν πρέπει ν' αλλαχθούν) ποτέ κατά την διάρκεια της εκτέλεσης του. Αυτά τα δεδομένα συνήθως καθορίζονται μια φορά και χρησιμοποιούνται όσο συχνά επιθυμούμε, κατά την διάρκεια λειτουργίας του προγράμματος. Για παράδειγμα, όταν γράφετε ένα πρόγραμμα, μπορείτε να καθορίσετε ότι η τιμή του π είναι 3.14159 και να χρησιμοποιείτε αυτή την τιμή όταν την χρειάζεστε, ξέροντας ότι είναι διαθέσιμη και σωστή. Οι σταθερές ορίζονται με εντολές του προεπεξεργαστού με την οδηγία #define και συνήθως χρησιμοποιούμε κεφαλαία γράμματα για να τις περιγράψουμε:
# define PI 3.14159
(προσέξτε! αυτή η εντολή δεν τελειώνει με το ερωτηματικό ";". Επίσης υπάρχει κενό μεταξύ του PI και του 3.14159)
Οι μεταβλητές
Αντίθετα με τις σταθερές, οι τιμές των μεταβλητών είναι δυνατόν να αλλάξουν κατα την διάρκεια της εκτέλεσης ενός προγράμματος. Οι γλώσσες προγραμματισμού μας δίνουν την δυνατότητα να καθορίσουμε μεταβλητές και στην συνέχεια να τους δώσουμε όποια τιμή επιθυμούμε, που έχει βέβαια σχέση με το πρόγραμμα. Η δήλωση των μεταβλητών γίνεται συνήθως στην αρχή του προγράμματος.
Οι τύποι δεδομένων στην C
Ένας τύπος στην C, αλλά και σε πολλές άλλες δημοφιλείς γλώσσες προγραμματισμού, καθορίζει τον τρόπο χειρισμού κάποιας μεταβλητής. Συγκεκριμένα προσδιορίζει το είδος των τιμών που μπορεί να αποθηκεύσει, και καθορίζει ένα σύνολο λειτουργιών που είναι δυνατόν να εφαρμοσθούν πάνω στις μεταβλητές αυτού του τύπου. Η C έχει κάποιους βασικούς τύπους δεδομένων, οι οποίοι έχουν προκαθοριστεί και μπορούν να χρησιμοποιηθούν οπουδήποτε σε ένα πρόγραμμα, υπό τον όρο να χρησιμοποιούνται σωστά (όλοι οι τύποι δεδομένων δεν υποστηρίζονται απαραίτητα από ολους τους compilers):
TΥΠΟΣ | ΠΕΡΙΓΡΑΦΗ |
char |
Χαρακτήρας
(π.χ. A,a, C,f ). |
unsigned char |
Χαρακτήρας χωρίς πρόσημο
(η ύπαρξη του εξαρτάται από τον compiler) |
short |
Aκεραιος
(π.χ. ...,-2,-1, 0,1,2,3, ..) |
unsigned short |
Aκεραιος χωρίς πρόσημο
(0,1,2,3,...) |
int |
Aκεραιος (π.χ.
...,-2,-1, 0,1,2,3, ..) |
unsigned int |
Ακεραιος χωρίς πρόσημο |
long |
Εκτεταμένος ακεραιος |
unsigned long |
Εκτεταμένος ακεραιος χωρίς πρόσημο |
float |
Πραγματικός
(κινητής υποδιαστολής) |
double |
Εκτεταμένος πραγματικός |
Επειδή το εύρος των διαφόρων τύπων δεδομένων είναι δυνατόν να είναι διαφορετικό από compiler σε compiler με την χρήση του τελεστή sizeof (που μπορεί να μοιάζει με συνάρτηση, αλλά δεν είναι) μπορούμε να δείτε το εύρος κάθε τύπου δεδομένων στο compiler που χρησιμοποιείτε. H sizeof() χρησιμοποιείται γιά να υπολογίσει το μέγεθος κάποιας μεταβλητής ή σταθεράς, αλλά μπορεί να παρει σαν παραμέτρους και τύπους δεδομένων:
#include <stdio.h>
main()
{
printf("\nSize of type char: %d bytes", sizeof(char));
printf("\nSize of type int: %d bytes", sizeof(int));
printf("\nSize of type short: %d bytes", sizeof(short));
printf("\nSize of type long: %d bytes", sizeof(long));
printf("\nSize of type unsigned char: %d bytes", sizeof(unsigned char));
printf("\nSize of type unsigned int: %d bytes", sizeof(unsigned int));
printf("\nSize of type float: %d bytes", sizeof(float));
printf("\nSize of type double: %d bytes", sizeof(double));
}
Ονομασίες μεταβλητών
Οι ονομασίες των μεταβλητών πρέπει να αρχίζουν με γράμμα ή με κάτω παύλα. Στην περιγραφή της ονομασίας μπορείτε να χρησιμοποιείστε και αριθμούς, αλλά δεν επιτρέπονται άλλοι ειδικοί χαρακτήρες. Τα πεζά και κεφαλαία γράμματα παίζουν ρόλο (είναι διαφορετικά!). Ενας συγκεκριμένος αριθμός χαρακτήρων είναι σημαντικοί για τον compiler και αυτός ο αριθμός εξαρτάται από τον συγκεκριμένο compiler που χρησιμοποιείτε (πχ για την turbo C τα πρώτα 32 ψηφία είναι σημαντικά)
Φυσικά για την ονομασία των μεταβλητών σας δεν θα πρέπει να χρησιμοποιείστε ονόματα που είναι δεσμευμένες λέξεις για την γλώσσα C. Οι δεσμευμένες λέξεις της standard C είναι:
DATA TYPES | STORAGE CLASSES | STATMENTS |
char | auto | break |
double | extern | case |
enum | register | continue |
float | static | default |
int | do | |
long | else | |
short | for | |
struct | goto | |
union | if | |
unsigned | return | |
void | switch | |
sizeof | while | |
typdef |
Μετατροπές τύπων
Οταν κάνουμε πράξεις όπου οι δύο όροι είναι διαφορετικού τύπου, ή όταν η καταχώρηση του αποτελέσματος γίνεται σε διαφορετικού τύπου μεταβλητή, θα πρέπει να είμαστε προσεκτικοί. Για παράδειγμα το Πρόγραμμα Α που ακολουθεί:
Πρόγραμμα - Α | Πρόγραμμα - Β | Πρόγραμμα - Γ |
#include <stdio.h> main() { int x=20; int y=3; float z; z=x/y; printf("z=%f\n",z); } |
#include <stdio.h> main() { int x=20; float y=3.0; float z; z=x/y; printf("z=%f\n",z); } |
#include <stdio.h> main() { int x=20; int y=3; float z; z= (float)x / y; printf("z=%f\n",z); } |
ενώ δεν θα μας δώσει κανένα μηνυμα λάθους, θα βγάλει λάθος αποτέλεσμα! Αντίθετα τα Προγράμματα Β και Γ θα δώσουν σωστό αποτέλεσμα...Αυτό γίνεται διότι στο Πρόγραμμα Α και οι δύο όροι της πράξης είναι ακέραιοι και συνεπώς το αποτέλεσμα θα είναι ακέραιο ανεξάρτητα αν το καταχωρούμε σε float μεταβλητή. Στο Προγραμμα Β οι όροι της πράξης είναι διαφορετικού τύπου και το αποτέλεσμα μετατρέπεται στον υψηλότερο ιεραρχικά τύπο, δηλαδή σε float. Στο Πρόγραμμα Γ, όταν γίνεται η πράξη μετατρέπουμε τον ένα από τους δύο ακέραιους όρους σε float (τον x) και το αποτέλεσμα πάλι μετατρέπεται στον υψηλότερο ιεραρχικά τύπο δηλαδή float. Γενικότερα ο υψηλότερος ιεραρχικά τύπος είναι ο double και ακολουθούν ο float, o long int, o unsigned int, o int και τέλος ο char. Τι θα γίνει άραγε αν η εντολή καταχώρησης γίνει z=(float)(x/y);
Αρχικές τιμές μεταβλητών
Στις μεταβλητές μπορούμε να δώσουμε τιμές κατα την διάρκεια της εκτέλεσης του προγράμματος, είναι όμως δυνατόν να δώσουμε και αρχικές τιμές, όταν τις δηλώνουμε:
int alpha = 6; /* δίνω αρχική τιμή */
alpha = 6; /* δίνω τιμή μέσα στο πρόγραμμα */
Χειρισμός των σειρών χαρακτήρων (συμβολοσειρών)
Στην C δεν υπάρχει ιδιαίτερος τύπος για τον χειρισμό των συμβολοσειρών. Για την αποθήκευση τους χρησιμοποιούμε την δομή του πίνακα τύπου char και φυσικά έχουν τα χαρακτηριστικά του πίνακα. O τελευταίος χαρακτήρας του πίνακα είναι ο \0 (μηδενικός χαρακτήρας). Στο πρόγραμμα οι τιμές που δίνουμε στις μεταβλητές που έχουν χαρακτηριστεί σαν συμβολοσειρές, οριοθετούνται με λατινικά εισαγωγικά διπλά (") ή απλά ( ' ) - δείτε παρακάτω.
Παράδειγματα δήλωσης: char minima1 [40];
Αρχικές
τιμές:
char minima1[20 ] = "hello";
char minima2[ ] = {'h', 'e','l','l','o','\0'};
Παράδειγματα χρήσης:
gets (minima1); /* Δίνοντας τιμή στο minima1 από το πληκτρολόγιο με την gets*/
scanf("%s",minima2); /* Δίνοντας τιμή στο minima1 από το πληκτρολόγιο με την scanf*/
.......
strcpy(minima1, "hello"); /* δινοντας τιμή στην μεταβλητή minima1 στο πρόγραμμα */
.......
puts(minima1); /* εμφανίζω το περιεχόμενο του minima1 στην οθόνη με την puts */
printf("Τo minina einai:\n", minima2); /* εμφανίζω το περιεχόμενο του minima2 με την printf */
Παρατηρήσεις γιά τους χαρακτήρες και τις συμβολοσειρές:
Ο
τύπος char είναι ουσιαστικά ακέραιος (int)
τύπος στην C. Μπορούμε μάλιστα αντί για char στο
προγραμμα μας να χρησιμοποιήσουμε χωρίς
κανένα πρόβλημα τον
τύπο int:
#include <stdio.h>
main()
{
int ch;
/* δηλώνω το ch σαν int */
ch='A';
/* δίνω τιμή στο ch σαν χαρακτήρα */
printf("The ch as char: %c \n", ch); /*
εμφανίζω το ch σαν char */
}
Οποιος χαρακτήρας ακολουθεί τον χαρακτήρα "\", τότε επισημαίνεται στο compiler ότι αυτός ο δευτερος χαρακτήρας έχει ειδική σημασία. Οι συνδυασμοί αυτών των δύο χαρακτήρων λαμβάνονται υπόψη σαν ένας χαρακτήρας και χρησιμοποιούνται για τον συμβολισμό των ειδικών χαρακτήρων (χαρακτήρες ελέγχου). Για παράδειγμα ο συνδυασμός \n είναι ο χαρακτήρας νέας γραμμής (new line), ο συνδυασμός \r δηλώνει τον χαρακτήρα επιστροφής (<enter> ή <carriage return>) κτλ.
Ο
μηδενικός χαρακτήρας \0 είναι
διαφορετικός από τον χαρακτήρα 0 (μηδέν). O
μηδενικός χαρακτήρας έχει την τιμή 0 (εσωτερική
αναπαράσταση), ενώ ο χαρακτήρας 0 έχει την
τιμή 48. Δηλαδή η εντολή
printf(" %d,
%d", '\0','0');
θα δώσει σαν
αποτέλεσμα: 0, 48.
Προσέξτε την εντολή minina1="hello"; όπου η minima1 είναι μία συμβολοσειρά. Κατά πάσα πιθανότητα δεν θα την δεχθεί ο compiler σας. Ο λόγος είναι ότι η μεταβλητή minima1, είναι στην πραγματικότητα ο δείκτης της διεύθυνσης της μνήμης του πρώτου μέλους του πίνακα minima1, που είναι μία συγκεκριμένη θέση η οποία ορίζεται με την δήλωση του συγκεκριμένου πίνακα (char minima1 [40];) και ο compiler δεν θα σας επιτρέψει να την αλλάξετε.
Οπως έχετε ίσως παρατηρήσει, για τους χαρακτήρες χρησιμοποιούμε πότε απλά και πότε διπλά εισαγωγικά. Η διαφορά μεταξύ του 'A' και του "A" είναι ότι το πρώτο μου δίνει έναν αριθμό που είναι η εσωτερική αναπαράσταση του γράμματος Α, ενώ το δευτερο είναι μία συμβολοσειρά που περιέχει το γράμμα Α και στο τέλος τον χαρακτήρα \0 (o μηδενικός χαρακτήρας). Τα δύο προγράμματα που ακολουθούν δίνουν το ίδιο αποτέλεσμα:
Πρόγραμμα - Α |
Πρόγραμμα - Β |
|
#include <stdio.h> |
#include <stdio.h> |
|
Αποτέλεσμα (και
των δύο προγραμμάτων): |
#include <stdio.h>
main()
{
char seira [10] = "A";
char seira1 [10] = {'A', '\0'};
printf("%s\n", seira);
printf("%s\n", seira1);
}Αποτέλεσμα:
Α
Α
Κατηγορίες μνήμης
Αργότερα...
Στην προηγούμενη ενότητα | ||
Κ.Βασιλάκης / ΤΕΙ Κρήτης |