Δηζαγωγή ζηε γιώζζα C Παξνπζίαζε 3 ε : Δίζνδνο/ Έμνδνο - Σπλαξηήζεηο - Pointers κυ θαη Χεθηαθόο Έιεγρνο Σρνιή Μεραλνιόγωλ Μεραληθώλ ΔΜΠ Δξγαζηήξην Απηνκάηνπ Διέγρνπ
Δίζνδνο/ Έμνδνο Βαζηθό output Σπλάξηεζε printf. Φξεζηκνπνηείηαη γηα ηελ πξνβνιή πιεξνθνξηώλ από ην πξόγξακκα πξνο ην ρξήζηε (έμνδνο). Τν πξώην όξηζκα είλαη έλα string, ην νπνίν, εθηόο από θείκελν, πεξηέρεη θαη εηδηθέο αθνινπζίεο ζπκβόιωλ. Αθνινπζνύλ νη κεηαβιεηέο, ηωλ νπνίωλ ε ηηκή πξόθεηηαη λα πξνβιεζεί. printf( This is a simple text.\n ); printf( You have %d attempts left\n, ats); float pi=3.14159; char str[] = PI ; printf( %4s s value is: %8.2f\n, str, pi); %d αθέξαηνο %f float, d ou ble %s string %c έλαο ραξαθηήξαο %4s string, εθηππώλεηαη κε ΤΟΥΛΑΦΙΣΤΟΝ 4 ραξαθηήξεο
Δίζνδνο/ Έμνδνο Βαζηθό input Σπλάξηεζε scanf. Φξεζηκνπνηείηαη γηα ηελ εηζαγωγή πιεξνθνξηώλ από ην ρξήζηε πξνο ην πξόγξακκα (είζνδνο). Τν πξώην όξηζκα είλαη θαη εδώ έλα string, ην νπνίν πεξηιακβάλεη εηδηθέο αθνινπζίεο ζπκβόιωλ. Αθνινπζνύλ pointers ζηηο κεηαβιεηέο, ηωλ νπνίωλ ε ηηκή πξόθεηηαη λα νξηζηεί. int age; char name[20]; printf("enter your name followed by your age: "); scanf("%[ a-za-z]%d", name, &age); printf("hello %s, you are %d years old\n", name, age); %[] ζύλνιν από ζπγθεθξηκέλνπο ραξαθηήξεο
Σπλαξηήζεηο Σπλαξηήζεηο Οη ζπλαξηήζεηο επηηξέπνπλ ηε δεκηνπξγία απηνηειώλ κνλάδωλ θώδηθα, νη νπνίεο κπνξνύλ λα θιεζνύλ από δηάθνξα ζεκεία ηνπ πξνγξάκκαηνο, θαη βνεζνύλ ζηε ζπλεθηηθόηεηα θαη θαζαξόηεηα ηνπ ινγηζκηθνύ (DRY). Οη ζπλαξηήζεηο έρνπλ α) όλνκα, β) ηύπν (αληηζηνηρεί ζηελ επηζηξεθόκελε κεηαβιεηή ή ζε void) θαη γ) νξίζκαηα (κε ηύπν ην θαζέλα). Η εληνιή return ζηακαηά ηελ εθηέιεζε ηεο ζπλάξηεζεο θαη, κε εμαίξεζε ηηο void ζπλαξηήζεηο, επηζηξέθεη ηελ ηηκή πνπ ηελ αθνινπζεί ωο ηηκή ηεο ζπλάξηεζεο. double min_of_two(double a, double b) { if (a<b) return a; return b;
Σπλαξηήζεηο Σπλαξηήζεηο θαη κεηαβιεηέο Οη κεηαβιεηέο ηωλ ζπλαξηήζεωλ έρνπλ ηνπηθή ηζρύ (scope). Μία ζπλάξηεζε, θαηά θαλόλα, δελ αιιάδεη ηελ ηηκή κίαο «εμωηεξηθή» κεηαβιεηήο. void pr(int a) { printf("value: %d\n",a); a = a + 1; printf("new value: %d\n",a); int main() { int i = 3; pr(i); printf("value in main(): %d\n",i);
Μεηαβιεηέο θαη κλήκε Όηαλ δειώλνπκε κία κεηαβιεηή απηόκαηα δεζκεύεηαη θάπνηα πεξηνρή ηεο κλήκεο char c; int a; char tc[5]; int ta[2]; Τν κέγεζνο ηεο κλήκεο πνπ δεζκεύεηαη (δειαδή πόζα bytes) εμαξηάηαη από ηνλ ηύπν ηεο κεηαβιεηήο 101 c 201 202 203 204 a 301 302 303 304 305 tc[0] tc[1] tc[2] tc[3] tc[4] 401 402 403 404 405 406 407 408 ta[0] ta[1]
Pointers Ο pointer a_ptr ζε κία κεηαβιεηή a είλαη έλαο αθέξαηνο (int) αξηζκόο, ν νπνίνο είλαη ίζνο κε ηε δηεύζπλζε ηνπ πξώηνπ byte ηεο κλήκεο πνπ έρεη δεζκεπηεί γηα ηε κεηαβιεηή απηή (βι. πξνεγνύκελε δηαθάλεηα). Ο pointer a_ptr ζε κία κεηαβιεηή ηύπνπ type έρεη πάληα ηύπν type*. char c; 101 c &c = 101 int a; char tc[5]; 201 202 203 204 a 301 302 303 304 305 tc[0] tc[1] tc[2] tc[3] tc[4] &a = 201 &tc= 301 &(tc[3])= 304 int ta[2]; &(ta[1])= 405 401 402 403 404 405 406 407 408 ta[0] ta[1]
Αο ηα πάξνπκε κε ηε ζεηξά: Pointers Έζηω όηη έρνπκε νξίζεη κία κεηαβιεηή int: int a=5; Άξα έρνπλ δεζκεπηεί 4 bytes από ηε δηαζέζηκε κλήκε γηα ηε κεηαβιεηή a: 201 202 203 204 Γηα λα θηηάμνπκε έλαλ pointer ζηε κεηαβιεηή απηή νξίδνπκε κία άιιε κεηαβιεηή ηύπνπ «pointer ζε int», δειαδή int*, θαη ζέηνπκε ωο ηηκή ηεο ηε δηεύζπλζε ηνπ πρώτου byte ηεο κεηαβιεηήο a int* a_ptr = &a; Η ηηκή ηεο κεηαβιεηήο a_ptr ζα είλα ηώξα: 201
Pointers Έζηω όηη ν pointer ptr γλωξίδνπκε όηη «δείρλεη» ζε κία κεηαβιεηή ηύπνπ double, δειαδή πεξηέρεη ηε δηεύζπλζε ηνπ πξώηνπ byte ηεο κεηαβιεηήο. Γηα λα βξνύκε ηελ πξαγκαηηθή ηηκή ηεο κεηαβιεηήο πξέπεη, αληίζηξνθα, λα γίλεη «dereferencing» ηνπ pointer ωο εμήο: printf( %f\n, *ptr); Με άιια ιόγηα, γηα λα πεξάζνπκε από κία κεηαβιεηή ζηνλ αληίζηνηρν pointer ρξεζηκνπνηνύκε ην ραξαθηήξα & (am persand) double* a_ptr = &a; Δλώ γηα λα πεξάζνπκε από ηνλ pointer ζηελ αληίζηνηρε κεηαβιεηή ρξεζηκνπνηνύκε ην ραξαθηήξα * (asterisk) double b = *b_ptr;
Pointers θαη πίλαθεο Δπεηδή ζηε C νη πίλαθεο ηνπνζεηνύληαη πάληα ζε ζπλερή ηκήκαηα ηεο κλήκεο, γλωξίδνληαο ηνλ pointer πνπ δείρλεη ζην 1 ν ζηνηρείν ελόο πίλαθα έρνπκε πξόζβαζε ζε όια ηνπ ηα ζηνηρεία. int tbla[3] = {10, 20, 30; int* ptr_tbla = &(tbla[0]); Ή αιιηώο: int* ptr_tbla = tbla; αθνύ tbla == &(tbla[0]) Θα ηζρύεη πάληα: *(tbla + i) = tbla[i] Καη βέβαηα: tbla + i = &(tbla[i])
Pointers Η ρξήζε pointers καο επηηξέπεη ηελ ηξνπνπνίεζε κεηαβιεηώλ από ζπλαξηήζεηο: void set(int* y, int x){ *y = x; void main(){ int y; int x = 10; set(&y, x); printf( y = %d\n, y); Η set() ιέγεηαη όηη παίξλεη ην y κατ αναφοπά (by reference) ελώ ην x κατά τιμή ή κατ αξία (by valu e).
Γπλακηθή δέζκεπζε κλήκεο Γελ είλαη αλαγθαίν ν pointer λα αληηζηνηρίδεηαη πάληα ζε κηα ππάξρνπζα κεηαβιεηή, κπνξεί λα ρξεζηκνπνηεζεί θαη απηόλνκα. Γηα ην ζθνπό απηό ην πξόγξακκα δεηάεη από ην ζύζηεκα κία θαηάιιειε πεξηνρή κλήκεο. Η δέζκεπζε ηεο κλήκεο γίλεηαη κε ηελ εληνιή malloc, ελώ ζηε ζπλέρεηα ε απνδέζκεπζή ηεο κε ηελ εληνιή free. int *ptr, i; ptr = malloc(5*sizeof(int)); // μνήμη για 5 ακεραίοσς for (i = 0; i < 5; i++){ *(ptr + i) = i; for (i = 0; i < 5; i++){ printf("%d\n",*(ptr + i)); free(ptr);
Γπλακηθή δέζκεπζε κλήκεο Η δπλακηθή δέζκεπζε κλήκεο ζηε γιώζζα C ρξεζηκνπνηείηαη ζρεδόλ απνθιεηζηηθά έλαληη ηεο ζηαηηθήο δέζκεπζεο. Τα βαζηθά πιενλεθηήκαηά ηεο είλαη δύν: Μεηά ηε ρξήζε ηεο ε κλήκε κπνξεί λα απνδεζκεπηεί θαη λα επαλαρξεζηκνπνηεζεί κε άιιν ηξόπν Τν κέγεζνο ηεο κλήκεο πνπ δεζκεύεηαη κπνξεί λα πξνζδηνξηζηεί δπλακηθά, δειαδή κε ηε ρξήζε αθέξαηεο κεηαβιεηήο, θαη δελ είλαη απαξαίηεην λα είλαη γλωζηό ηε ζηηγκή πνπ γξάθεηαη ν θώδηθαο ηνπ πξνγξάκκαηνο. char *str; int n;... scanf( %d, &n);... str = malloc(n*sizeof(char));