Βίντεο: Coding Challenge #4: Purple Rain in Processing 2024
Το όνομα του πίνακα είναι ένας δείκτης στον ίδιο τον πίνακα. Η συστοιχία είναι μια ακολουθία μεταβλητών που είναι αποθηκευμένες στη μνήμη. Το όνομα συστοιχίας δείχνει το πρώτο στοιχείο.
Αυτή είναι μια ενδιαφέρουσα ερώτηση σχετικά με τους δείκτες: Μπορείτε να έχετε μια κεφαλίδα λειτουργίας, όπως η ακόλουθη γραμμή, και απλώς χρησιμοποιήστε sizeof για να καθορίσετε πόσα στοιχεία υπάρχουν στον πίνακα; Αν ναι, αυτή η λειτουργία δεν θα χρειαστεί να έχει ο καλών να καθορίσει το μέγεθος του πίνακα.
int AddUp (int Αριθμοί []) {Εξετάστε αυτή την συνάρτηση που βρίσκεται στο παράδειγμα Array01 και στην κύρια () που το καλεί:
void ProcessArray {int Numbers [cout << "εσωτερική συνάρτηση: Το μέγεθος σε bytes είναι" << μέγεθοςof (Numbers) << endl;} int main (int argc, char * argv []) {int MyNumbers [5, 6, 7, 8, 9, 10}. cout << "εξωτερική συνάρτηση: το μέγεθος σε bytes είναι"; cout << μέγεθοςof (MyNumbers) << endl; ProcessArray (MyNumbers); επιστροφή 0?}
Όταν εκτελείτε αυτήν την εφαρμογή, δείτε τι βλέπετε:
Εξωτερική συνάρτηση: Το μέγεθος σε bytes είναι 40 Εσωτερική λειτουργία: Το μέγεθος σε bytes είναι 4
Εκτός της συνάρτησης, ο κώδικας γνωρίζει ότι το μέγεθος του πίνακα είναι 40 bytes. Αλλά γιατί ο κώδικας πιστεύει ότι το μέγεθος είναι 4 αφού είναι μέσα στο πίνακα; Ο λόγος είναι ότι παρόλο που φαίνεται ότι περνάτε από έναν πίνακα, μεταφέρετε πραγματικά έναν δείκτη σε έναν πίνακα. Το μέγεθος του δείκτη είναι μόλις 4 και έτσι εκτυπώνεται η τελική γραμμή.
Οι δηλώσεις των συστοιχιών έχουν μια μικρή ιδιοσυγκρασία. Όταν δηλώνετε έναν πίνακα παρέχοντας έναν ορισμένο αριθμό στοιχείων, όπως
int MyNumbers [5].
ο μεταγλωττιστής γνωρίζει ότι έχετε έναν πίνακα και ο φορέας sizeof σας δίνει το μέγεθος ολόκληρου του πίνακα. Το όνομα του πίνακα, λοιπόν, είναι τόσο ένας δείκτης και ένας πίνακας! Αν όμως δηλώσετε μια κεφαλίδα συνάρτησης χωρίς μέγεθος πίνακα, όπως το
void ProcessArray (int Numbers []) {
ο μεταγλωττιστής αντιμετωπίζει αυτό ως απλό δείκτη και τίποτα περισσότερο. Αυτή η τελευταία γραμμή είναι στην πραγματικότητα ισοδύναμη με την ακόλουθη γραμμή:
void ProcessArray (int * Numbers) {
Έτσι, μέσα στις λειτουργίες που δηλώνει η γραμμή, οι ακόλουθες δύο γραμμές κώδικα είναι : Αριθμοί [3] = 10. * (Αριθμοί + 3) = 10.
Αυτή η ισοδυναμία σημαίνει ότι αν χρησιμοποιείτε εξωτερική δήλωση σε πίνακα, όπως
εξωτερικά int MyNumbers [];
και στη συνέχεια να πάρει το μέγεθος αυτού του πίνακα, ο μεταγλωττιστής θα μπερδευτεί. Ακολουθεί ένα παράδειγμα: Εάν έχετε δύο αρχεία, αριθμούς. cpp και main. cpp, όπου αριθμοί. Το cpp δηλώνει μια σειρά και κύρια. Το cpp το δηλώνει εξωτερικά (όπως φαίνεται στο παράδειγμα Array02), θα λάβετε ένα σφάλμα μεταγλωττιστή αν καλέσετε sizeof:
#include using namespace std; εξωτερικά int MyNumbers []; int main (int argc, char * argv []) {cout << μέγεθοςof (MyNumbers) << endl; Επιστροφή 0;}
Στο κώδικα:: Blocks, ο μεταγλωττιστής gcc μας δίνει αυτό το σφάλμα:
σφάλμα: μη έγκυρη εφαρμογή του 'sizeof' σε ατελές τύπο 'int []'
της συστοιχίας μέσα στις αγκύλες.Απλά βεβαιωθείτε ότι το μέγεθος είναι το ίδιο με το άλλο αρχείο πηγαίου κώδικα! Μπορείτε να παραποιήσετε τον μεταγλωττιστή αλλάζοντας τον αριθμό και
δεν θα λάβετε σφάλμα . Αλλά αυτό είναι κακό στυλ προγραμματισμού και απλά ζητά λάθη. Παρόλο που μια
συστοιχία είναι απλώς μια ακολουθία μεταβλητών όμοια μεταξύ τους στη μνήμη, το όνομα ενός πίνακα είναι πραγματικά ένας δείκτης στο πρώτο στοιχείο του πίνακα. Μπορείτε να χρησιμοποιήσετε το όνομα ως δείκτη. Ωστόσο, το κάνετε αυτό μόνο όταν πραγματικά χρειάζεται να εργαστείτε με ένα δείκτη. Μετά από όλα, πραγματικά δεν έχετε λόγο να γράψετε έναν κώδικα που είναι κρυπτικός, όπως * (Αριθμοί + 3) = 10;. Το αντίστροφο ισχύει επίσης. Δείτε αυτή τη λειτουργία:
void ProcessArray (int * Numbers) {cout << αριθμοί [1] << endl;}
Αυτή η λειτουργία παίρνει έναν δείκτη ως παράμετρο, αλλά έχετε πρόσβαση σε αυτόν ως πίνακα. Και πάλι, μην γράφετε κώδικα σαν αυτό. Αντίθετα, θα πρέπει να καταλάβετε το
γιατί ο κώδικας σαν αυτό λειτουργεί . Έτσι, αποκτάτε βαθύτερη γνώση των συστοιχιών και του τρόπου με τον οποίο ζουν μέσα στον υπολογιστή, και αυτή η γνώση, με τη σειρά της, μπορεί να σας βοηθήσει να γράψετε κώδικα που λειτουργεί σωστά. Παρόλο που το όνομα του πίνακα είναι απλά ένας δείκτης, το όνομα μιας σειράς ακεραίων δεν είναι ακριβώς το ίδιο με ένα δείκτη σε έναν ακέραιο αριθμό. Ελέγξτε αυτές τις γραμμές κώδικα (που βρίσκονται στο παράδειγμα Array03):
int LotsNumbers [50]; int x; LotsNumbers = & x;
Τοποθετήστε τον δείκτη LotsONumbers
σε κάτι διαφορετικό: κάτι που δηλώνεται ως ακέραιος αριθμός. Ο μεταγλωττιστής δεν σας επιτρέπει να το κάνετε αυτό. θα λάβετε ένα σφάλμα. Αυτό δεν θα συνέβαινε αν οι LotsONumbers δηλώνονταν ως int * LotsNumbers. τότε αυτός ο κώδικας θα λειτουργήσει. Αλλά όπως γράφτηκε, ο κώδικας αυτός σας δίνει ένα σφάλμα μεταγλωττιστή. Και το πιστεύετε ή όχι, εδώ είναι το σφάλμα του μεταγλωττιστή που παίρνετε στον Κωδικό:: Μπλοκ: σφάλμα: μη συμβατοί τύποι στην ανάθεση του 'int *' στο 'int [50]'
ορισμένη διάκριση μεταξύ των δύο τύπων, int * και int []. Ωστόσο, το όνομα της συστοιχίας είναι πράγματι δείκτης και μπορείτε να το χρησιμοποιήσετε ως ένα. απλά δεν μπορείτε να κάνετε τα πάντα με αυτό που μπορείτε με ένα κανονικό δείκτη, όπως το επανατοποθετήστε.
Όταν χρησιμοποιείτε συστοιχίες, σημειώστε τις παρακάτω συμβουλές. Αυτά θα σας βοηθήσουν να διατηρήσετε τα αρχεία σας χωρίς προβλήματα:
Διατηρήστε τον κωδικό σας συνεπή. Αν δηλώσετε, για παράδειγμα, έναν δείκτη σε έναν ακέραιο αριθμό, μην το αντιμετωπίζετε ως πίνακα.
-
Διατηρήστε τον κώδικα σαφή και κατανοητό. Εάν περάσετε τους δείκτες, είναι εντάξει να πάρετε τη διεύθυνση του πρώτου στοιχείου, όπως στο & (MyNumbers [0]) αν αυτό κάνει τον κώδικα πιο ξεκάθαρο - αν και είναι ισοδύναμο με μόνο τα MyNumbers.
-
Όταν δηλώνετε έναν πίνακα, προσπαθήστε πάντα να βάζετε έναν αριθμό μέσα στις αγκύλες, εκτός εάν γράφετε μια συνάρτηση που παίρνει έναν πίνακα.
-
Όταν χρησιμοποιείτε την εξωτερική λέξη-κλειδί για να δηλώσετε μια συστοιχία, προχωρήστε και τοποθετήστε το μέγεθος του πίνακα μέσα στις αγκύλες. Αλλά να είστε συνεπείς! Μην χρησιμοποιείτε έναν αριθμό μία φορά και έναν διαφορετικό αριθμό άλλη φορά. Ο ευκολότερος τρόπος να είναι συνεπής είναι να χρησιμοποιήσετε μια σταθερά, όπως const int ArraySize = 10; σε ένα κοινό αρχείο κεφαλίδας και στη συνέχεια χρησιμοποιήστε το στη δήλωση του πίνακα: int MyArray [ArraySize];.