ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Μάθημα 5ο Τμήμα Διοίκησης Επιχειρήσεων α εξάμηνο Β. Φερεντίνος
Πίνακες 77 Στατική δομή αποθήκευσης δεδομένων (το μέγεθος ορίζεται εξαρχής και δεν αλλάζει) Αποθήκευση πολλών μεταβλητών ίδιου τύπου, κάτω από ένα κοινό όνομα Η προσπέλαση σε συγκεκριμένη μεταβλητή (στοιχείο του πίνακα) γίνεται με τη χρήση δεικτών/indexes (ενός για μονοδιάστατους πίνακες, δύο για δισδιάστατους, κτλ.) Η αρίθμηση των δεικτών ξεκινάει από το μηδέν
Πίνακες (σχηματικά) 78 1D 0 1 2 3 2D 0 1 2 0 1 2 3 1 2 3D 3 0 array[3] array[0][1] array[2][3] array[1][ ][ ]
Δήλωση και αρχικοποίηση 79 μονοδιάστατου πίνακα τύπος_στοιχείων όνομα[μήκος]; τύπος_στοιχείων όνομα[n] = τιμή_1, τιμή_2,..., τιμή_n; τύπος_στοιχείων όνομα[] = τιμή_1, τιμή_2,..., τιμή_n; int A[10]; // δημιουργία ενός πίνακα Α 10 ακέραιων τιμών int A[10] = 3, 5, 2, 0, -4, 2, 14, 2, -1, 8; ή int A[ ] = 3, 5, 2, 0, -4, 2, 14, 2, -1, 8;
Αναφορά σε στοιχεία μονοδιάστατου 80 πίνακα Η αναφορά σε συγκεκριμένο στοιχείο του πίνακα γίνεται με το δείκτη (index όχι pointer) της θέσης του. Η πρώτη θέση έχει δείκτη 0. A[0] = 3; A[1] = 5; int x = A[0]+A[1];
81 Αρχικοποίηση των τιμών ενός μονοδιάστατου πίνακα στο μηδέν int N = 10; int A[N]; int i; for (i=0; i<n; i++) A[i] = 0; //όχι i=1, όχι i<=n Εναλλακτικά του Ν μπορεί να χρησιμοποιηθεί ο γενικός τύπος sizeof(a)/sizeof(a[0]) Η διαίρεση με το sizeof(a[0]) είναι απαραίτητη καθώς η sizeof επιστρέφει τιμές σε bytes, άρα διαιρούμε με το μέγεθος του ενός στοιχείου του πίνακα σε bytes.
82 Παράδειγμα 1: Εκτύπωση των στοιχείων ενός μονοδιάστατου πίνακα #include <stdio.h> float Α[] = 2.4, -4.5, -3.1, 1.7, 6.5; int i; for (i=0; i<5; i++) // ή for (i=0; i<sizeof(a)/sizeof(a[0]); i++) printf("%.2f\n", Α[i]); // χωρίς \n για εκτύπωση στην ίδια γραμμή
83 Παράδειγμα 2: Εισαγωγή στοιχείων σε ένα μονοδιάστατο πίνακα #include <stdio.h> double Α[5]; int i; for (i=0; i<5; ++i) printf("δώσε τιμή για το Α[%d]: ", i); scanf("%f", &Α[i]);
84 Παράδειγμα 3: Υπολογισμός του μέσου όρου των στοιχείων ενός μονοδιάστατου πίνακα #include <stdio.h> int a[] = 3, 7, -1, 4, 6; float mean = 0; int i; for (i=0; i<5; ++i) mean += a[i]; mean /= 5; printf("μέσος όρος = %.2f\n", mean);
Δήλωση και αρχικοποίηση 85 δισδιάστατου πίνακα τύπος_στοιχείων όνομα[μέγεθος1][μέγεθος2]; τύπος_στοιχείων όνομα[n1][n2] = = τιμή1_1, τιμή1_2,..., τιμή1_n2, τιμή2_1, τιμή2_2,..., τιμή2_n2,, τιμήn1 _1, τιμήn1 _2,..., τιμήn1_n2 float A[5][10]; int Α[5][2] = 3, 5, 2, 0, -4, 2, 14, 2, -1, 8;
86 Αρχικοποίηση των τιμών ενός δισδιάστατου πίνακα στο μηδέν int N = 5, M=10; int A[N][M]; int i,j; for (i=0; i<n; i++) for (j=0; j<m; j++) A[i][j] = 0;
87 Παράδειγμα 1: Εκτύπωση των στοιχείων ενός δισδιάστατου πίνακα #include <stdio.h> int Α[5][3] = 3, 5, 2, 7, 4, 3, 1, 0, 1, 9, 2, 1, 5, 5, 3; int i,j; for (i=0; i<5; i++) for (j=0; j<3; j++) printf("%d ", Α[i][j]); printf("\n"); Θα εκτυπώσει: 3 5 2 7 4 3 1 0 1 9 2 1 5 5 3
88 Παράδειγμα 2: Υπολογισμός του μέγιστου στοιχείου κάθε γραμμής ενός δισδιάστατου πίνακα #include <stdio.h> int Α[5][3] = 3, 5, 2, 7, 4, 3, 1, 0, 1, 9, 2, 1, 5, 5, 3; int i, j, max; for (i=0; i<5; i++) max = Α[i][0]; // αρχικοποίηση στο 1ο στοιχείο της κάθε γραμμής for (j=1; j<3; j++) // από το 2ο στοιχείο της κάθε γραμμής if (Α[i][j] > max) max = Α[i][j]; printf("το μέγιστο της %d-ης γραμμής είναι το: %d\n", i+1, max);
Παράδειγμα 3: Υπολογισμός του αθροίσματος των στοιχείων της κάθε στήλης ενός δισδιάστατου πίνακα 89 #include <stdio.h> int Α[5][3] = 3, 5, 2, 7, 4, 3, 1, 0, 1, 9, 2, 1, 5, 5, 3; int i, j, sum; for (j=0; j<3; j++) sum = 0; // μηδενισμός του αθροίσματος για κάθε στήλη for (i=0; i<5; i++) sum += Α[i][j]; printf("το άθροισμα της %d-ης στήλης είναι: %d\n", j+1, sum);
90 Παράδειγμα 4: Πολλαπλασιασμός δισδιάστατων πινάκων #include <stdio.h> int Α[2][3], Β[3][4], C[2][4], i, j, k; for (i=0; i<2; i++) for (j=0; j<4; j++) C[i][j] = 0; //αρχικοποίηση στοιχείων τελικού πίνακα for (i=0; i<2; i++) for (j=0; j<4; j++) for (k=0; k<3; k++) C[i][j] = C[i][j] + A[i][k] * B[k][j]; //Εκτύπωση των στοιχείων του δισδιάστατου πίνακα C[2][4]
Πίνακες και συναρτήσεις 91 Οι συναρτήσεις, όπως μπορούν να δέχονται μεταβλητές ως ορίσματα, έτσι μπορούν να δέχονται και πίνακες. Η βασική διαφορά αφορά τον τρόπο με τον οποίο μεταβιβάζονται σε αυτές οι παράμετροι εισόδου (εδώ πίνακες) από τη συνάρτηση που τις καλεί: ενώ οι μεταβλητές μπορούν να μεταβιβάζονται είτε με τιμή είτε με αναφορά, οι πίνακες μεταβιβάζονται πάντα με αναφορά
Μεταβίβαση πίνακα και μεγέθους 92 Η συνάρτηση sizeof δεν μπορεί να χρησιμοποιηθεί για τον προσδιορισμό του μεγέθους ενός πίνακα μέσα στη συνάρτηση που τον δέχεται ως όρισμα. Αυτό σημαίνει ότι στη συνάρτηση θα πρέπει επίσης να μεταβιβάζεται και το μέγεθος (διαστάσεις) του πίνακα, αλλιώς δεν υπάρχει άλλος τρόπος για να το γνωρίζει Περισσότερες λεπτομέρειες στο κεφάλαιο για τους δείκτες (pointers)
93 Παράδειγμα συνάρτησης που δέχεται πίνακα Συνάρτηση που επιστρέφει το άθροισμα των στοιχείων του μονοδιάστατου πίνακα που δέχεται ως είσοδο float mesos_oros (int pinakas[], int megethos) float athroisma = 0.0; int i; for (i=0; i< megethos; i++) athroisma += pinakas[i]; return ( athroisma / megethos ); int Α[5] = 5, 3, 2, -4, 6; float mo = mesos_oros(α, 5); printf("μέσος όρος = %.2f\n", mo);
"Επιστροφή" πίνακα από συνάρτηση 94 Στη C οι συναρτήσεις δεν μπορούν να επιστρέφουν πίνακα (όπως συμβαίνει π.χ. στη Java). Η αντίστοιχη λειτουργία επιστροφής πίνακα επιτυγχάνεται με την ιδιότητα της μεταβίβασης με αναφορά των πινάκων. Άρα, οποιαδήποτε μεταβολή των στοιχείων ενός πίνακα μέσα στη συνάρτηση που τον δέχεται ως όρισμα, παραμένει και μετά την επιστροφή της ροής του κώδικα στη συνάρτηση που έκανε την κλήση.
Παραδείγματα συναρτήσεων που μεταβάλουν τα στοιχεία υπάρχοντα πίνακα (1D) 95 void init_array_one (int pinakas[], int len) // αρχικοποίηση στοιχείων πίνακα στη μονάδα int i; for (i=0; i<len; i++) pinakas[i] = 1; void init_array_zero (int pinakas[], int len) // αρχικοποίηση στοιχείων πίνακα στο μηδέν int i; for (i=0; i<len; i++) pinakas[i] = 0; int A[10], B[500]; init_array_one(a, 10); init_array_zero(b, 500); // A = &A[0] // B = &B[0]
Συναρτήσεις που μεταβάλουν τα στοιχεία υπάρχοντα πίνακα (2D) 96 Το πέρασμα δισδιάστατων πινάκων σε συναρτήσεις στη C είναι προβληματικό χωρίς τη χρήση δεικτών (pointers). Στους δισδιάστατους πίνακες, πρέπει η δεύτερη διάσταση να είναι εκ των προτέρων γνωστή στη συνάρτηση που δέχεται τον πίνακα, δηλαδή να ορίζεται επακριβώς στην παράμετρο εισόδου πίνακα της συνάρτησης. Άρα, μια συνάρτηση που δέχεται δισδιάστατο πίνακα, δεν δέχεται οποιονδήποτε δισδιάστατο πίνακα, αλλά μόνο πίνακες με συγκεκριμένο μέγεθος στη δεύτερη διάσταση. void example(int array[ ][5], int len) //2D-array len x 5,
97 Συνάρτηση που δέχεται 2D πίνακα και τον αρχικοποιεί στο μοναδιαίο πίνακα (για μη τετραγωνικούς αρχικοποιεί στο 1 τα στοιχεία της διαγωνίου που ξεκινάει από το 1 ο στοιχείο του) Παράδειγμα συνάρτησης που μεταβάλει τα στοιχεία υπάρχοντα πίνακα (2D) void init_identity (int pinakas[ ][10], int len) int i,j; for (i=0; i<len; i++) int m, n=10; for (j=0; j<10; j++) if (i==j) pinakas[i][j] = 1; else pinakas[i][j] = 0; // # γραμμών και στηλών, printf("δώσε πλήθος γραμμών πίνακα: "); scanf("%d", &m); int pin[m][n]; //Δημιουργία πίνακα m x n init_identity(pin, m); //Αρχικοποίηση πίνακα στον μοναδιαίο