ΗΜΜΥ 101 - courses.softlab.ntua.gr

Download Report

Transcript ΗΜΜΥ 101 - courses.softlab.ntua.gr

ΦΡΟΝΤΙΣΤΗΡΙΟ 1-β
Φ1β-1
ΕΝΤΟΛΗ ΑΝΑΘΕΣΗΣ
Οι μεταβλητές λαμβάνουν τιμές με συκγεκριμένη
εντολή ανάθεσης
Η εντολή είναι της μορφής:
Μεταβλητή = έκφραση
όπου η έκφραση μπορεί να είναι μια σταθερή τιμή,
ένας μαθηματικός τύπος, το αποτέλεσμα κλήσης μιάς
συνάρτησης κλπ.
Η έκφραση θα πρέπει να παράγει ένα
αποτέλεσμα που να είναι συμβατό με τον τύπο
της μεταβλητής
Φ1β-2
ΠΑΡΑΔΕΙΓΜΑ (1)
#include <stdio.h>
float main()
{
float height, base, area;
height = 10.2;
base = 3.6;
printf(“The height of the triangle is: %f\n”, height);
printf(“The base of the triangle is: %f\n”, base);
area = (height * base)/2;
printf(“The area of the triangle is %f\n”, area);
return (area);
}
Φ1β-3
ΠΑΡΑΔΕΙΓΜΑ (2)
#include <stdio.h>
float main()
{
float height, base, area;
printf(“Enter the height of the triangle:”);
scanf(“%f”, &height);
printf(“\n”);
printf(“Enter the base of the triangle”);
scanf(%f”, &base);
printf(“\n”);
printf(“The height of the triangle is: %f\n”, height);
printf(“The base of the triangle is: %f\n”, base);
area = (height * base)/2;
printf(“The area of the triangle is %f\n”, area);
return (area);
}
Φ1β-4
ΠΑΡΑΔΕΙΓΜΑ (3)
#include <stdio.h>
#define FREEZING_POINT_IN_FARHENHEIT 32
#define SCALE_FACTOR (5.0 / 9.0)
float main()
{
float farhenheit, celcius;
printf(“Enter the temperature in Farhenheit:”);
scanf(“%f”, &farhenheit);
celcius = (farhenheit – FREEZING_POINT_IN_FARHENHEIT) *
SCALE_FACTOR;
printf(“The celcius equivalent temperature of %f is %.1f \n”, farhenheit, celcius);
return (area);
}
Φ1β-5
ΟΝΟΜΑΤΑ ΜΕΤΑΒΛΗΤΩΝ
Τα ονόματα των μεταβλητών σ΄ένα πρόγραμμα C πρέπει
να αρχίζουν με γράμμα καί μπορουν να περιέχουν
αλφαριθμητικούς χαρακτήρες.
Επίσης δεν μπορουν να περιέχουν ειδικούς χαρακτήρες
όπως #, &, * κλπ.
Υπάρχουν συγκεκριμένα ονόματα τα οποία αναφέρονται
σε λέξεις κλειδιά της C
Τα ονόματα των μεταβλητών είναι ευαισθητα στην δομή
τους (Κεφαλαίοι, μικροί χαρακτήρες) π.χ. AVariable ≠
Avariable
Φ1β-6
ΛΕΞΕΙΣ ΚΛΕΙΔΙΑ ΠΟΥ ΔΕΝ ΜΠΟΡΟΥΝ ΝΑ
ΧΡΗΣΙΜΟΠΟΙΗΘΟΥΝ ΓΙΑ ΜΕΤΑΒΛΗΤΕΣ
auto
double
int
struct
break
else
long
switch
case
enum
register
typedef
char
extern
return
union
const
float
short
unsigned
continue
for
Signed
void
default
goto
sizeof
volatile
do
if
static
while
Φ1β-7
ΚΑΛΕΣ ΠΡΑΚΤΙΚΕΣ ΟΝΟΜΑΣΙΑΣ
ΜΕΤΑΒΛΗΤΩΝ
Χρήση μικρών χαρακτήρων (όχι κεφαλαίων)
Μη χρήση μικρών και κεφαλαίων για δύο
διαφορετικές μεταβλητές π.χ one καί ONE
Χρήση μνημονικών ονομάτων π.χ.
interestRate αντί ir
Κατανοητή σύνταξη γιά πολύπλοκα ονόματα π.χ.
interestRate, ή interest_Rate αντί
interestrate
Φ1β-8
ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ (1)
Όπως είπαμε, η C είναι μία typed language όπου οι μεταβλητές
ορίζονται να είναι συμβατές με κάποιο συγκεκριμένο τύπο.
Υπάρχουν δύο μεγάλες κατηγορίες τύπων δεδομένων
– Βασικοί τύποι που προσφέρει η γλώσσα
– Τύποι που ορίζονται από τον χρήστη
Στή C έχουμε τους παρακάτω βασικούς τύπους δεδομένων
– Integer types (ακέραιοι αριθμοί)
– Floating point types (πραγματικοί αριθμοί)
– Character types (σύμβολα π.χ. Γράμματα και στοιχεία)
Οι σύνθετοι (aggregate) τύποι που ορίζονται από τον χρήστη
μπορούν να παραχθούν σαν διανύσματα (arrays) ή/και κατασκευές
(structures) άλλων βασικών ή συνθέτων τύπων ανάλογα με το
πρόβλημα και τη σχεδίαση του αλγόριθμου που χρησιμοποιείται για
την επίλυση του προβλήματος.
Φ1β-9
ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ (2)
Οι παρακάτω λέξεις κλειδιά χρησιμοποιούνται για τον ορισμό ακεραίων
μεταβλητών. Οι όροι μέσα σε στις παρενθέσεις είναι προαιρετικοί. Οι
διαφορετικοί συνδυασμοί αφορούν στό «εύρος» των διαφορετικών τιμών
που μιά μεταβλητή ενός συγκεκριμένου τύπου μπορεί να αποθηκεύσει:
–
–
–
–
–
–
–
–
–
char
signed char
unsigned char
[signed] short [int]
unsigned short [int]
[signed] [int] (ένα από τα δύο πρέπει να ορισθεί)
unsigned [int]
[signed] long [int]
unsigned long [int]
Οι τύποι char, signed char, και unsigned char είναι μη αριθμητικοί τύποι και
δεν μπορούν άμεσα να παρουσιασθούν σαν αριθμοί κατά την είσοδο/έξοδο
δεδομένων του προγράμματος. Κωδικοποιούνται όμως εσωτερικά στον Η/Υ
σαν ακέραιοι χρησιμοποιώντας το κώδικα ASCII.
Οι τύποι short, int, και long θεωρούνται αυτόματα signed
Φ1β-10
ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ (3)
Το εύρος των τιμών που μπορεί να αποθηκεύσει
μία μεταβλητή απο κάθε ένα από τους
παραπάνω τύπους εξαρτάται απο τον
συγκεκριμένο μεταφραστή και το συγκεκριμένο
επεξεργαστή. Όμως σε κάθε περίπτωση θα
πρέπει το μέγεθος που καταλαμβάνει η
μεταβλητή στη μνήμη να είναι:
– Μέγεθος του char ≤ Μέγεθος του short int ≤ Μέγεθος
int ≤ Μέγεθος του long int
Φ1β-11
ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ (4)
Οι λέξεις κλειδιά που χρησιμοποιούνται για τον
ορισμό μεταβλητών πραγματικων αριθμών είναι
– float (πραγματικός αριθμός)
– double (διπλής ακριβείας πραγματικός)
– long double (διπλής ακρίβειας πραγματικός με
ακρίβεια 15 δεκαδικών ψηφίων)
Οι πραγματικοί αριθμοί στη C είναι απλά ένα
υποσύνολο των πραγματικών αριθμών στα
μαθηματικά μιάς και λόγω περιορισμών στη
μνήμη του Η/Υ δεν μπορούμε να
παρουσιάσουμε αριυμους πέρα από ένα όριο.
Φ1β-12
ΒΑΣΙΚΟΙ ΤΥΠΟΙ ΔΕΔΟΜΕΝΩΝ (5)
(Borland 5.02 C)
Τύπος
Signed
(με πρόσημο)
Unsigned
(χωρίς πρόσημο)
char
-128 έως 127
0 έως 255
short int
-32768 έως 32767
0 έως 65535
int
-231 έως 231 - 1
0 έως 232 - 1
long int
-231 έως 231 - 1
0 έως 232 - 1
float
10-38 έως 10+38
Ακρίβεια 7 δεκαδικών
double
10-308 έως 10+308
Ακρίβεια 15 δεκαδικών
long double
10-4932 έως 10+4932
Ακρίβεια 18 δεκαδικών
Φ1β-13
Δυαδικοί Αριθμοί
Ένας δυαδικός αριθμός είναι μια
ακολουθία από 0 και 1.
Η μετατροπή ενός δυαδικού αριθμού
b3b2b1b0b-1b-2b-3 είναι
(b3 X 23 ) + (b2 X 22) + (b1 X 21) + (b0 X 20) + (b-1 X
2-1) + (b-2 X 2-2) + (b-3 X 2 -3)
Οπότε (1011.101)2 = (11.625)10
Φ1β-14
Signed και Unsigned
Στούς αριθμούς με πρόσημο (signed) όταν το πρώτο bit είναι 0 δηλώνει
θετικό πρόσημο και όταν είναι 1 δηλώνει αρνητικό.
Οι αρνητικές τιμές είναι γνωστές σαν συμπλήρωμα του 2 ή δυαδικό
συμπλήρωμα. Για να παράγουμε το δυαδικό συμπλήρωμα ενός αριθμού
λαμβάνουμε το 2n – x όπου n είναι το πλήθος των bits και χ είναι ο αριθμός
του οποίου προσπαθούμε να υπολογίσουμε το δυαδικό συμπλήρωμα.
Το πλεονέκτημα του δυαδικού συμπληρώματος είναι ότι δυαδικοί αριθμοί
μπορούν να προστεθούν ή να αφαιρεθούν σαν να ήταν χωρίς πρόσημο.
Π.χ.
Δυαδική Παρουσίαση
110
+ 011
______
001
Δεκαδική Παρουσίαση
-2
+3
_____
+1
Φ1β-15
Signed και Unsigned (Παράδειγμα
σε Ακεραίους)
Δυαδικό
000
001
010
011
100
101
110
111
Δεκαδικό χωρίς
πρόσημο (unsigned)
0
1
2
3
4
5
6
7
Δεκαδικό με
πρόσημο (signed)
0
1
2
3
-4
-3
-2
-1
Φ1β-16
ΑΡΙΘΜΗΤΙΚΗ ΜΕ signed/unsigned
Στή C δέν γίνεται αυτόματα ο έλεγχος για
να διαπιστωθεί ότι το αποτέλεσμα μιάς
πράξης είναι στά σωστά όρια του τύπου
της μεταβλητής.
Ένα παράδειγμα έιναι ότι
2147483647 + 1 = - 2147483648 δηλαδή
(231 -1 ) + 1= -231 !!!
Φ1β-17
ΣΤΑΘΕΡΕΣ
Οι μεταβλητές πού ορίζονται να έχουν σταθερές τιμές σ’ όλη τη διάρκεια του
προγράμματος μπορεί να είναι ακέραιοι (int) ή πραγματικοί (float, double), ή
χαρακτήρες (char).
Μιά ακέραια σταθερή π.χ. 1234 είναι int. Μία long παρίσταται με την
καταλληξη l ή L π.χ. 123456789L. Unsigned σταθερές δηλώνονται με την
κατάλληξη U π.χ. 1234567UL. Ακέραιες σταθερές μπορούν να
παρουσιαστούν και στο οκταδικό σύστημα με το πρόθεμα 0 (μηδέν) π.χ. ο
δεκαδικός 31 είναι 037 εάν ορισθεί σαν οκταδικός, και 0x1f εάν ορισθεί στο
δεκαεξαδικό σύστημα. Π.χ. 011 είναι οκταδικός και είναι ο αριθμός 9 στό
δεκαδικό.
Πραγματικές σταθερές ορίζονται με την κατάλληξη f.
Οι χαρακτήρες σταθερές ορίζονταο μέ quotes (‘ ‘) π.χ. ‘a’. Η τιμή της
σταθερής είναι η τιμή του χαρακτήρα στο σύστημα μετατροπής που
χρησιμοποιεί ο συγκεκριμένος Η/Υ. Π.χ. Ο χαρακτήρας ‘0’ έχει τιμη στον
κώδικα ASCII 48.
Περισσότερα για σταθερές αργότερα στο μάθημα.
Φ1β-18
ΠΑΡΑΔΕΙΓΜΑΤΑ
int anIntegerVariable;
float aFloatVariable;
char aCharVariable;
double aDoubleVariable;
#define MAXLINE 100
#define ASTRING “I am a string”
unsigned short aVar;
signed int aSignedInt;
Για αρχή ας εστιάσουμε στους ακεραίους καί στούς πραγματικούς
(με ή χωρίς πρόσημο)
Φ1β-19
ΠΑΡΑΔΕΙΓΜΑ
#include <stdio.h>
#define fahr1 0
#define fahr2 20
#define fahr3 40
#define fahr4 60
/* Τύπωσε τους βαθμους σε κλίμακα Κελσίου καί Φαρεναΐτ. /*
void main()
{
int celcius1, celcius2, celcius3, celcius4;
celcius1 = 5 * (fahr1 – 32) / 9;
celcius2 = 5 * (fahr2 – 32) / 9;
celcius3 = 5 * (fahr3 – 32) / 9;
celcius4 = 5 * (fahr4 – 32) / 9;
printf(“%d\t%d\n”, fahr, celcius)
/* Τύπωσε ακέραιο, tab, ακέραιο */
}
Το αποτέλεσμα θα είναι
0 -17
20 -6
40 4
60 15
Φ1β-20
ΕΝΤΟΛΕΣ ΕΙΣΟΔΟΥ/ΕΞΟΔΟΥ
Ας δούμε δύο βασικές εντολές εισόδου /
εξόδου καί συγκεκριμένα τις:
– printf, και την scanf
Φ1β-21
ΕΝΤΟΛΗ ΕΚΤΥΠΩΣΗΣ ΣΤΗΝ
ΟΘΟΝΗ (standard output)
Η σύνταξη της εντολής printf έιναι
printf(“δήλωση φόρμας”, έκφραση1, έκφραση2 ...)
όπου:
Η δήλωση φόρμας ορίζει το πως θα φορμάρεται ή
εκτύπωση, και το τι θα τυπώνεται στο standard output.
H δήλωση φόρμας ορίζει επίσης το πώς οι τιμές των
μεταβλητών που είναι να τυπωθούν, μετατρέπονται
από τη εσωτερική δυαδική μορφή του Η/Υ στην
επιθυμητή μορφή της εκτύπωσης.
Φ1β-22
ΠΑΡΑΔΕΙΓΜΑ
void main()
{
int i, j;
float x, y;
Δήλωση φόρμας
Εκτύπωση σε ακεραίου
i = 10;
Εκτύπωση σε πραγματικό
j = 20;
x = 43.2892;
y = 5527.0;
printf( “ i = %d, j = %d, x = %f, y = %f\n” , i, j, x, y);
}
Οι μεταβλητές για εκτύπωση
Αποτέλεσμα εκτύπωσης : i = 10, j = 20, x = 43.289200, y = 5527.0000
Φ1β-23
ΤΥΠΟΙ ΜΕΤΑΤΡΟΠΗΣ
Στη δήλωση φόρμας οι πιο κοινές παρακάτω μετατροπές ορίζονται:
–
–
–
–
%d : Εκτύπωση ακεραίου
%e : Εκτύπωση πραγματικού σε εκθετική μορφή
%f : Εκτύπωση πραγματικού σε δεκαδική μορφή με δεκαδικά ψηφία
%g : Εκτύπωση πραγματικού σε εκθετική ή σε δεκαδική μορφή ανάλογα με το
μεγεθός του
Συμπληρωματικά με τα παραπάνω, η γενική μορφή είναι :
– %m.pX όπου
m δηλώνει τον ελάχιστο αριθμό «χαρακτήρων» πρός εκτύπωση, p δηλώνει τον
αριθμό δεκαδικών ψηφίων για εκτύπωση, και Χ είναι ένα από %d, %f, %g.
– a alert bell – ηχητικό σήμα
– \n new line – νέα γραμμή
– \b backspace – κενό πρίν
– \t horizontal tab – οριζόντιο κενό
συγκεκριμένου
μήκους
Δοκιμάστε το παρακάτω πρόγραμμα
Φ1β-24
ΠΑΡΑΔΕΙΓΜΑ
int main()
{
int i = 40;
float x = 839.21;
printf(“|%d|%5d|%-5d|%5.3d|\n”, i, i, i, i);
printf(“|%10.3f|%10.3e|%10g|\n”, x, x, x, x);
return (1);
}
Φ1β-25
ΕΝΤΟΛΗ ΕΙΣΟΔΟΥ ΑΠΟ ΤΟ
ΠΛΗΚΤΡΟΛΟΓΙΟ (standard input)
Η σύνταξη της εντολής scanf έιναι
scanf(“δήλωση φόρμας”, έκφραση1, έκφραση2 ...)
όπου:
Η δήλωση φόρμας ορίζει το πως θα φορμάρεται ή
εκτύπωση, και το τι θα διαβάζεται απο το standard
input.
H δήλωση φόρμας ορίζει επίσης το πώς οι τιμές των
μεταβλητών θα διαβαστούν.
Φ1β-26
ΠΑΡΑΔΕΙΓΜΑ
Διαφορά από το
printf
void main()
{
int i, j;
float x, y;
scanf(%d%d%f%f”, &i, &j, &x, &y);
}
Εάν ο χρήστης εισάγει 1, -20, .3, -4.0ε3 τότε η παραπάνω εντολή εισόδου θα
διαβάσει και θα αναθέσει στη μεταβλητή i τον αριθμό 1, στη j το -20, στη x το
0.3, και στη y το -4000.0
Φ1β-27
ΕΚΦΡΑΣΕΙΣ (expressions)
Οι εκφράσεις στη C είναι συντακτικές μορφές
που παράγονται από το τον συνδυασμό
μεταβλητών, σταθερών, και τελεστών
(operators). Προς το παρόν θα ασχοληθούμε με
ακέραιες και πραγματικές μεταβλητές.
Μεταβλητές ακέραιου, και πραγματικού τύπου
μπορούν να συνδυαστούν με αριθμητικούς
τελεστές.
Το σημαντικό στοιχείο είναι ο τύπος του
αποτελέσματος που προκύπτει.
Φ1β-28
ΑΡΙΘΜΗΤΙΚΟΙ ΤΕΛΕΣΤΕΣ
(+) Πρόσθεση (δυαδικός τελεστής – binary operator), και έκφραση θετικού
προσήμου (μοναδιαίος τελεστής – unary operator)
(-) Αφαίρεση (δυαδικός τελεστής – binary operator), και έκφραση αρνητικού
προσήμου (μοναδιαίος τελεστής – unary operator)
(*) Πολλαπλασιασμός (δυαδικός τελεστής – binary operator)
(/) Διαίρεση (δυαδικός τελεστής – binary operator)
(%) Υπόλοιπο διαίρεσης (γιά ακέραιους τύπους μόνο - (δυαδικός τελεστής –
binary operator)
Άλλοι τελεστές που θα δούμε αργότερα είναι οι λογικοί τελεστές, σχεσιακοί
τελεστές, καί τελεστές δυαδικών ψηφίων (bitwise operators)
Φ1β-29
ΠΑΡΑΔΕΙΓΜΑTA
25
aVariable
+x
-anotherVariable
a*b
a/b (Παράγει ακέραιο αποτέλεσμα όταν οι τυποι των a, b,
είναι ακέραιοι.
count/n
a+ (b+c)/32) + 12
(b-4ac)/2d
a%b (η γνωστή μας σχέση a modulo b)
Φ1β-30
ΥΠΟΛΟΓΙΣΜΟΣ ΤΩΝ
ΕΚΦΡΑΣΕΩΝ
Ο υπολογισμός του αποτελέσματος μιάς έκφρασης
εξαρτάται απο την προτεραιότητα και την συσχέτιση των
τελεστών.
Η προτεραιότητα καθορίζει τη σειρά εφαρμογής (order of
application) των τελεστών. Για παράδειγμα, η έκφραση
2*2+4 υπολογίζεται με την τιμή 8 μιάς και ο τελεστής του
Πολ/σμού έχει μεγαλύτερη προτεραιότητα από τον τελεστή
της Πρόσθεσης.
Χρησιμοποιώντας παρενθέσεις μπορούμε να αλλάξουμε
τη δομή μιάς έκφρασης και ουσιαστικά να μεταβάλλουμε
τον τρόπο υπολογισμού της. Για παράδειγμα η έκφραση
2*(2+4) υπολογίζεται με την τιμή 12.
Η συσχέτιση καθορίζει τη σειρά εφαρμογής τελεστών με
την ίδια προτεραιότητα. Για παράδειγμα θεωρώντας οτι οι
τελεστές / και * έχουν την ίδια προτεραιότητα η συσχέτιση
τους ορίζει ότι η έκφραση 6/2*3 υπολογίζεται με την τιμή 9,
αντί τη τιμή 1.
Φ1β-31
ΠΡΟΤΕΡΑΙΟΤΗΤΑ ΚΑΙ
ΣΥΣΧΕΤΙΣΗ ΤΕΛΕΣΤΩΝ
ΠΡΟΤΕΡΑΙΟΤΗΤΑ
ΤΕΛΕΣΤΗΣ
ΣΥΣΧΕΤΙΣΗ
ΥΨΗΛΗ
Μοναδιαίος +, -
Από δεξιά προς τα
αριστερά
.........
*, /, %
Από αριστερά προς τα
δεξιά
ΧΑΜΗΛΗ
Δυαδικός +, -
Από αριστερά προς τα
δεξιά
Φ1β-32
ΠΑΡΑΔΕΙΓΜΑΤΑ
1/5
υπολογίζεται με την τιμή 0
10/3
υπολογίζεται με την τιμή 3
10%3
υπολογίζεται με την τιμή 1
10%2
υπολογίζεται με την τιμή 0
10+2
υπολογίζεται με την τιμη 12
10*2-2
υπολογίζεται με την τιμή 18
10/0
δεν ορίζεται (διαίρεση με 0)
10%0
δεν ορίζεται (υπόλοιπο διαίρεσης με 0)
7/2+3
υπολογίζεται με την τιμή 6
-10+2
υπολογίζεται με την τιμη -8
10/2 + -10/3 = (10/2) + ((-10)/3) υπολογίζεται με την τιμη 2
Φ1β-33
ΜΕΤΑΤΡΟΠΗ ΤΥΠΩΝ (1)
Όταν οι μεταβλητές/σταθερές είναι του ιδίου τύπου το αποτέλεσμα
είναι γενικά του αυτού τύπου.
Όταν όμως οι μεταβλητές/σταθερές σε μία έκφραση δέν είναι του
ιδίου τύπου τότε λέμε οτι έχουμε μία μικτή έκφραση.
Στη C υπάρχουν μερικοί απλοί κανόνες αυτόματης μετατροπής
τύπων στις μικτές εκφράσεις.
Γενικά ο κανόνας είναι να μετατρέπεται ο τύπος με το μικρότερο
μέγεθος στον τύπο με το μεγαλύτερο μέγεθος έτσι ώστε δεν χάνεται
πληροφορία. Για παράδειγμα εαν f έιναι float και ο i είναι integer τότε
στην έκφραση f+i o I μετατρέπεται σε float.
Η έκφραση υπολογίζεται στον τύπο με το μεγαλύτερο μέγεθος
Το αποτέλεσμ είναι τύπου όμοιου με τον «μεγαλύτερο» τύπο στην
έκφαρση.
Εκφράσεις που αναθέτουν ένα τύπο μεγαλύτερου μεγεθους σε ένα
μικρότερο (π.χ. i = f) συνήθως δημιουργούν μια παρατήρηση
(warning) από τον μεταφραστή (compiler) και γενικά πρέπει να
αποφεύγονται.
Φ1β-34
ΠΙΝΑΚΑΣ ΜΕΤΑΤΡΟΠΗΣ ΤΥΠΩΝ
Ο παρακάτω πίνακας δείχνει τον τύπο του αποτελέσματος σαν συνάρτηση
των τύπων στην έκφραση.
Μέγεθος
Operand
types
int
long
float
double
long double
int
int
long
float
double
long double
long
long
long
float
double
long double
float
float
float
float
double
long double
double
double
double
double
double
long double
long double long double long double long double long double long double
Φ1β-35
ΑΛΓΟΡΙΘΜΟΣ ΜΕΤΑΤΡΟΠΗΣ
ΤΥΠΩΝ
Έστω μια έκφραση x op y, για κάποιο τελεστή op.
Βήμα 1.
Κάθε char ή short μετατρέπεται σε int.
Κάθε unsigned cha ή unsigned short μετατρέπεται σε
unsigned (int).
Βήμα 2.
Αν μετά το πρώτο βήμα η έκφραση είναι μικτού τύπου
η έκφραση έχει σαν αποτέλεσμα ένα τύπο ανάλογα με
τον «μεγαλύτερο τύπο» που υπάρχει στην έκφραση
και σύμφωνα με τον παρακάτω κανόνα μεγέθους τύπων
int < unsigned < long < unsigned long < float < double
Φ1β-36
ΠΑΡΑΔΕΙΓΜΑΤΑ
Έστω οι ακόλουθες δηλώσεις:
char c; double d; float f; int i; long l; short s; unsigned u;
Έκφραση
c–s/i
u*3–i
u * 3.0 – i
f*3–i
c+1
c + 1.0
3*s+l
Τελικός Τύπος
int
unsigned
double
float
int
float
long
Φ1β-37
ΛΟΓΙΚΟΙ ΤΕΛΕΣΤΕΣ και
ΛΟΓΙΚΕΣ ΕΚΦΡΑΣΕΙΣ
Οι λογικές εκφράσεις παράγουν ένα από τα δύο αποτελέσματα:
True, False
Έχουμε τρεις βασικούς λογικούς τελεστές
– Σύζευξη (and) ορίζεται με τον τελεστή && στη C
– Διάζευξη (or) ορίζεται με τον τελεστή || στη C
– Άρνηση (not) ορίζεται με τον τελεστή ! στη C
Οι λογικοί τελεστές χρησιμοποιούνται για να παράγουν λογικές
εκφράσεις
Παράδειγμα
int a, b;
a = 1;
b = 0;
(a && b)
(a || b)
((!a || b) && c)
Στη C η λογική τιμή true ορίζεται με την ακέραια τιμή 1 και η λογική
τιμή false με την ακέραια τιμή 0
Φ1β-38
ΕΡΜΗΝΕΙΑ ΛΟΓΙΚΩΝ ΤΕΛΕΣΤΩΝ
Έκφραση
a && b
a || b
!a
a
True
True
False
False
True
True
False
False
True
False
b
True
False
True
False
True
False
True
False
Αποτέλεσμα
True
False
False
False
True
True
True
False
False
True
Φ1β-39
ΣΧΕΣΙΑΚΟΙ ΤΕΛΕΣΤΕΣ
(relational operators)
Οι βασικοί σχεσιακοί τελεστές είναι
Τελεστής
<
Ερμηνεία
Μικρότερο
<=
Μικρότερο ή ίσο
>
Μεγαλύτερο
>=
Μεγαλύτερο ή ίσο
==
Ίσο (έλεγχος)
!=
Όχι ίσο (έλεγχος)
Φ1β-40
ΠΑΡΑΔΕΙΓΜA
int main()
{
int a = 4;
int b = 3;
int c = 2;
int x = (a < b);
int y = (a == c);
int z = ( x && y )
return (z);
}
Ποια είναι η τιμή της μεταβλητής z;
Φ1β-41
ΠΡΟΤΕΡΑΙΟΤΗΤΑ ΚΑΙ ΣΥΣΧΕΤΙΣΗ
Όπως έχουμε δει ο
υπολογισμός του
αποτελέσματος μιας
έκφρασης εξαρτάται από
την προτεραιότητα και
την συσχέτιση των
τελεστών.
Προτεραιότητα Τελεστής
Συσχέτιση
Υψηλή
+ - ++ ! -(μοναδιαίος)
Δεξιά προς
αριστερά
*/%
Αριστερά
προς δεξιά
+(δυαδικός)
΄΄
΄΄
< <= > >=
΄΄
΄΄
== !=
΄΄
΄΄
&&
΄΄
΄΄
||
΄΄
΄΄
= /= *= %=
+= -=
Δεξιά προς
αριστερά
Πως υπολογίζεται η έκφραση
(1) α/ β*γ; και (2) η α == β+γ
Χαμηλή
Απ. (1) Από αριστερά προς τα
δεξιά  (α / β) *γ και (2)
με διαφορά προτεραιότητας  (α == (β+γ))
Φ1β-42
ΕΛΕΓΧΟΣ ΡΟΗΣ ΠΡΟΓΡΑΜΜΑΤΟΣ
Μέχρι τώρα έχουμε μιλήσει για στοιχεία της C που αφορούν τον
ορισμό μεταβλητών, την είσοδο και εκτύπωση δεδομένων από το
πληκτρολόγιο και την οθόνη αντίστοιχα, εκφράσεις και διάφορους
τελεστές
Ουσιαστικά στην απλούστερη μορφή ένα πρόγραμμα είναι μια
ακολουθία από εντολές που εκτελούνται με τη σειρά (από την πρώτη
εντολή προς την τελευταία)
Όμως για να είμαστε σε θέση να υλοποιήσουμε πιο σύνθετους
αλγόριθμους θα πρέπει να έχουμε την δυνατότητα του ελέγχου της
ροής του προγράμματος
Αυτό επιτυγχάνεται με εντολές ελέγχου ροής
– Διακλάδωση με συνθήκη
– Εντολές βρόγχου
– Συναρτήσεις
Φ1β-43
Εντολές Διακλάδωσης με Συνθήκη
Η εντολή if χρησιμοποιείται για να ορίσει
την υπό συνθήκη εκτέλεση μίας ή
περισσοτέρων εντολών. Υπάρχουν δύο
βασικοί τύποι της εντολής if
1.
2.
Συνθήκη
True
Εντολές
If-then
Συνθήκη
False
True
Εντολές
False
Εντολές
If-then-else
Φ1β-44
Η ΠΡΩΤΗ ΜΟΡΦΗ
Σύνταξη:
if (<λογική έκφραση>)
{
εντολή1
εντολή2
...........
εντολήκ
}
Παράδειγμα
Εναλλακτικά
if (a <= b)
{
if (a <= b)
{
a = a+1;
b = b/3;
}
a += 1;
b /= 3;
}
Φ1β-45
Η ΔΕΥΤΕΡΗ ΜΟΡΦΗ
Παράδειγμα
Σύνταξη:
if (<λογική έκφραση>)
{
εντολή1;
εντολή2 ;
...........
εντολήκ ;
}
else
{
εντολήκ+1;
Κάθε εντολή μπορεί
εντολήκ+2;
να είναι σύνθετη (μπλοκ)
.............
{
εντολήν;
s1;
}
s2;
….
}
if (a <= b)
{
a=3;
b=4;
{
a = a+1;
b = b/3;
}
}
else
{
a = a+5;
b = b%3;
}
printf(“a is: %d\n”, a);
Φ1β-46
ΑΛΓΟΡΙΘΜΟΙ ΚΑΙ ΥΛΟΠΟΙΗΣΗ
ΠΡΟΓΡΑΜΜΑΤΟΣ
Έχουμε μιλήσει για τις δύο βασικές μεθόδους ανάλυσης
ενός προβλήματος. Όμως πώς αυτές συσχετίζονται με την
σχεδίαση προγραμμάτων;
Η αναλυτική μέθοδος (top down) σχετίζεται με την μέθοδο
σχεδίασης «διαίρει και βασίλευε» (divide and conquer),
όπου για να σχεδιάσουμε ένα πρόγραμμα το διαιρούμε σε
απλούστερα προγράμματα
Η συνθετική μέθοδος (bottom up) σχετίζεται με την μέθοδο
σχεδίασης «σταδιακή εξέλιξη» (successive refinement),
όπου αρχίζουμε με ένα απλό πρόγραμμα και σταδιακά του
προσθέτουμε περισσότερες λεπτομέρειες μέχρι που όλες
οι περιπτώσεις που πρέπει να λυθούν έχουν λυθεί
Φ1β-47
ΨΕΥΔΟ-ΚΩΔΙΚΑΣ
(pseudocode)
Όταν είμαστε έτοιμοι να παρουσιάσουμε ένα αλγόριθμο
(πρόγραμμα) μπορούμε να χρησιμοποιήσουμε ψευδοκώδικα αντί
μια γλώσσα προγραμματισμού
Αυτό μας δίνει το πλεονέκτημα ότι η σχεδίαση του αλγόριθμου δεν
επηρεάζεται από την γλώσσα που θα χρησιμοποιηθεί οπότε
διαχωρίζονται οι φάσεις σχεδίασης προγράμματος (design) από την
υλοποίηση του προγράμματος (implementation)
Ο ψευδοκώδικας είναι ένα μαθηματικό μοντέλο του αλγόριθμου,
εκφραζόμενο σε μια μορφή που θυμίζει (αλλά δεν είναι) γλώσσα
προγραμματισμού
Η ιδέα είναι ότι από τον ψευδοκώδικα είναι απλή η διαδικασία της
υλοποίησης (αναλογία μεταξύ Αρχιτέκτονα που σχεδιάζει και
Εργολάβου που ακολουθεί πιστά το σχέδιο για την ανέγερση μιας
οικοδομής)
Φ1β-48
ΠΑΡΑΔΕΙΓΜΑ ΨΕΥΔΟΚΩΔΙΚΑ
Μία πιθανή μορφή ψευδοκώδικα είναι:
let name1, name2 (ορισμός μεταβλητών)
get name1, name2 (διάβασε τις μεταβλητές name1, name2
από κάποια μονάδα εισόδου)
record name1, name2 (αποθήκευσε τις τρέχουσες τιμές των μεταβλητών name1,
name2
σε κάποια εξωτερική μονάδα – π.χ. Δίσκο)
name1  έκφραση (αποθήκευσε την τιμή της έκφρασης
στη μεταβλητή name1
if expression then
A
else
B
endif
Φ1β-49
ΠΑΡΑΔΕΙΓΜΑ
Πρόβλημα
Να σχεδιάσετε και να υλοποιήσετε ένα
πρόγραμμα το οποίο να διαβάζει τις
παραμέτρους ενός πολυωνύμου δευτέρου
βαθμού αx2 + βx + γ = Π(x) και
να υπολογίζει τις ρίζες τις εξίσωσης
Π(x) = 0.
Ο αλγόριθμος είναι
x = (- β ± sqrt(β2 – 4*α*γ))/ (2*α)
Φ1β-50
ΠΑΡΑΔΕΙΓΜΑ
Μία απλή μορφή του ψευδοκώδικα είναι
(περίπτωση με πραγματικές ρίζες)
get a, b, c;
root1  (-b + sqrt(b2 -4ac)/(2a);
root2  (-b - sqrt(b2 -4ac)/(2a);
record root1, root2;
Όμως τι γίνεται για τις άλλες περιπτώσεις όπου
α = 0, ή α = 0 και β = 0, ή η διακρίνουσα είναι
αρνητική;
Φ1β-51
ΣΤΑΔΙΑΚΗ ΕΞΕΛΙΞΗ ΤΟΥ ΨΕΥΔΟΚΩΔΙΚΑ
Ο ψευδοκώδικας γίνεται
get a, b, c;
if a = 0 then
if b = 0 then
case  1;
record case;
else
case  2;
root1  - c/b
record case, root1;
endif
else
if b2 >= 4ac then
case  3;
root1  (-b + sqrt(b2 – 4ac) / (2a);
root2  (-b - sqrt(b2 – 4ac) / (2a);
record case, root1, root2;
else
case  4;
root1  (-b/ (2a)) + j (sqrt(abs(b2 – 4ac)) / (2a));
root1  (-b/ (2a)) - j (sqrt(abs(b2 – 4ac)) / (2a));
record case, root1, root2;
endif
endif
Η υλοποίηση του προγράμματος είναι
τώρα απλή υπόθεση.
Φ1β-52
ΕΝΤΟΛΕΣ ΕΠΑΝΑΛΗΨΗΣ
(ΒΡΟΓΧΟΥ)
Οι εντολές βρόγχου (iterative statements) στη C επιτρέπουν την
επαναληπτική εκτέλεση μιάς σειράς εντολών όσο κάποιες λογικές
συνθήκες ισχύουν. Στη C έχουμε τις παρακάτω εντολές βρόγχου,
που αντιστοιχούν και σε διαφορετικές περιπτώσεις επανάληψης:
– Εντολή while
– Εντολή do-while
– Εντολή for
Η σειρά των εντολών που επαναλαμβάνεται ονομάζεται το «σώμα»
(body) της εντολής βρόγχου. Η λογική συνθήκη ονομάζεται
«συνθήκη» (condition). Το σημείο που η επανάληψη σταματά
ονομάζεται «σταθερό σημείο» (fixed point)
Φ1β-53
ΚΑΤΑΣΚΕΥΕΣ ΕΠΑΝΑΛΗΨΗΣ
Πρίν προχωρήσουμε όμως στη μελέτη της σύνταξης
αυτών των εντολών ας μελετήσουμε πρωτα την
κατασκευή τους και γιατι όχι τον αντίστοιχο ψευδοκώδικα
τους και την γραφική ερμηνεία τους
Κατασκευή (structure) δίνει τη γενική ιδέα και την
ερμηνεία μέσω ενός μοντέλου (π.χ. Διαγράμματος ροής).
Η κατασκευή είναι σχετικά ανεξαρτητη της γλώσσας
προγραμματισμού.
Η εντολή (statement ή command) έχει να κάνει με την
συγκεκριμένη γλώσσα προγραμματισμου (π.χ. Σύνταξη
της C) και υλοποιεί μία κατασκευή.
Στη C έχουμε τρείς κατασκευέ βρογχου ή επανάληψης
(iterative structures). Δύο απο αυτές υλοποιούνται άμεσα
με εντολές της C
Φ1β-54
ΚΑΤΑΣΚΕΥΕΣ ΕΠΑΝΑΛΗΨΗΣ 1
while A do
B
endwhile
Όσο ισχύει η (λογική έκφραση Α) επανελαβε
σειρά εντολών Β
Τελος επανάληψης
Συνθήκη
False
Α
True
Β
Φ1β-55
ΚΑΤΑΣΚΕΥΕΣ ΕΠΑΝΑΛΗΨΗΣ 2
επανελαβε σειρά εντολών Β
όσο ισχύει η (λογική έκφραση Α)
Τελος επανάληψης
do B
while A
Β
Συνθήκη
False
Α
Η διαφορά απο την προηγούμενη
κατασκευή είναι οτι η σειρά
εντολών Β θα εκτελεστεί
τουλαχιστον μία φορά πρίν τη
λογίκή συνθήκη Α
True
Φ1β-56
ΕΝΤΟΛΗ while
Η εντολή while έχει τη μορφή
while (<λογική έκφραση Α>)
σειρά εντολών Β
Παράδειγμα:
int i = 0
while (i <= 10)
{
printf(“The number is: %d\n”, i);
i++;
}
Σημαίνει i = i+1
Φ1β-57
ΠΑΡΑΔΕΙΓΜΑ
Ένα μικρό πρόγραμμα που υπολογίζει το άθροισμα των αριθμών από 1
μέχρι 10.
#include <stdio.h>
int main() {
int i = 1;
int sum = 0;
while (i <= 10)
{
sum = sum + i;
i = i+1;
}
printf(“The sum of numbers from 1 to 10 is: %d\n”, sum);
return (sum);
}
Φ1β-58
ΠΑΡΑΔΕΙΓΜΑ
Ένα μικρό πρόγραμμα που υπολογίζει το άθροισμα των κύβων των
αριθμών 0.4 0.8 1.2 1.6 2.0 2.4
#include <stdio.h>
Λίγο μεγαλύτερη τιμή
float main() {
από 2.4 για να προλάβουμε
float sum = 0.0;
προβλήματα με rounding
float increment = 0.4;
error π.χ. Στη τελευταία επανάληψη
float x = 0.4;
η μεταβλητή χ να είναι λίγο μεγαλύτερη
while (x <= 2.5)
του 2.4 μιας και οι float μπορεί να
{
έχουν περισσότερα από ένα δεκαδικό
sum = sum + x*x*x;
x = x+ increment;
}
printf(“The sum of the cubes is: %f\n”, sum);
return (sum);
}
Φ1β-59
ΠΑΡΑΔΕΙΓΜΑ
Ένα μικρό πρόγραμμα που διαβάζει από μία πηγή εισόδου (input stream)
χαρακτήρες (characters), και τους τυπώνει σε πηγή εξόδου (output stream).
#include <stdio.h>
float main() {
int c;
int nl = 0;
…………
π.χ. εντολές γιά άνοιγμα αρχείου για διάβασμα
..............
c = getchar();
while (c != EOF)
{
putchar(c);
if(c == ‘\n’)
nl++;
c= getchar();
}
}
Φ1β-60
ΕΝΤΟΛΗ do while
Η εντολή while έχει τη μορφή
do σειρά εντολών Β
while (<λογική έκφραση Α>)
Χρησιμοποιείται όταν θέλουμε η σειρά εντολών Β να εκτελεστεί τουλάχιστον
μία φορά πριν τον έλεγχο τερματισμού.
Παράδειγμα:
#include <stdio.h>
int i = 0
do
{
printf(“The number is: %d\n”, i);
i = i + 1;
}
while (i <= 10)
Φ1β-61
ΠΑΡΑΔΕΙΓΜΑ
Ένα μικρό πρόγραμμα που διαβάζει αριθμούς από τον χρήστη και υπολογίζει το άθροισμα
τους. Το πρόγραμμα θα σταματήσει όταν ο χρήστης δώσει ένα αριθμό μικρότερο ή ίσο του
μηδενός. Εάν το άθροισμα είναι αρνητικό τότε επιστρέφουμε μηδέν.
#include <stdio.h>
float main() {
signed float number;
signed float sum = 0;
do
{
printf(“Enter a number: “);
scanf(“%f”, &number);
sum = sum + number;
printf(“\n”); /* Πήγαινε στην επόμενη γραμμή στην οθόνη */
}
while (!(number == 0 || number < 0))
if( sum <= 0) /* Στη περίπτωση που ο χρήστης εισάγει 0 ή αρνητικό σαν πρώτο αριθμό */
sum = 0; /* θέσε τη μεταβλητή sum ίση πάλι με το μηδέν */
printf(“The sum of numbers is: %f\n”, sum);
return (sum);
}
Φ1β-62
ΕΝΤΟΛΗ for
Η εντολή for έχει τη μορφή
for (<αρχικές τιμές>; <έλεγχος τερματισμού>; <έκφραση ανανεωσης τιμών>)
σειρά εντολών Β
Παράδειγμα:
#include <stdio.h>
int main () {
int i, sum=0;
for (i = 1; i <= 10; i++)
{
sum = sum + 1;
printf(The sum now is: %d\n”, sum);
}
printf(“The final sum is:%d\n”, sum);
return (sum);
}
Φ1β-63
ΠΑΡΑΔΕΙΓΜΑ
100
Ένα μικρό πρόγραμμα που υπολογίζει το άθροισμα ∑ χ3
Χ=10
#include <stdio.h>
int main() {
int number;
int sum = 0;
for (number = 10; number <= 100; number++)
{
sum = sum + number * number * number;
printf(“The number is %d and the sum is now: %d\n”, number, sum);
}
printf(“The final sum is %d\n”, sum);
return (sum);
}
Φ1β-64
ΠΑΡΑΔΕΙΓΜΑ
Ένα μικρό πρόγραμμα που υπολογίζει το άθροισμα
100
∑ χ3
Χ=10
Ο Τελεστής ,
#include <stdio.h>
int main() {
int sum;
int number;
for (sum = 0, number = 10; number <= 100; number++)
{
sum = sum + number * number * number;
printf(“The number is %d and the sum is now: %d\n”, number, sum);
}
printf(“The final sum is %d\n”, sum);
return (sum);
Φ1β-65
ΠΑΡΑΔΕΙΓΜΑ
Ένα μικρό πρόγραμμα που να υπολογίζει τα
τετράγωνα αριθμών απο το 1 μεχρι n
#include <stdio.h>
int main() {
int i, n;
printf(“Enter the max number to compute the square: “);
scanf(“%d”, &n);
for (i = 1; i <= n; i++)
1
{
2
printf(“%10d%10d\n”, i, i*i);
3
4
}
……….
return (1);
}
1
4
9
16
Φ1β-66
ΙΣΟΔΥΝΑΜΙΕΣ ΕΝΤΟΛΩΝ while, for
<αρχική τιμή 1>
while (<έκφραση τερματισμού 2>)
{
εντολές 4
<έκφραση αναπροσδιορισμού τιμών 3>
}
for (<αρχική τιμή 1>;
<έκφραση τερματισμού 2>;
<έκφραση αναπροσδιορισμού
τιμών 3>)
{
εντολές 4
}
i = 1;
while (i <= 10)
{
statements;
i++;
}
for (i = 1; i <= 10; i++)
{
statements
}
Φ1β-67
ΟΡΙΣΜΟΙ ΜΕΤΑΒΛΗΤΩΝ
ΒΡΟΓΧΟΥ - 1
Ας θεωρήσουμε το πρόγραμμα
for (int i = 1; i <= 100; i++)
printf(“The number is %d\n”, i);
Η μεταβλητή i δεν υπάρχει και δεν είναι διαθέσιμη μετά την εκτέλεση της εντολής for
Αντίθετα στο πρόγραμμα
int i;
for(i = 1; i<=100; i++)
printf(“The number is %d\n”, i);
Η μεταβλητή i είναι διαθέσιμη μετά την εκτέλεση της εντολής for. Μερικοί
μεταφραστές όμως δεν θεωρούν τη μεταβλητή i διαθέσιμη !!!
Φ1β-68
ΟΡΙΣΜΟΙ ΜΕΤΑΒΛΗΤΩΝ
ΒΡΟΓΧΟΥ - 2
Ας θεωρήσουμε το πρόγραμμα
void main() {
do
{
float i = 10.0
statements;
…………..
i++;
}
while i <= 100.0
}
Η μεταβλητή i δεν μπορεί να ορισθεί μέσα σ’ένα εσωτερικό block εντολής.
Το πρόγραμμα αυτό είναι λάθος.
Φ1β-69
ΟΡΙΣΜΟΙ ΜΕΤΑΒΛΗΤΩΝ
ΒΡΟΓΧΟΥ - 3
Αντίθετα sτο πρόγραμμα
void main() {
float i = 10.0
do
{
statements;
…………..
i++;
}
while i <= 100.0
Η μεταβλητή i έχει ορισθεί στο block του main. Θα μπορούσε να
είχε ορισθεί και μετά τις εντολές του προεπεξεργαστή. Θα μιλήσουμε
για το εύρος και ορίζοντα των δηλώσεςν των μεταβλητών αργότερα.
Φ1β-70
ΚΑΤΑΣΚΕΥΗ ΕΠΑΝΑΛΗΨΗΣ 3
Σε μερικές περιπτώσεις μας ενδιαφέρει να
έχουμε την λογική έκφραση τερματισμού του
βρογχου ούτε στην αρχή, ούτε στο τέλος, αλλά
κάπου στη μέση της σειράς εντολών που
εκτελούνται επαναληπτικά
Δυστυχώς δεν υπάρχει άμεση εντολή στη C που
να υλοποιεί αυτή τη περίπτωση (π.χ. Η
κατασκευη 1 υλοποιείται με την εντολή while και
for ενώ η κατασκευή 2 με την εντολή do-while)
Γραφικά η κατασκευή 3 είναι:
Φ1β-71
ΚΑΤΑΣΚΕΥΕΣ ΕΠΑΝΑΛΗΨΗΣ 3 –
ΓΡΑΦΙΚΗ ΠΑΡΑΣΤΑΣΗ
Β1
True
Α Συνθήκη
False
Β2
Η διαφορά από την
προηγούμενες κατασκευές είναι
ότι η σειρά εντολών Β1 θα
εκτελεστεί τουλάχιστον μία φορά
πριν τη λογική συνθήκη Α η
οποία εάν είναι αληθής τότε η
επανάληψη σταματά, αλλιώς η
σειρά εντολών Β2 θα εκτελεστεί,
και ο βρόγχος θα επαναληφθεί.
Φ1β-72
ΥΛΟΠΟΙΗΣΗ ΤΗΣ ΚΑΤΑΣΚΕΥΗΣ 3
#define TRUE 1
#define FALSE 0
void main() {
int flag;
flag = TRUE;
while (flag)
{
εντολές Β1;
if (λογική συνθήκη Α)
{
flag = FALSE;
}
else
{
εντολές Β2;
}
}
}
Η υλοποίηση αυτή απαιτεί μια
παραπάνω μεταβλητή (flag) αλλά
είναι εύκολα κατανοητή και επεκτάσιμη
Φ1β-73
ΥΛΟΠΟΙΗΣΗ ΤΗΣ ΚΑΤΑΣΚΕΥΗΣ 3
#define TRUE 1
Αυτό το loop δεν θα
σταμάταγε ποτέ
void main() {
while (TRUE) /* Συνεχής επανάληψη */
{
εντολές Β1;
if (λογική συνθήκη Α)
break;
εντολές Β2;
}
}
Μόνο η πρώτη εντολή
break εκτελείται στο if διότι
δεν υπάρχουν¨{ }. Η εντολή
break σταματά το βρόγχο και
μεταφέρει τον έλεγχο στην
πρώτη εντολή μετά το βρογχο.
Φ1β-74
ΛΙΓΑ ΛΟΓΙΑ ΓΙΑ ΤΗΝ ΚΑΤΑΣΚΕΥΗ 3
Φαίνεται και είναι λίγο παράξενη. Όμως την συναντάμε
συχνά ιδιαίτερα όταν διαβάζουμε από ένα αρχείο ή ΄το
πρόγραμμα λαμβάνει στοιχεία από τον χρήστη.
Η πρώτη υλοποίηση χρειάζεται μία επιπλέον μεταβλητή
αλλά είναι εύκολα κατανοητή. Η δεύτερη υλοποίηση
χρησιμοποιεί την εντολή break που χρησιμοποιείται γιά
να τερματίσει οποιοδήποτε βρόγχο. Όμως η εντολή
break μπορεί να δημιουργήσει σύγχυση ιδιαίτερα όταν
υπάρχουν βρόγχοι μέσα σε άλλους βρόγχους.
Παρακάτω παρουσιάζονται τέσσερα σενάρια χρήσης της
κατασκευής 3 (βιβιλογραφία: B. Preiss, J, Fields)
Φ1β-75
ΣΕΝΑΡΙΟ 1
void main() {
int done = 0;
while (! done)
Η υλοποίηση αυτή απαιτεί μια
{
παραπάνω μεταβλητή (done) αλλά
{
είναι εύκολα κατανοητή και επεκτάσιμη
διαβάζουμε στοιχεία;
}
if (συνθήκη τερματισμού εισόδου στοιχείων)
done = 1;
else
{
διαδικασίες χρήσης των στοιχείων
}
}
}
Φ1β-76
ΣΕΝΑΡΙΟ 2
Η break δημιουργεί τα γνωστά
προβλήματα κατανόησης. Μπορεί
όμως σ’αυτή τη περίπτωση να
αντικατασταθεί με την εντολή return, και
όλη η υλοποίηση να γίνει μια function που
κάπως θα επιστρέφει τα επιθυμητά
αποτελέσματα
#define TRUE 1
void main() {
while (TRUE)
{
διαβάζουμε στοιχεία;
if (συνθήκη τερματισμού εισόδου στοιχείων)
break;
διαδικασίες χρήσης των στοιχείων
}
}
Φ1β-77
ΣΕΝΑΡΙΟ 3
Η υλοποίηση αυτή είναι παρόμοια με αυτή
του Σεναρίου 1, αλλά χρησιμοποιεί την εντολή
do-while
void main() {
int done = 0;
do
{
διαβάζουμε στοιχεία;
if (συνθήκη τερματισμού εισόδου στοιχείων)
done = 1;
else
{
διαδικασίες χρήσης των στοιχείων
}
}
while (!done)
Φ1β-78
ΣΕΝΑΡΙΟ 4
Στην υλοποίηση αυτή θεωρούμε ότι το διάβασμα
των στοιχείων γίνεται από μία συνάρτηση (function)
η οποία επιστρέφει κάποια αριθμητική τιμή (ώστε
να μπορεί να χρησιμοποιηθεί σε μιά λογική έκφραση,
ΚΑΙ έχει σαν παράπλευρο αποτέλεσμα την απόθεση
των στοιχείων σε κάποιες μεταβλητές που είναι
ορατές από το πρόγραμμα. Γενικά όχι καλός τρόπος.
void main() {
.................
while (διαβάζουμε στοιχεία() && ! συνθήκη τερματισμού εισόδου στοιχείων)
{
διαδικασίες χρήσης των στοιχείων
}
}
Φ1β-79
ΣΥΝΘΕΤΕΣ ΕΝΤΟΛΕΣ ΒΡΟΓΧΟΥ
Σε μερικές περιπτώσεις χρειαζόμαστε να
έχουμε βρόγχους (loops) μέσα σε άλλους
βρόγχους (nested loops)
Γενικά σ’αυτή τη περίπτωση το ζητούμενο
έιναι να προσέχουμε ποιές διαδικασίες
χρειάζονται σε ποιό βρόγχο οπότε να μην
έχουμε παράπλευρα φαινόμενα, ή
παραπάνω απ΄ότι χρειάζεται
πολυπλοκότητα
Φ1β-80
ΠΑΡΑΔΕΙΓΜΑ
Ας υλοποιήσουμε ένα πρόγραμμα
το οποίο θα
5 10
υπολογίζει το αθροισμα ∑ ∑ κ*χ
k=1 x=2
#include <stdio.h>
int main() {
int k, x, sum = 0;
for(k=1; k<= 5; k++)
for(x=2; x<=10; x++
sum = sum + k*x;
return (sum)
(1*2 + 1*3 + … 1*10) +
(2*2 + 2*3 + ….2*10) +
………………………..
(5*2 + 5*3 + …5*10)
}
Φ1β-81
ΕΙΣΑΓΩΓΗ ΣΤΑ ΑΡΧΕΙΑ (FILES)
Στη C ο όρος stream ορίζει μία πηγή στοιχείων εισόδου,
ή ένα προορισμό για στοιχεία εξόδου
Δύο βασικά και οριζόμενα αυτόματα απο τη C streams
είναι το πληκρολόγιo (keyboard) για είσοδο (input), και η
οθόνη (screen or terminal), για έξοδο (output)
Τα μεγάλα προγράμματα μπορούν να έχουν πολλές
πηγές εισόδου π.χ. Modems, CD drives, files, κλπ.
Τα προγράμματα συνήθως διαβάζουν στοιχεία απο μια
πηγή και στέλνουν αποτελέσματα σε ένα προορισμό
(που μπορεί να είναι πηγή στοιχείων για κάποιο άλλο
πρόγραμμα)
Φ1β-82
ΔΕΙΚΤΕΣ ΑΡΧΕΙΩΝ
(FILE POINTERS)
Ένα C πρόγραμμα μπορεί να χρησιμοποιήσει ένα αρχείο σαν πηγή
στοιχείων εισόδου, ή προορισμό στοιχείων εξόδου με το ορισμό δεικτών
αρχείου
Ο ορισμός ενός δείκτη αρχείου γίνεται με την εντολή FILE *
Ουσιαστικά ένας δείκτης αρχείου ορίζει οτι μια μεταβλητή (π.χ. ifp) είναι
τύπου (type) FILE, και το πρόγραμμα έτσι καταλαβαίνει πως να
χρησιμοποιήσει τη μεταβλητή ifp.
Για παράδειγμα έαν θέλουμε να έχουμε δύο αρχέια για χρήση (είσοδο, ή
έξοδο) στο πρόγραμμά μας τα οποία χρησιμοποιούνται και ορίζονται με
τις μεταβλητές π.χ. fp1, fp2 με τότε η εντολή ορισμoύ τους είναι:
FILE *fp1, *fp2;
Φ1β-83
ΒΑΣΙΚΕΣ ΠΗΓΕΣ
ΔΕΙΚΤΗΣ ΑΡΧΕΙΟΥ
ΠΗΓΗ
ΕΡΜΗΝΕΙΑ
stdin
Βασική πηγή εισόδου
Πληκτρολόγιο
stdout
Βασική πηγή εξόδου
Οθόνη
stderr
Βασική πηγή
Οθόνη
διαγνωστικών μηνυμάτων
Οι εντολές printf, scanf που έχουμε εξετάσει μέχρι τώρα λαμβάνουν στοιχεία
από την πηγή stdin και αποστέλουν στοιχεία στο stdout. Μπορύμε να αλλάξουμε
την ερμηνεία των stdin, και stdout να είναι ένα αρχείο αντί του πληκτρολογίου
ή της οθόνης αντίστοιχα. Αυτό γίνεται με τη χρήση του λειτουργικού συστήματος
και των τελεστών > ή < π.χ. demo < in.dat
Πρόγραμμα
Αρχείο με στοιχεία
εισόδου
Φ1β-84
ΨΗΦΙΑΚΑ ΑΡΧΕΙΑ ΚΑΙ ΑΡΧΕΙΑ
ΚΕΙΜΕΝΟΥ
Η βιβλιοθήκη stdio.h υποστηρίζει δύο ειδών αρχεία –
ψηφιακά, και κειμένου (χαρακτήρων). Ο πηγαίος κώδικας
που γράφουμε για παράδειγμα αποθηκεύεται σ’ένα
αρχείο, ενώ το συμβολομεταφρασμένο πρόγραμμα σ’ένα
ψηφικό αρχείο (θα το δείτε αυτο εάν προσπαθήσετε να
ανοίξετε μ’ένα επεξεργαστή κειμένου ή editor ένα exe
αρχείο.
Στη συγκεκριμένο παράδειγμα ο μεταφραστής είναι ένα
πρόγραμμα (ίσως και αυτό γραμμένο στη C !!) το οποίο
έχει ώς πηγή εισόδου ένα αρχείο κειμένου (πηγαίο
κώδικα), και σαν προόρισμό ένα αρχείο κειμένου
(assembly code). O συμβολομεταφραστής είναι και
αυτός ένα πρόγραμμα (ίσως και αυτό γραμμένο στη C !!)
το οποίο έχει ώς πηγή εισόδου ένα αρχείο κειμένου
(assembly code) και σαν προόρισμό ένα ψηφιακό αρχείο
(binary code).
Φ1β-85
ΨΗΦΙΑΚΑ ΑΡΧΕΙΑ ΚΑΙ ΑΡΧΕΙΑ
ΧΑΡΑΚΤΗΡΩΝ - ΠΑΡΑΔΕΙΓΜΑ
Για παράδειγμα άς δούμε πως ο αριθμός 32767 θα μπορούσε να παρασταθεί
σ΄ένα αρχέιο κειμένου, και σ΄ένα ψηφιακό αρχείο. Σ΄ένα αρχείο κειμένου θα
φαινεται σαν η «λεξη» κειμένου 32767 που διαβάζεται απο τόν χρήστη.
Εσωτερικά όμως στη μνήμη του Η/Υ θα παριστάνεται σαν η ακολουθία (έαν
υποθέσουμε ότι χρησιμοποίούμε κώδικα ASCII (συνολο 5 bytes, 8 bits = 1 byte)
00110011
3
00110010
00110111
2
00110110
00110111
2
7
2
Ο ίδιος αριθμός 32767 θα μπορούσε να παρασταθεί σ΄ένα ψηφιακό αρχέιο σαν
δύο bytes
01111111
11111111
Φ1β-86
ΨΗΦΙΑΚΑ ΑΡΧΕΙΑ ΚΑΙ ΑΡΧΕΙΑ
KEIMENOY - 2
Γιατί όμως χρειαζόμαστε δύο τύπων αρχεία? Μερικοί
από τους λόγους είναι
– Μέγεθος
– Ο τρόπος που το κάθε λειτουργικό σύστημα καταλαβαίνει τη
δομή του αρχείου (EOL, EOF)
– Η δυνατότητα χρήσης ειδικών χαρακτήρων
Τα αρχεία κειμένου συνήθως αποτελούνται από σειρές
γραμμών, και κάθε γραμμή σταματά με ένα ειδικό
χαρακτήρα (end of line). Επείσης υπάρχει ένας ειδικός
χαρακτήρας για να δηλώνει το τέλος του αρχείου (end of
file).
Τα ψηφιακά αρχεία συνήθως δεν είναι χωρισμένα σε
γραμμές, και επειδή ένα ψηφιακό αρχείο μπορεί να
περιέχει οποιοδήποτε στοιχείο δεν μπορούμε συνήθως
να διακρίνουμε το τέλος μιάς «γραμμής»
Φ1β-87
ΨΗΦΙΑΚΑ ΑΡΧΕΙΑ ΚΑΙ ΑΡΧΕΙΑ
KEIMENOY (DOS)
End of line: Ο τρόπος που ορίζεται το τέλος μιάς
γραμμής σ΄ένα αρχείο κειμένου είναι ουσιαστικά δύο
χαρακτήρες – τέλος γραμμής (carriage return) και νέα
γραμμή (line feed). Ο τρόπος για ένα ψηφιακό αρχείο
είναι ένας χαρακτήρας - νέα γραμμή (line feed).
End of file: Ο χαρακτήρας Control-Z \x1a σ΄ένα αρχείο
κειμένου ορίζει το τέλος του αρχείου. Σ’ένα ψηφιακό
αρχείο ο χαρακτήρας Control-Z δέν έχει σημασία. Στο
UNIX τα ψηφιακά αρχεία και τα αρχεία κειμένου έχουν
την ίδι δομή σεχετικα με το End of line, End of file.
Φ1β-88
ΛΕΙΤΟΥΡΓΙΕΣ ΑΡΧΕΙΩΝ
Ανοιγμα αρχείου: Για να «ανοίξουμε ένα
αρχείο» σαν πηγή εισόδου ή εξόδου,
χρησιμοποίούμε την εντολή fopen. H
γενική σύνταξη είναι
fopen(<ονομα αρχείου>, <χρήση>)
Παράδειγμα
fopen(“c:\\project\\test.dat”, “r”)
Φ1β-89
fopen
Η εντολή (ουσιαστικά συνάρτηση) fopen,
επιστρέφει ένα δείκτη αρχείου. Επιστρέγει
NULL εάν το αρχείο δεν μπορεί να ανοίξει.
Οπότε η ολοκληρωμένη εικόνα είναι:
Δήλωση δέικτη
FILE *fp;
Χρήση για είσοδο (read)
………..
fp = fopen(“c:\\project\\test.dat”, “r”)
Για να μην θεωρήσει ο μεταφραστής
ότι είναι ειδικοί χαρακτήρες
Φ1β-90
ΠΑΡΑΔΕΙΓΜΑ
Ένα μικρό πρόγραμμα που να ανοίγει ένα
αρχείο
#include <stdio.h>
FILE *fp;
int main() {
fp = fopen(“test.dat”, “r”)
…………….
}
Φ1β-91
fclose
Η εντολή κλείνει ένα αρχείο στο τέλος του προγράμματος
ή όταν αυτό δεν χρειάζεται πιά είναι η fclose. H σύνταξη
της εντολής fclose είναι
fclose (<δείκτης αρχείου>)
Παράδειγμα
FILE *fp;
………..
fp = fopen(“c:\\project\\test.dat”, “r”)
.............
fclose(fp)
Φ1β-92
ΠΑΡΑΔΕΙΓΜΑ
Ένα μικρό πρόγραμμα που να ανοίγει ένα αρχείο να ελέγχει εάν μπορεί να
ανοίξει και να το κλείνει.
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME “test.dat”
int main() {
FILE *fp;
fp = fopen(“test.dat”, “r”);
if (fp == NULL)
{
printf(“Can not open file %s\n”, FILE_NAME);
exit(EXIT_FAILURE);
}
………………..
fclose(fp);
}
Φ1β-93
ΚΩΔΙΚΟΙ ΧΡΗΣΗΣ
Είδαμε ότι για να
ανοίξουμε ένα αρχέιο
χρησιμοποιούμε την
εντολη fopen με
σύνταξη
fopen(<ονομα αρχείου>,
<χρήση>)
Οι κωδικοι χρήσης
είναι:
ΚΩΔΙΚΟΣ
ΕΡΜΗΝΕΙΑ
“r”
Άνοιγμα για να διαβάσει το
πρόγραμμα στοιχεία
“w”
Άνοιγμα για να «γραψει» το
πρόγραμμα αποτελέσματα
“a”
Άνοιγμα για να «γράψει» στο
τέλος υπάρχοντος αρχείου
“r+”
Άνοιγμα για είσοδο-έξοδο,
απο την αρχή του αρχείου
“w+”
Άνοιγμα για είσοδο-έξοδο, με
κάλυψη
“a+”
Άνοιγμα για είσοδο-έξοδο,
απο το τέλος εάν το αρχείο
υπάρχει.
Φ1β-94
ΕΙΣΟΔΟΣ/ΕΞΟΔΟΣ ΣΤOΙΧΕΙΩΝ
ΑΠΟ ΑΡΧΕΙΟ
Η είσοδος/έξοδος στοιχείων απο αρχείο είναι
πανεύκολη ! Χρησιμοποιεί τις εντολές fprintf,
fscanf που έχουν λιγο πολύ πανομοιότυπη
σύνταξη με τις printf και, scanf !!
Η σύνταξη είναι:
fprintf( <δείκτης αρχείου> , <δήλωση φόρμας>, έκφραση1, έκφραση2 ...)
fscanf ( <δείκτης αρχείου> , <δήλωση φόρμας>, έκφραση1, έκφραση2 ...)
Φ1β-95
ΠΑΡΑΔΕΙΓΜΑ
#include <stdio.h>
Int main(){
FILE *ifp;
FILE *ofp;
int c;
ifp = fopen(“test.dat”, “r”);
ofp = fopen(out.dat”, “w”);
Το πρόγραμμα διαβάζει χαρακτήρες από
το αρχείο ifp (“test.dat”) και τους
αντιγράφει στο αρχείο ofp (“out.dat”)
if(ifp == NULL) {
printf(“Can not open input file\n”);
return(0);
}
if(ofp == NULL) {
printf(“Can not open output file\n);
return (1);
}
c = getc(ifp);
while(c != EOF) {
putc(c, ofp);
c = getc(ifp);
}
fclose(ifp); fclose(ofp);
return(2)
}
Φ1β-96
ΠΑΡΑΔΕΙΓΜΑ
#include <stdio.h>
int main(){
FILE *ifp;
FILE *ofp;
int c;
ifp = fopen(“test.dat”, “r”);
ofp = fopen(out.dat”, “w”);
Το πρόγραμμα διαβάζει ακεραίους από
το αρχείο ifp (“test.dat”) και τους
αντιγράφει στο αρχείο ofp (“out.dat”)
if(ifp == NULL) {
printf(“Can not open input file\n”);
return(0);
}
if(ofp == NULL) {
printf(“Can not open output file\n);
return (1);
}
fscanf(ifp, “%d\n”, &c);
while(c != EOF) {
fprintf(ofp, “%d\n”, c);
fscanf(ifp, “%d\n”, &c);
}
fclose(ifp); fclose(ofp);
return(2)
}
Φ1β-97