Lec10

  • October 2019
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Lec10 as PDF for free.

More details

  • Words: 1,493
  • Pages: 42
Συναρτήσεις • Κληση/Επιστροφη • Παραμετροι • Περασμα/Επιστροφη δια αναφορας • Δεικτες (τελεστες * και &)

• Εμβελεια Μεταβλητων (συναρτησεων) • τοπικες/καθολικες/στατικες/αυτοματες

• Αναδρομη

#include <stdio.h> float compute_area(float x, float y);

πρωτοτυπο συναρτησης

{

ορισμος συναρτησης

τυπικοι παραμετροι float compute_area(float a, float b) return (a * b); } int main() { float length, width, area;

ορισματα/ πραγματικοι παραμετροι

}

printf(“Enter length and width: “); scanf(“%f%f”,&length, &width); area = compute_area(length, width);

κληση συναρτησης

printf(“The area of a rectangle %f m by %f m is %f sq. m\n” length, width, area); return 0;

Σημασία Κλήσης • Κατανομη μνημης για παραμετρους και τοπικες μεταβλητες της συναρτησης (εαν υπαρχουν) • Αντιγραφη των τιμων των ορισματων στις παραμετρους (εαν υπαρχουν παραμετροι) • Ξεκινα εκτελεσης απο την πρωτη εντολη της συναρτησης

Σημασία Επιστροφής • Αποτιμηση της εκφρασης που ακολουθει το return και αντιγραφη της τιμης στο σημειο κλησης (εαν επιστρεφεται τιμη) • Συνεχιση εκτελεσης με την εντολη που ακολουθει την κληση

#include <stdio.h> int compute_sum(int x, int y); int compute_sum(int a, int b) { int sum; sum = a + b; return sum; } int main() { int sum=0; sum = compute_sum(5, 4);

sum

09

a

5

b sum

printf(“The sum of %d and %d is %d\n”,4, 5, sum); return(0); }

4 9

#include <stdio.h> int compute_sum(int x, int y); int compute_sum(int a, int b) { int sum; sum = a + b; return sum; }

sum

int main() { int sum=0; sum = compute_sum(5, 4); printf(“The sum of %d and %d is %d\n”,4, 5, sum); return(0); }

9

Παραμέτροι • Επιτρεπουν την επικοινωνια μεταξυ συναρτησεων – περασμα δια τιμης (τιμή) • Διοχετευση πληροφοριων προς στην συναρτηση • Μεταβλητη στην συναρτηση κλησης δεν επηρεαζεται αντιγραφεται η τιμη της

– περασμα/επιστροφη δια αναφορας (διεύθυνση) • Διοχετευση πληροφοριων απο την συναρτηση (και εισοδο) • Μεταβλητη στην συναρτηση κλησης μπορει να της ανατεθουν τιμες στην καλουμενη συναρτηση (scanf με τελεστη διευθυνσης) • Επιστροφη πολλων τιμων μεσο διευθυνσεων

#include <stdio.h> int swap(int x, int y); void swap(int a, int b) { int temp; temp = a; a = b; b = temp; }

a

4

c

6

int main() { int a=4, c=6; printf(“a: %d, b: %d\n”,a,c); swap(a, c); printf(“a: %d, b: %d\n”,a,c);

a

46

b

64

return(0); }

temp

4

#include <stdio.h> int swap(int *x, int *y); void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; }

a

46

c

64

int main() { int a=4, c=6; printf(“a: %d, c: %d\n”,a,c); swap(&a, &c); printf(“a: %d, c: %d\n”,a,c);

a

return(0); }

b temp

4

#include <stdio.h> int swap(int *x, int *y); void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } int main() { int a=4, c=6; printf(“a: %d, c: %d\n”,a,c); swap(&a, &c); printf(“a: %d, c: %d\n”,a,c); return(0); }

a

46

c

64

Δεικτες (pointers) • Συνταξη Δηλωσης Δεικτη – τυπος *ονομα_μεταβλητης – int *foo, *pointer, no_pointer;

• Σημασια Δεικτη – μεταβλητη που περιεχει διευθυνση μιας αλλης μεταβλητης

Δεικτες • Τελεστης Διευθυνσης & – Συνταξη: &ονομα_μεταβλητης (συναρτηση) – Σημασια: δινει την διευθυνση της μεταβλητης

• Τελεστης Εμμεσης Αναφορας * – Συνταξη: *διευθυνση – Σημασια: δινει την τιμη στην διευθυνση

Τελεστης * • Τελεστης γινομενου a*b;

• Δηλωση Δεικτη int *p;

• Τελεστης Εμμεσης Αναφορας * x = *p + 1;

Παραδειγμα με Δεικτες int *p, y, *z; y y = 6; p = &y; z = p; *p = *p + 1; y = *z + 1;

p

*p

z

*z

Παραδειγμα δεικτες • Γραψετε την συναρτηση sort2 που ταξινομει δυο αριθμους a και b ωστε μετα την εκτελεση a<=b • Χρειαζονται δεικτες

Παραδειγμα δεικτες void sort2(int *a, int *b) { int temp; if (*a>*b) temp=*a; *a=*b; *b=temp; }

Παραδειγμα δεικτες void sort2(int *a, int *b) { if (*a>*b) swap(a,b); }

Παραδειγμα δεικτες • Γραψετε την συναρτηση sort3 που ταξινομει τρεις ακεραιους αριθμους a, b και c ωστε μετα την εκτελεση a<=b<=c • Χρησιμοποιηστε την sort2

Παραδειγμα δεικτες void sort3(int *a, int *b, int *c) { sort2(a,b); /* a<= b*/ sort2(a,c); /* a<=c and a<=b sort2(b,c); /* b<= c */ }

Χρηση δεικτων • Χρησιμοποιατε δεικτες μονο οταν χρειαζονται - εμμεση αναφορα ειναι αργη σχεδον σε ολους τους υπολογιστες • Οταν μια συναρτηση επιστρεφει μια τιμη χρησιμοποιατε return αντι δεικτη • Πλευρικα φαινομενα μεσω δεικτων πιο δυσκολα να κατανοηθουν/ανιχνευτουν • Πολυ κοινη πηγη λαθων

Εμβέλεια Μεταβλητής (scope) • Το τμημα του προγραμματος που μπορει μια μεταβλητη να χρησιμοποιηθει – local (τοπικες): • δηλωνονται στην αρχη ενος programming block {..} • οπουδηποτε μετα τον ορισμο μεσα στο block

– global (καθολικες) • δηλωνονται εξω απο συναρτησεις • οπουδηποτε μετα τον ορισμο

– Συγκρουσεις:τοπικες ονομασιες εχουν προτεραιοτητα

#include <stdio.h> int sum=0;

Καθολικη (global)

int compute_sum(int x, int y); void compute_sum(int a, int b) { sum = a + b; }

int main() { int a = 4;

Παραμετροι (parameters)

Τοπικη (local) Ορισματα (arguments)

compute_sum(a, 6); printf(“The sum of %d and %d is %d\n”,a, 6, sum); return(0); }

Καθολικες Μεταβλητες • Γενικα πρεπει να αποφευγονται: δυσκολο να κατανοησεις πλευρικα φαινομενα γιατι διεπαφη γινεται χωρις παραμετρους • Χρησιμη για μεταβλητες που χρησιμοποιουντε απο πολλες συναρτησεις

#include <stdio.h> int sum=0; int compute_sum(int x, int y); int compute_sum(int a, int b) { int sum; sum = a + b; return sum; } int main() { sum = compute_sum(5, 4);

sum

09

a

5

b sum

printf(“The sum of %d and %d is %d\n”,4, 5, sum); return(0); }

4 9

#include <stdio.h> int sum=0; int compute_sum(int x, int y); void compute_sum(int a, int b) {

sum

09

a

5

sum = a + b; } int main() {

b

compute_sum(5, 4); printf(“The sum of %d and %d is %d\n”,4, 5, sum); return(0); }

4

Τοπικες Μεταβλητες • Αυτοματες (automatic) οι τιμες δεν διατηρουνται μεταξυ εκτελεσεων του block που δηλωνεται η μεταβλητη. Δεσμευση/ αποδεσμευση μνημης καθε κληση/ επιστροφη • Στατικες (static) οι τιμες τους υφιστανται μετα την πρωτη εκτελεση του block που ανηκουν. Μια φορα δεσμευση μνημης (αναδρομη!)

Παραδειγμα automatic και static void count_events(int events) { int total = 0; total += events; printf(“Events up to now: %d\n”,total); } int main() { count_events(5); count_events(10); return 0; }

Παραδειγμα automatic και static void count_events(int events) { static int total = 0; total += events; printf(“Events up to now: %d\n”,total); } int main() { count_events(5); count_events(10); return 0; }

Εμβέλεια Συναρτησεων C • Το τμημα του προγραμματος που μπορει μια συναρτηση να χρησιμοποιηθει • Oλες οι συναρτησεις σε ενα αρχειο ειναι καθολικες (δεν υπαρχουν τοπικες συναρτησεις) • Η C δεν παρεχει τοπικες συναρτησεις (αλλες γλωσσες μπορουν πχ pascal)

Αναδρομή (recursion) • Συναρτηση ειναι αναδρομικη εαν ο ορισμος της περιεχει κληση στον ευατο της • Αναδρομικη λυση ενος προβληματος ειναι συχνα ο “φυσικος” τροπος επιλυσης του • Διαμορφωση προβληματος για αναδρομικη λυση • Καθε αναδρομικη συναρτηση μπορει να υλοποιηθει με επαναληψη

Αναδρομή (recursion) • Αναδρομικη και Τερματικη περιπτωση – Πρεπει να υπαρχει τουλαχιστο μια βασικη περιπτωση (base-case) που τερματιζει αναδρομη. Αλλιως απειρος αναδρομη ή δεσμευση ολοκληρη μνημης. – Η αναδρομική κλήση πρέπει να είναι ένα βήμα πιο κοντά σε τερματική περίπτωση, από την κλήση που οδήγησε σε αυτή.

Αναδρομή (recursion) • • • •

Υπολογισμος n! n! = n n-1 n-2 … 1, 1!=1 0!=1 n! = n n-1! fact(n) = n fact(n-1) και fact(1)=1, fact(0)=1

Αναδρομή (recursion) float factorial(int n) { if (n<2) return 1; return n*factorial(n-1); }

float factorial(int n) { int i ; int fact = 1; for(i=n;i>2;--i) fact = fact *i; return fact; }

Προβληματα Αναδρομής • Αχρειαστος υπολογισμος • Δεσμευση μνημης (για αυτοματες μεταβλητες)

Ακολουθια Fibonacci • 0, 1, 1, 2, 3, 5, 8, 13, . . . . . • Fib(n) = Fib(n – 2) + Fib(n – 1) και Fib(0) = 0, Fib(1) = 1 • πχ – – – –

Fib(2) = Fib(0)+ Fib(1) = 0 + 1 = 1 Fib(3) = Fib(1)+ Fib(2)= 1 + 1 = 2 Fib(4) = Fib(2)+ Fib(3)= 1 + 2 = 3 ........

Αναδρομικο Fibonacci int Fib (int x){ if (x == 0) return 0; else if (x == 1) return 1; else return Fib(x – 2) + Fib(x – 1); }

Fib(5)

Fib(3)

Fib(1)

1

Fib(4)

Fib(2)

Fib(2)

Fib(0)

Fib(1)

Fib(0)

0

1

0

Fib(3)

Fib(1) Fib(1)

1

Fib(2)

1 Fib(0) Fib(1) 0

Ο ορισμός δεν είναι αποδοτικός

1

Fibonacci με επαναληψη int Fib (int x){ int f, a=0, b=1,i; if (x < 2) return x; for(i=2;i<=x;++i){ f=a+b; εννοια a = b; b = f; } return f; }

moving window

Αναδρομη και static • Συναρτηση read_and_sum που διαβαζει μια σειρα θετικων ακεραιων απροσδιοριστου μεγευθους (τερματιζεται με 0) και υπολογιζει και επιστρεφει το αθροισμα τους.

Αναδρομη και static int read_and_sum() { int number; scanf(“%d”,&number); if (number == 0) return 0; return number + read_and_sum(); }

Αναδρομη και static(problematic) int read_and_sum() { static int number; scanf(“%d”,&number); if (number == 0) return 0; return number + read_and_sum(); }

Αναδρομη Γραψετε την συναρτηση reverse που διαβαζει μια απροσδιοριστου μεγεθους σειρας και την τυπωνει αντιστροφα. void reverse() { int number; scanf(“%d”,&number); if (number == 0) return; printf(“%d\n”,number); }

Related Documents

Lec10
May 2020 2
Lec10
October 2019 3
Lec10
December 2019 1
Lec10
November 2019 2
Mae 640 Lec10
May 2020 1
Lec10 Vlsi Clocking
May 2020 1