Πξνγξακκαηηζκόο Ι (ΗΥ120) Δηάιεμε 13: Σπλαξηήζεηο & Δείθηεο
Αιιαγή ηνπ «εμσηεξηθνύ» πεξηβάιινληνο Αλ ζαλ παξάκεηξνο κηαο ζπλάξηεζεο δνζεί κηα κεηαβιεηή, ζαλ πξαγκαηηθή παξάκεηξνο ζα πεξαζηεί ε ηηκή ηεο. Τν πέξαζκα παξακέηξσλ είλαη θαζ απνηίκεζε. Οη πξαγκαηηθέο παξάκεηξνη (ηηκέο) απνζεθεύνληαη ζε ηνπηθή κλήκε πξνζσξηλέο κεηαβιεηέο κε ηα νλόκαηα ησλ αληίζηνηρσλ ηππηθώλ παξακέηξσλ. Αλ ν θώδηθαο ηεο ζπλάξηεζεο αιιάμεη ηελ ηηκή κηαο ηππηθήο παξακέηξνπ, ζηελ πξαγκαηηθόηεηα αιιάδεη ηελ ηηκή ηεο αληίζηνηρεο ηνπηθήο κεηαβιεηήο, όρη ηεο κεηαβιεηήο πνπ «πεξάζηεθε» ζαλ παξάκεηξνο. 2
#include <stdio.h> void inc0(int a) { a=a+1; νπνηαδήπνηε αιιαγή ζηελ a δελ επεξεάδεη ην «εμωηεξηθό» πεξηβάιινλ ηεο θιήζεο 3 int a; a=5; inc0(a); printf("a=%d\n", a); ζαλ πραγματική παξάκεηξνο (γηα ηελ ηππηθή παξάκεηξν a) πεξληέηαη ε τιμή 5 inc0(a); printf("a=%d\n", a);
Γείθηεο σο παξάκεηξνη ζπλαξηήζεσλ Αλ ζαλ παξάκεηξνο κηαο ζπλάξηεζεο δνζεί κηα δηεύζπλζε, ηόηε ε ζπλάξηεζε κπνξεί (πξνθαλώο) λα αιιάμεη ηα πεξηερόκελα ζε απηή ηελ ζέζε κλήκεο. Η αληίζηνηρε ηππηθή παξάκεηξνο πξέπεη λα δεισζεί σο δείθηεο-ζε-τ, θαη ν θώδηθαο ηεο ζπλάξηεζεο πξέπεη λα ρξεζηκνπνηεί απηή ηελ ηηκή αληίζηνηρα, όπσο αθξηβώο απαηηείηαη ζε κηα κεηαβιεηή δείθηε. Αληίζηνηρα, όηαλ θαιείηαη ε ζπλάξηεζε, ζαλ παξάκεηξνο πξέπεη λα δίλεηαη κηα δηεύζπλζε πνπ αληηζηνηρεί ζε έλα αληηθείκελν (κεηαβιεηή) ηύπνπ Τ. Πξνζνρή: έλα θιαζηθό ιάζνο είλαη ην πέξαζκα ηεο ηηκήο αληί ηεο δηεύζπλζεο ηεο κεηαβιεηήο. 4
#include <stdio.h> void inc0(int a) { a = a + 1; 5 void inc1(int *a_ptr) { *a_ptr = *a_ptr + 1; δείθηεο! int a1, a2; printf("enter int value: "); scanf("%d", &a1); a2=a1; δηεύζπλζε! inc0(a1); inc1(&a2); printf("a1=%d, a2=%d\n", a1, a2); inc0(a1); inc1(&a2); printf("a1=%d, a2=%d\n", a1, a2);
#include <stdio.h> void swap(int *a_ptr, int *b_ptr) { int tmp; 6 tmp=*a_ptr; *a_ptr=*b_ptr; *b_ptr=tmp; int i,j; printf("enter 2 int values: "); scanf("%d %d", &i, &j); printf("i=%d, j=%d\n", i, j); swap(&i,&j); printf("i=%d, j=%d\n", i, j);
Πίλαθεο σο παξάκεηξνη ζπλαξηήζεσλ 7 Η ηππηθή παξάκεηξνο δειώλεηαη σο πίλαθαο. Δελ είλαη ππνρξεσηηθό λα πξνζδηνξηζηεί ην κέγεζνο ηνπ πίλαθα κπνξεί λα δνζεί θαη σο παξάκεηξνο. Καηά ηελ θιήζε, ζαλ πξαγκαηηθή παξάκεηξνο πεξληέηαη (ζηελ ζηνίβα) ε δηεύζπλζε (ηνπ πξώηνπ ζηνηρείνπ) ηνπ πίλαθα, όρη ηα πεξηερόκελα ηνπ. Ο θώδηθαο ηεο ζπλάξηεζεο κπνξεί λα αιιάμεη ηηο ηηκέο ησλ ζηνηρείσλ ηνπ πίλαθα, θαη απηέο νη αιιαγέο ζα «παξακείλνπλ» αθνύ επηζηξέςεη ε ζπλάξηεζε. Παξαηήξεζε: κηα ηππηθή παξάκεηξνο ηύπνπ δείθηε-ζε-τ κπνξεί λα εξκελεπηεί σο ε αξρή ελόο πίλαθα από Τ.
/* αλλαγή σε κευαλαία */ #include <stdio.h> #define N 16 void smalltocapitals(char s[]) { int i; 8 for (i=0; s[i]!= '\0'; i++) { if ( (s[i] >= 'a') && (s[i] <= 'z') ) { s[i] = 'A' + s[i] - 'a'; char str[n]; scanf("%15s",str); printf("%s\n",str); smalltocapitals(str); printf("%s\n",str);
/* αλλαγή σε κευαλαία */ #include <stdio.h> #define N 16 void smalltocapitals(char *s) { int i; 9 for (i=0; s[i]!= '\0'; i++) { if ( (s[i] >= 'a') && (s[i] <= 'z') ) { s[i] = 'A' + s[i] - 'a'; char str[n]; scanf("%15s",str); printf("%s\n",str); smalltocapitals(str); printf("%s\n",str);
πάλσ κηζό Αο δνπιέςνπκε κόλν ζην /* αλλαγή σε κευαλαία */ #include <stdio.h> #define N 16 void smalltocapitals(char s[]) { int i; for (i=0; s[i]!= '\0'; i++) { if ( (s[i] >= 'a') && (s[i] <= 'z') ) { s[i] = 'A' + s[i] - 'a'; char str[n]; scanf("%7s",&str[8]); printf("%s\n",str); smalltocapitals(&str[8]); printf("%s\n",&str[8]); 10
/* ανάγνωση και ταξινόμηση ακεπαίων */ #include <stdio.h> #define N 10 void swap(int *a_ptr, int *b_ptr) { 11 void sort(int t[], int len) { int i, j; for (i=0; i<len; i++) for (j=i; j<len; j++) if (t[i]>t[j]) swap(&t[i],&t[j]); int buf[n], i; for (i=0; i<n; i++) scanf("%d", &buf[i]); sort(buf,n); for (i=0; i<n; i++) printf("%d ", buf[i]); printf("\n");
/* ανάγνωση και ταξινόμηση ακεπαίων */ #include <stdio.h> #define N 10 void swap(int *a_ptr, int *b_ptr) { 12 void sort(int *t, int len) { int i, j; for (i=0; i<len; i++) for (j=i; j<len; j++) if (t[i]>t[j]) swap(&t[i],&t[j]); int buf[n], i; for (i=0; i<n; i++) scanf("%d", &buf[i]); sort(buf,n); for (i=0; i<n; i++) printf("%d ", buf[i]); printf("\n");
Γελ είλαη ζσζηή ιύζε. Απιά ηαμηλνκείηαη ην θάησ κηζό θαη ην πάλσ κηζό ηνπ πίλαθα /* ανάγνωση και ταξινόμηση ακεπαίων */ #include <stdio.h> #define N 10 void swap(int *a_ptr, int *b_ptr) { void sort(int t[], int len) { int i, j; for (i=0; i<len; i++) for (j=i; j<len; j++) if (t[i]>t[j]) swap(&t[i],&t[j]); int buf[n],i; for (i=0; i<n; i++) scanf("%d", &buf[i]); sort(buf,n/2); sort(&buf[n/2],n/2); for (i=0; i<n; i++) printf("%d ", buf[i]); printf("\n"); 13
Σρόιην Η αιιαγή ηεο ηηκήο κηαο εμσηεξηθήο κεηαβιεηήο κέζα από ζπλάξηεζε, κέζσ δείθηε, κπνξεί λα ζεσξεζεί σο κηα κνξθή παξελέξγεηαο. Η δηαθνξά ζε ζρέζε κε ηελ αιιαγή θαζνιηθώλ κεηαβιεηώλ είλαη όηη γηα λα γίλεη απηό πξέπεη λα ππάξρεη ηππηθή παξάκεηξνο πνπ λα έρεη δεισζεί ζαλ δείθηεο, θαη όηαλ γίλεηαη ε θιήζε λα δίλεηαη ζαλ παξάκεηξνο ε δηεύζπλζε ηεο κεηαβιεηήο. Απηό είλαη νξαηό θαηά ηελ αλάγλσζε ηνπ θώδηθα, ζπλεπώο δελ απνηειεί «πξαγκαηηθή» παξελέξγεηα. Τν πξόζεκα const ζε κηα ηππηθή παξάκεηξν δείθηε, δειώλεη όηη ε ζπλάξηεζε δελ αιιάδεη ηα πεξηερόκελα πνπ βξίζθνληαη ζε απηή ηε δηεύζπλζε. 14
Γείθηεο σο απνηέιεζκα ζπλαξηήζεσλ 15 Μηα ζπλάξηεζε κπνξεί λα δεισζεί έηζη ώζηε λα επηζηξέθεη ζαλ απνηέιεζκα έλα δείθηε-ζε-τ. Χξεηάδεηαη πξνζνρή ώζηε ε ηηκή πνπ επηζηξέθεηαη λα αληηζηνηρεί ζε κεηαβιεηή (κλήκε) πνπ είλαη κόληκε. Η επηζηξνθή ηεο δηεύζπλζεο κηαο (ζπκβαηηθήο) πξνζσξηλήο ηνπηθήο κεηαβιεηήο κηαο ζπλάξηεζεο είλαη πξνγξακκαηηζηηθό ιάζνο, θαζώο απηή κπνξεί λα κελ πθίζηαηαη κεηά ηελ θιήζε ηεο ζπλάξηεζεο (θαηαζηξέθεηαη ην πιαίζην εθηέιεζεο). Απηό δελ εληνπίδεηαη από ην κεηαθξαζηή αιιά νδεγεί (αλ είκαζηε ηπρεξνί, θαη όρη πάληα) ζε ηεξκαηηζκό ηεο εθηέιεζεο ηνπ πξνγξάκκαηνο.
#include <stdio.h> int *add(int a, int b) { int c; c=a+b; return(&c); /* αςτό είναι λάθορ! */ 16 int f(int a, int b) { int c = 0; int a,b,*c; printf("enter 2 int values: "); scanf("%d %d", &a, &b); c=add(a,b); f(a,b); printf("the result is %d\n", *c);
Φξήζε ζπλαξηήζεσλ Χξεζηκνπνηνύκε ζπλαξηήζεηο: Όηαλ ην πξόγξακκα απνηειείηαη από κηα νκάδα εληνιώλ πνπ επαλαιακβάλεηαη πνιιέο θνξέο, θαη ε νπνία κπνξεί λα παξακεηξνπνηεζεί έηζη ώζηε λα γξάςνπκε ηνλ θώδηθα κηα κνλαδηθή θνξά. Όηαλ επηζπκνύκε, γηα ιόγνπο θαιύηεξεο δόκεζεο, λα ζπάζνπκε έλα κεγάιν ηκήκα θώδηθα ζε πεξηζζόηεξα, λνεκαηηθά αλεμάξηεηα, θνκκάηηα. Όηαλ επηζπκνύκε λα έρνπκε αλεμάξηεηα ηκήκαηα θώδηθα ζε δηαθνξεηηθά αξρεία ή/θαη κε δπλαηόηεηα μερσξηζηήο κεηάθξαζεο (π.ρ. βηβιηνζήθεο). 17
Φξήζε κεηαβιεηώλ Κάζε κεηαβιεηή εμππεξεηεί έλα ζπγθεθξηκέλν ζθνπό θαη νλνκάδεηαη αληίζηνηρα (ρσξίο ππεξβνιέο). Μεηαβιεηέο κε «εηδηθό» ξόιν ζρνιηάδνληαη ώζηε λα δηεπθνιύλνπλ ηελ αλάγλσζε ηνπ θώδηθα. Ιδαληθά, ε ιεηηνπξγία θάζε ζπλάξηεζεο πξέπεη λα είλαη θαηαλνεηή «από κόλε ηεο», ρσξίο λα γλσξίδνπκε ην ηη (αθξηβώο) θάλεη ν ππόινηπνο θώδηθαο ηνπ πξνγξάκκαηνο. Οη θαζνιηθέο κεηαβιεηέο πξέπεη λα ρξεζηκνπνηνύληαη κε ζύλεζε, κόλν όηαλ απινπζηεύνπλ ηνλ θώδηθα. 18
Σπλαξηήζεηο κε άγλσζην αξηζκό παξακέηξσλ Μπνξεί λα πινπνηεζνύλ ζπλαξηήζεηο κε άγλσζην (κεηαβιεηό) αξηζκό παξακέηξσλ, νξίδνληαο σο ηειεπηαία (αιιά όρη πξώηε) παξάκεηξν ην. Απηό είλαη βνιηθό ζε πεξηπηώζεηο πνπ ν αξηζκόο ησλ παξακέηξσλ δελ κπνξεί λα πξνζδηνξηζηεί εθ ησλ πξνηέξσλ ή είλαη επηζπκεηό ε ζπλάξηεζε λα κπνξεί λα θαιείηαη κε κεηαβιεηό αξηζκό παξακέηξσλ. Ο ζπλνιηθόο αξηζκόο ησλ παξακέηξσλ πξέπεη λα κπνξεί λα ππνινγίδεηαη κε βάζε ηηο ηηκέο ησλ (γλσζηώλ) παξακέηξσλ ηεο ζπλάξηεζεο. 19 Κιαζηθό παξάδεηγκα: printf θαη scanf.
Βαζηθέο ιεηηνπξγίεο βηβιηνζήθεο Γηα ηελ πξόζβαζε ζηηο παξακέηξνπο πνπ δόζεθαλ θαηά ηελ θιήζε, ρξεζηκνπνηνύληαη νη κάθξν-εληνιέο (από ηε βηβιηνζήθε stdarg): - va_list: ν ηύπνο ηεο ιίζηαο ησλ παξακέηξσλ - void va_start(va_list ap, last): αξρηθνπνηεί ηελ κεηαβιεηή ap ώζηε λα δείρλεη ζηελ πξώηε άγλσζηε παξάκεηξν κεηά ηελ ηειεπηαία γλσζηή παξάκεηξν ηεο ζπλάξηεζεο last - type va_arg(va_list ap, type): επηζηξέθεη ηελ ηηκή ηεο παξακέηξνπ ζηελ νπνία δείρλεη ε ap εξκελεύνληαο ηελ ζύκθσλα κε ηνλ ηύπν type θαη κεηαζέηεη ην ap ζηελ επόκελε ζέζε - void va_end(va_list ap): θαιείηαη πξηλ ηνλ ηεξκαηηζκό ηεο ζπλάξηεζεο 20
#include<stdio.h> #include<stdarg.h> 21 void sum(int nof_args,...) { int i,s; va_list ap; va_start(ap,nof_args); for(i=0,s=0; i<nof_args; i++) { s=s+va_arg(ap,int); va_end(ap); printf("sum of 1..7 is %d\n",sum(7,1,2,3,4,5,6,7)); printf("sum of 1..5 is %d\n",sum(5,5,7,9,11,13));