Αρχικοποίηση - τι είναι; Προ-αρχικοποίηση παραμέτρων συνάρτησης

Ένα τυπικό πρόγραμμα SI είναι ένας ορισμός της κύριας συνάρτησης, η οποία, προκειμένου να εκτελεστεί απαραίτητες ενέργειεςκαλεί άλλες λειτουργίες. Τα παραπάνω παραδείγματα προγραμμάτων ήταν ένα ενιαίο αρχείο προέλευσης που περιείχε όλες τις απαραίτητες λειτουργίες για την εκτέλεση του προγράμματος. Η επικοινωνία μεταξύ των συναρτήσεων πραγματοποιήθηκε με βάση δεδομένα περνώντας παραμέτρους και επιστρέφοντας τιμές συναρτήσεων. Αλλά ο μεταγλωττιστής SI σάς επιτρέπει επίσης να σπάσετε ένα πρόγραμμα σε πολλά ξεχωριστά μέρη (αρχεία πηγής), να μεταφράσετε κάθε μέρος ξεχωριστά και στη συνέχεια να συνδυάσετε όλα τα μέρη σε ένα εκτελέσιμο αρχείο χρησιμοποιώντας έναν σύνδεσμο.

Με τέτοια δομή πρωτότυπο πρόγραμμαΟι συναρτήσεις που βρίσκονται σε διαφορετικά αρχεία προέλευσης μπορούν να χρησιμοποιούν καθολικές εξωτερικές μεταβλητές. Όλες οι συναρτήσεις στη γλώσσα C είναι εξ ορισμού εξωτερικές και είναι πάντα προσβάσιμες από οποιοδήποτε αρχείο. Για παράδειγμα, εάν ένα πρόγραμμα αποτελείται από δύο αρχεία προέλευσης, όπως φαίνεται στο Σχ. 2, τότε η κύρια συνάρτηση μπορεί να καλέσει οποιαδήποτε από τις τρεις συναρτήσεις fun1, fun2, fun3 και καθεμία από αυτές τις συναρτήσεις μπορεί να καλέσει οποιαδήποτε άλλη.

Προκειμένου μια καθορισμένη συνάρτηση να εκτελέσει οποιεσδήποτε ενέργειες, πρέπει να χρησιμοποιεί μεταβλητές. Στο SI, όλες οι μεταβλητές πρέπει να δηλωθούν πριν χρησιμοποιηθούν. Οι δηλώσεις αντιστοιχίζουν το όνομα και τα χαρακτηριστικά μιας μεταβλητής, συνάρτησης ή τύπου. Ο καθορισμός μιας μεταβλητής προκαλεί την εκχώρηση μνήμης για την αποθήκευση της τιμής της. Η κλάση της εκχωρημένης μνήμης καθορίζεται από τον προσδιοριστή κλάσης μνήμης και ορίζει τη διάρκεια ζωής και το εύρος μιας μεταβλητής που σχετίζεται με την έννοια ενός μπλοκ προγράμματος.

Στη γλώσσα SI, ένα μπλοκ είναι μια ακολουθία δηλώσεων, ορισμών και δηλώσεων που περικλείονται σε σιδερακια ΔΟΝΤΙΩΝ. Υπάρχουν δύο τύποι μπλοκ - μια σύνθετη πρόταση και ένας ορισμός συνάρτησης, που αποτελείται από μια σύνθετη πρόταση, η οποία είναι το σώμα της συνάρτησης, και μια κεφαλίδα συνάρτησης που προηγείται του σώματος (που περιλαμβάνει το όνομα της συνάρτησης, τους τύπους επιστροφής και τις τυπικές παραμέτρους ). Τα μπλοκ μπορούν να περιλαμβάνουν σύνθετες δηλώσεις, αλλά όχι ορισμούς συναρτήσεων. Το εσωτερικό μπλοκ ονομάζεται ένθετο, και εξωτερική μονάδα- περιεκτικός.

Η διάρκεια ζωής είναι το διάστημα του χρόνου εκτέλεσης του προγράμματος κατά το οποίο υπάρχει ένα αντικείμενο προγράμματος (μεταβλητή ή συνάρτηση). Η διάρκεια ζωής μιας μεταβλητής μπορεί να είναι τοπική ή καθολική. Μια μεταβλητή με καθολική διάρκεια ζωής έχει μνήμη που της έχει εκχωρηθεί και μια συγκεκριμένη τιμή καθ' όλη τη διάρκεια της εκτέλεσης του προγράμματος, ξεκινώντας από τη στιγμή που δηλώνεται η μεταβλητή. Μια μεταβλητή με τοπική διάρκεια ζωής έχει μνήμη που της εκχωρείται και μια καθορισμένη τιμή μόνο κατά την εκτέλεση του μπλοκ στο οποίο ορίζεται ή δηλώνεται η μεταβλητή. Κάθε φορά που εισάγεται ένα μπλοκ, εκχωρείται μια τοπική μεταβλητή νέα μνήμη, το οποίο απελευθερώνεται κατά την έξοδο από το μπλοκ.

Όλες οι συναρτήσεις στο SI έχουν συνολική διάρκεια ζωής και υπάρχουν καθ' όλη τη διάρκεια του χρόνου εκτέλεσης του προγράμματος.

Το πεδίο εφαρμογής είναι ένα μέρος του κειμένου του προγράμματος στο οποίο μπορεί να χρησιμοποιηθεί αυτό το αντικείμενο. Ένα αντικείμενο θεωρείται ορατό σε ένα μπλοκ ή ένα αρχείο προέλευσης εάν το όνομα και ο τύπος του αντικειμένου σε αυτό το μπλοκ ή αρχείο είναι γνωστά. Ένα αντικείμενο μπορεί να είναι ορατό μέσα σε ένα μπλοκ, ένα αρχείο προέλευσης ή σε όλα τα αρχεία προέλευσης που αποτελούν το πρόγραμμα. Εξαρτάται σε ποιο επίπεδο δηλώνεται το αντικείμενο: στο εσωτερικό επίπεδο, δηλ. μέσα σε κάποιο μπλοκ, ή στο εξωτερικό, δηλ. έξω από όλα τα μπλοκ.

Εάν ένα αντικείμενο δηλώνεται μέσα σε ένα μπλοκ, τότε είναι ορατό σε αυτό το μπλοκ και σε όλα τα εσωτερικά μπλοκ. Εάν ένα αντικείμενο έχει δηλωθεί σε εξωτερικό επίπεδο, τότε είναι ορατό από το σημείο της δήλωσης του έως το τέλος του δεδομένου αρχείου προέλευσης.

Ένα αντικείμενο μπορεί να γίνει καθολικά ορατό με κατάλληλες δηλώσεις σε όλα τα αρχεία προέλευσης που απαρτίζουν το πρόγραμμα.

Ο προσδιοριστής κλάσης μνήμης σε μια δήλωση μεταβλητής μπορεί να είναι αυτόματος, καταχωρητής, στατικός ή εξωτερικός. Εάν η κλάση μνήμης δεν έχει καθοριστεί, τότε προσδιορίζεται από προεπιλογή από το περιβάλλον δήλωσης.

Αντικείμενα των τάξεων auto και register έχουν Τοπική ώραΖΩΗ. Οι στατικοί και εξωτερικοί προσδιοριστές ορίζουν αντικείμενα με συνολική διάρκεια ζωής.

Κατά τη δήλωση μιας μεταβλητής σε εσωτερικό επίπεδο, μπορεί να χρησιμοποιηθεί οποιοσδήποτε από τους τέσσερις προσδιοριστές κατηγορίας μνήμης και εάν δεν έχει καθοριστεί, τότε θεωρείται η κατηγορία αυτόματης μνήμης.

Μια μεταβλητή με αυτόματη κλάση μνήμης έχει τοπική διάρκεια ζωής και είναι ορατή μόνο στο μπλοκ στο οποίο έχει δηλωθεί. Η μνήμη για μια τέτοια μεταβλητή εκχωρείται κατά την είσοδο σε ένα μπλοκ και ελευθερώνεται κατά την έξοδο από το μπλοκ. Στο είσοδοςένα άλλο τμήμα της μνήμης μπορεί να εκχωρηθεί στο μπλοκ αυτής της μεταβλητής.

Μια μεταβλητή με αυτόματη κλάση αποθήκευσης δεν προετοιμάζεται αυτόματα. Πρέπει να αρχικοποιείται ρητά όταν δηλώνεται με την ανάθεση μιας αρχικής τιμής. Μια μη αρχικοποιημένη μεταβλητή με αυτόματη κλάση αποθήκευσης θεωρείται απροσδιόριστη.

Ο προσδιοριστής κλάσης μνήμης καταχωρητή δίνει εντολή στον μεταγλωττιστή να εκχωρήσει μνήμη για μια μεταβλητή σε έναν καταχωρητή, αν είναι δυνατόν. Η χρήση της μνήμης καταχωρητή συνήθως οδηγεί σε μειωμένο μεταβλητό χρόνο πρόσβασης. Μια μεταβλητή που δηλώνεται με την κλάση αποθήκευσης καταχωρητή έχει το ίδιο εύρος με μια αυτόματη μεταβλητή. Ο αριθμός των καταχωρητών που μπορούν να χρησιμοποιηθούν για τιμές μεταβλητών περιορίζεται από τις δυνατότητες του υπολογιστή και εάν ο μεταγλωττιστής δεν έχει ελεύθερους καταχωρητές στη διάθεσή του, τότε η μεταβλητή εκχωρείται μνήμη όπως για την κατηγορία auto. Η κλάση μνήμης καταχωρητή μπορεί να καθοριστεί μόνο για μεταβλητές με πληκτρολογήστε intή δείκτες με μέγεθος ίσο με το μέγεθος του int.

Οι μεταβλητές που δηλώνονται εσωτερικά με τον προσδιοριστή κλάσης στατικής αποθήκευσης παρέχουν τη δυνατότητα αποθήκευσης της τιμής της μεταβλητής κατά την έξοδο από ένα μπλοκ και χρήσης της κατά την επανεισαγωγή στο μπλοκ. Μια τέτοια μεταβλητή έχει συνολική διάρκεια ζωής και εύρος εντός του μπλοκ στο οποίο έχει δηλωθεί. Σε αντίθεση με τις αυτόματες μεταβλητές, οι οποίες εκχωρούνται στη στοίβα, οι στατικές μεταβλητές κατανέμονται στο τμήμα δεδομένων και επομένως διατηρούν την αξία τους κατά την έξοδο του μπλοκ.

Παράδειγμα: /* να δηλώσετε τη μεταβλητή i σε εσωτερικό επίπεδο με την κλάση μνήμης στατική. */ /* αρχείο πηγής file1.c */ main() ( ... ) fun1() ( static int i=0; ... ) /* αρχείο πηγής file2.c */ fun2() ( static int i= 0; ... ) fun3() (static int i=0; ...)

Στο παραπάνω παράδειγμα, τρεις διαφορετικές μεταβλητές με την κλάση μνήμης static δηλώνονται και έχουν τα ίδια ονόματα i. Κάθε μία από αυτές τις μεταβλητές έχει συνολική διάρκεια ζωής, αλλά είναι ορατή μόνο στο μπλοκ (συνάρτηση) στο οποίο έχει δηλωθεί. Αυτές οι μεταβλητές μπορούν να χρησιμοποιηθούν για την καταμέτρηση του αριθμού των κλήσεων σε καθεμία από τις τρεις συναρτήσεις.

Οι μεταβλητές της κλάσης στατικής μνήμης μπορούν να αρχικοποιηθούν με μια σταθερή έκφραση. Εάν δεν υπάρχει ρητή προετοιμασία, τότε σε μια τέτοια μεταβλητή εκχωρείται μηδενική τιμή. Κατά την προετοιμασία με μια έκφραση σταθερής διεύθυνσης, μπορείτε να χρησιμοποιήσετε τις διευθύνσεις οποιωνδήποτε εξωτερικών αντικειμένων, εκτός από τις διευθύνσεις αντικειμένων με την κλάση αυτόματης μνήμης, καθώς η διεύθυνση της τελευταίας δεν είναι σταθερά και αλλάζει με κάθε είσοδο στο μπλοκ. Η αρχικοποίηση εκτελείται μία φορά κατά την πρώτη είσοδο στο μπλοκ.

Μια μεταβλητή που δηλώνεται τοπικά με την κλάση αποθήκευσης extern είναι μια αναφορά σε μια μεταβλητή με το ίδιο όνομα που ορίζεται καθολικά σε ένα από τα αρχεία προέλευσης του προγράμματος. Ο σκοπός μιας τέτοιας δήλωσης είναι να κάνει ορατό τον ορισμό της μεταβλητής σε παγκόσμιο επίπεδο μέσα στο μπλοκ.

Παράδειγμα: /* δηλώστε τη μεταβλητή i, η οποία είναι το όνομα ενός εξωτερικού πίνακα μεγάλων ακεραίων, σε τοπικό επίπεδο */ /* αρχείο πηγής file1.c */ main() ( ... ) fun1() ( extern long i; ... ) /* αρχείο προέλευσης file2.c */ long i=(0); fun2() ( ... ) fun3() ( ... )

Η δήλωση i ως εξωτερικό στο παραπάνω παράδειγμα το κάνει ορατό μέσα στο fun1. Ο ορισμός αυτής της μεταβλητής είναι στο file2.c σε παγκόσμιο επίπεδο και θα πρέπει να υπάρχει μόνο μία, ενώ μπορεί να υπάρχουν πολλές δηλώσεις με την κλάση μνήμης extern.

Απαιτείται δήλωση με εξωτερική κλάση μνήμης όταν είναι απαραίτητο να χρησιμοποιηθεί μια μεταβλητή που περιγράφεται στο ρεύμα αρχείο προέλευσης, αλλά χαμηλότερα στο κείμενο του προγράμματος, δηλ. πριν το ολοκληρώσετε παγκόσμιο ορισμό. Το ακόλουθο παράδειγμα επεξηγεί αυτή τη χρήση μιας μεταβλητής που ονομάζεται st.

Παράδειγμα: main() ( extern int st; ... ) static int st=(0); διασκέδαση1() (...)

Η δήλωση μιας μεταβλητής με τον εξωτερικό προσδιοριστή ενημερώνει τον μεταγλωττιστή ότι η μνήμη για τη μεταβλητή δεν χρειάζεται να εκχωρηθεί, καθώς αυτό γίνεται κάπου αλλού στο πρόγραμμα.

Κατά τη δήλωση μεταβλητών σε καθολικό επίπεδο, μπορεί να χρησιμοποιηθεί ο προσδιοριστής κλάσης στατικής ή εξωτερικής μνήμης και μπορείτε επίσης να δηλώσετε μεταβλητές χωρίς να καθορίσετε μια κλάση μνήμης. Οι κατηγορίες μνήμης auto και register δεν επιτρέπονται για καθολική δήλωση.

Η δήλωση μεταβλητών σε παγκόσμιο επίπεδο είναι είτε ορισμός μεταβλητών είτε αναφορές σε ορισμούς που γίνονται σε άλλα σημεία του προγράμματος. Μια καθολική δήλωση μεταβλητής που αρχικοποιεί αυτήν τη μεταβλητή (είτε ρητά είτε σιωπηρά) είναι ένας ορισμός μεταβλητής. Ο ορισμός σε παγκόσμιο επίπεδο μπορεί να δοθεί με τις ακόλουθες μορφές:

1. Η μεταβλητή δηλώνεται με την κλάση μνήμης στατική. Μια τέτοια μεταβλητή μπορεί να αρχικοποιηθεί με μια ρητή σταθερή έκφραση ή με μια προεπιλεγμένη τιμή μηδέν. Δηλαδή, οι δηλώσεις static int i=0 και static int i είναι ισοδύναμες και και στις δύο περιπτώσεις στη μεταβλητή i θα εκχωρηθεί η τιμή 0.

2. Η μεταβλητή δηλώνεται χωρίς να καθορίζεται κατηγορία μνήμης, αλλά με ρητή προετοιμασία. Σε αυτήν τη μεταβλητή εκχωρείται η κλάση στατικής μνήμης από προεπιλογή. Δηλαδή, οι δηλώσεις int i=1 και static int i=1 θα είναι ισοδύναμες.

Μια μεταβλητή που δηλώνεται καθολικά είναι ορατή στο υπόλοιπο του αρχείου προέλευσης στο οποίο έχει οριστεί. Πάνω από την περιγραφή της και σε άλλα αρχεία προέλευσης, αυτή η μεταβλητή είναι αόρατη (εκτός εάν έχει δηλωθεί με την κλάση extern).

Μια καθολική μεταβλητή μπορεί να οριστεί μόνο μία φορά εντός του πεδίου εφαρμογής της. Σε ένα άλλο αρχείο προέλευσης, μια άλλη καθολική μεταβλητή με το ίδιο όνομα και με την κλάση μνήμης στατική μπορεί να δηλωθεί, δεν θα υπάρχει διένεξη, αφού καθεμία από αυτές τις μεταβλητές θα είναι ορατή μόνο στο αρχείο προέλευσης.

Ο προσδιοριστής κλάσης εξωτερικής μνήμης για καθολικές μεταβλητές χρησιμοποιείται, όπως για μια τοπική δήλωση, ως αναφορά σε μια μεταβλητή που δηλώνεται σε άλλο σημείο του προγράμματος, π.χ. για να επεκτείνετε το εύρος μιας μεταβλητής. Με μια τέτοια δήλωση, το εύρος της μεταβλητής επεκτείνεται στο τέλος του αρχείου προέλευσης στο οποίο γίνεται η δήλωση.

Οι δηλώσεις με την εξωτερική κλάση αποθήκευσης δεν επιτρέπουν την προετοιμασία, επειδή αυτές οι δηλώσεις αναφέρονται σε προϋπάρχουσες και προκαθορισμένες μεταβλητές.

1.6.2. Δηλώσεις Λειτουργίας

Οι συναρτήσεις ορίζονται πάντα συνολικά. Μπορούν να δηλωθούν με μια κλάση στατικής ή εξωτερικής μνήμης. Οι δηλώσεις λειτουργιών σε τοπικό και παγκόσμιο επίπεδο έχουν την ίδια σημασία.

Οι κανόνες για τον προσδιορισμό του εύρους των συναρτήσεων διαφέρουν από τους κανόνες ορατότητας για τις μεταβλητές και είναι οι εξής.

1. Μια συνάρτηση που έχει δηλωθεί ως στατική είναι ορατή μέσα στο αρχείο στο οποίο έχει οριστεί. Κάθε συνάρτηση μπορεί να καλέσει μια άλλη συνάρτηση με στατική κλάση αποθήκευσης από το αρχείο προέλευσης, αλλά δεν μπορεί να καλέσει μια συνάρτηση που ορίζεται με στατική κλάση σε άλλο αρχείο προέλευσης. Διάφορες λειτουργίεςμε μια κλάση στατικής μνήμης που έχει το ίδιο όνομα μπορεί να οριστεί σε διαφορετικά αρχεία προέλευσης χωρίς να προκαλείται διένεξη.

2. Μια συνάρτηση που δηλώνεται με την κλάση εξωτερικής μνήμης είναι ορατή σε όλα τα αρχεία προέλευσης του προγράμματος. Οποιαδήποτε συνάρτηση μπορεί να καλέσει συναρτήσεις με την κλάση εξωτερικής μνήμης.

3. Εάν δεν υπάρχει προσδιοριστής κλάσης μνήμης στη δήλωση συνάρτησης, τότε η κλάση extern θεωρείται από προεπιλογή.

Ο μεταγλωττιστής τοποθετεί όλα τα αντικείμενα με την κλάση μνήμης extern σε έναν ειδικό πίνακα στο αρχείο αντικειμένων εξωτερικοί σύνδεσμοι, το οποίο χρησιμοποιείται από το πρόγραμμα επεξεργασίας συνδέσμων για την επίλυση εξωτερικών συνδέσμων. Ορισμένοι εξωτερικοί σύνδεσμοι δημιουργούνται από τον μεταγλωττιστή κατά την κλήση συναρτήσεων βιβλιοθήκης SI, επομένως για την επίλυση αυτών των συνδέσμων, οι αντίστοιχες βιβλιοθήκες λειτουργιών πρέπει να είναι διαθέσιμες στον επεξεργαστή συνδέσμων.

1.6.3. Διάρκεια ζωής και εύρος αντικειμένων λογισμικού

Η διάρκεια ζωής μιας μεταβλητής (συνολικής ή τοπικής) καθορίζεται σύμφωνα με τους ακόλουθους κανόνες.

1. Μια μεταβλητή που δηλώνεται καθολικά (δηλαδή εκτός όλων των μπλοκ) υπάρχει σε όλη την εκτέλεση του προγράμματος.

2. Οι τοπικές μεταβλητές (δηλαδή που δηλώνονται μέσα σε ένα μπλοκ) με καταχωρητή ή κατηγορία αυτόματης μνήμης έχουν διάρκεια ζωής μόνο για την περίοδο εκτέλεσης του μπλοκ στο οποίο δηλώνονται. Εάν μια τοπική μεταβλητή δηλωθεί με μια κλάση μνήμης στατικής ή εξωτερικής, τότε έχει διάρκεια ζωής για τη διάρκεια ολόκληρου του προγράμματος.

Η ορατότητα των μεταβλητών και των συναρτήσεων σε ένα πρόγραμμα καθορίζεται από τους ακόλουθους κανόνες.

1. Μια μεταβλητή που δηλώνεται ή ορίζεται καθολικά είναι ορατή από το σημείο της δήλωσης ή του ορισμού έως το τέλος του αρχείου προέλευσης. Μπορείτε να κάνετε μια μεταβλητή ορατή σε άλλα αρχεία προέλευσης δηλώνοντάς τη με την κλάση εξωτερικής μνήμης σε αυτά τα αρχεία.

2. Μια μεταβλητή, που δηλώνεται ή ορίζεται τοπικά, είναι ορατή από το σημείο της δήλωσης ή του ορισμού μέχρι το τέλος τρέχον μπλοκ. Μια τέτοια μεταβλητή ονομάζεται τοπική.

3. Οι μεταβλητές από τα μπλοκ που περικλείουν, συμπεριλαμβανομένων των μεταβλητών που δηλώνονται σε παγκόσμιο επίπεδο, είναι ορατές στα εσωτερικά μπλοκ. Αυτή η ορατότητα ονομάζεται ένθετη. Εάν μια μεταβλητή που δηλώνεται μέσα σε ένα μπλοκ έχει το ίδιο όνομα με μια μεταβλητή που δηλώνεται στο μπλοκ που περικλείει, τότε αυτές είναι διαφορετικές μεταβλητές και η μεταβλητή από το μπλοκ που περικλείει είναι εσωτερική μονάδαθα είναι αόρατο.

4. Οι συναρτήσεις με στατική κατηγορία μνήμης είναι ορατές μόνο στο αρχείο προέλευσης στο οποίο έχουν οριστεί. Όλες οι άλλες λειτουργίες είναι ορατές σε όλο το πρόγραμμα.

Οι ετικέτες στις συναρτήσεις είναι ορατές σε ολόκληρη τη λειτουργία.

Τα επίσημα ονόματα παραμέτρων που δηλώνονται στη λίστα παραμέτρων ενός πρωτοτύπου συνάρτησης είναι ορατά μόνο από το σημείο της δήλωσης παραμέτρων μέχρι το τέλος της δήλωσης συνάρτησης.

1.6.4. Εκκίνηση καθολικών και τοπικών μεταβλητών

Κατά την προετοιμασία, πρέπει να τηρείτε τους ακόλουθους κανόνες:

1. Οι δηλώσεις που περιέχουν τον προσδιοριστή κλάσης εξωτερικής μνήμης δεν μπορούν να περιέχουν εκκινητές.

2. Οι καθολικές μεταβλητές αρχικοποιούνται πάντα και, εκτός εάν αυτό γίνει ρητά, αρχικοποιούνται στο μηδέν.

3. Μια μεταβλητή με στατική κλάση μνήμης μπορεί να αρχικοποιηθεί με μια σταθερή έκφραση. Η αρχικοποίηση για αυτά πραγματοποιείται μία φορά πριν από την έναρξη του προγράμματος. Εάν δεν υπάρχει ρητή προετοιμασία, τότε η μεταβλητή αρχικοποιείται στο μηδέν.

4. Η εκκίνηση των μεταβλητών με την κατηγορία μνήμης auto ή καταχωρητή πραγματοποιείται κάθε φορά που εισάγετε το μπλοκ στο οποίο δηλώνονται. Εάν οι μεταβλητές δεν αρχικοποιηθούν στη δήλωση, τότε η αρχική τους τιμή είναι απροσδιόριστη.

5. Οι αρχικές τιμές για καθολικές μεταβλητές και για μεταβλητές με κλάση στατικής μνήμης πρέπει να είναι σταθερές εκφράσεις. Οι διευθύνσεις τέτοιων μεταβλητών είναι σταθερές και αυτές οι σταθερές μπορούν να χρησιμοποιηθούν για την προετοιμασία των καθολικά δηλωμένων δεικτών. Οι διευθύνσεις μεταβλητών με αυτόματη κλάση μνήμης ή καταχωρητή δεν είναι σταθερές και δεν μπορούν να χρησιμοποιηθούν σε εκκινητές.

Παράδειγμα: int global_var; int func(void) ( int local_var; /* default auto */ static int *local_ptr=&local_var; /* αυτό είναι λάθος */ static int *global_ptr=&global_var; /* αυτό είναι σωστό */ register int *reg_ptr=&local_var; /* και έτσι σωστά */ )

Στο παραπάνω παράδειγμα, η καθολική μεταβλητή global_var έχει μια καθολική διάρκεια ζωής και μια μόνιμη διεύθυνση στη μνήμη και αυτή η διεύθυνση μπορεί να χρησιμοποιηθεί για την προετοιμασία του στατικού δείκτη global_ptr. Η τοπική μεταβλητή local_var, η οποία έχει μια κατηγορία μνήμης auto, εκχωρείται στη μνήμη μόνο όταν εκτελείται η συνάρτηση func, η διεύθυνση αυτής της μεταβλητής δεν είναι σταθερή και δεν μπορεί να χρησιμοποιηθεί για την προετοιμασία της στατικής μεταβλητής local_ptr. Για να αρχικοποιήσετε τη μεταβλητή τοπικού μητρώου reg_ptr, μπορείτε να χρησιμοποιήσετε μη σταθερές εκφράσεις και, ειδικότερα, τη διεύθυνση της μεταβλητής local_ptr.

[

Αρχικοποίηση

Σε μια μεταβλητή σε μια δήλωση μπορεί να εκχωρηθεί μια αρχική τιμή μέσω ενός αρχικοποιητή. Πριν από την καταχώριση του αρχικοποιητή στη δήλωση υπάρχει σύμβολο ίσου

= <αρχικοποιητή>

Οι μεταβλητές οποιουδήποτε τύπου μπορούν να αρχικοποιηθούν. Οι συναρτήσεις δεν αρχικοποιούνται. Δηλώσεις που χρησιμοποιούν την προδιαγραφή κλάσης μνήμης εξωτερικό, δεν μπορεί να περιέχει αρχικοποιητή.

Μια μεταβλητή που δηλώνεται εξωτερικά χωρίς προδιαγραφή κλάσης αποθήκευσης μπορεί να αρχικοποιηθεί το πολύ μία φορά σε οποιοδήποτε από τα αρχεία προέλευσης που αποτελούν το πρόγραμμα. Εάν δεν έχει αρχικοποιηθεί ρητά σε κανένα από τα αρχεία προέλευσης, τότε ο σύνδεσμος το αρχικοποιεί στο μηδέν.

Μεταβλητή κατηγορίας μνήμης στατικός, που δηλώνεται τόσο στο εξωτερικό όσο και στο εσωτερικό επίπεδο, μπορεί να αρχικοποιηθεί με μια σταθερή έκφραση το πολύ μία φορά στο αρχείο προέλευσης. Εάν δεν είναι ρητά αρχικοποιημένο, ο μεταγλωττιστής C το αρχικοποιεί στο μηδέν.

Εκκίνηση μεταβλητών κλάσης μνήμης αυτοΚαι κανω ΕΓΓΡΑΦΗεκτελείται κάθε φορά που εισάγετε ένα μπλοκ (εκτός από την εισαγωγή ενός μπλοκ χρησιμοποιώντας τον τελεστή παω σε) στο οποίο δηλώνονται. Εάν παραληφθεί ένας αρχικοποιητής σε μια δήλωση μεταβλητής κατηγορίας μνήμης αυτοή κανω ΕΓΓΡΑΦΗ, τότε η αρχική του τιμή είναι απροσδιόριστη. Αρχικοποίηση μεταβλητών μιγαδικών τύπων (πίνακας, δομή, ένωση) που έχουν κλάση μνήμης αυτο, απαγορεύεται στο SP MSC, αλλά επιτρέπεται στο SP TS ακόμα και για μεταβλητές που δηλώνονται με τροποποιητή συνθ. Μεταβλητές σύνθετου τύπουέχοντας ένα μάθημα μνήμης στατικός, μπορεί να αρχικοποιηθεί εσωτερικά.

Αρχικοποίηση τιμών για μεταβλητές εξωτερικού επιπέδου και μεταβλητές κλάσης μνήμης στατικόςτο εσωτερικό επίπεδο πρέπει να είναι μια σταθερή έκφραση (βλ. ενότητα 4.2.9). Μεταβλητές κατηγορίας μνήμης αυτοΚαι κανω ΕΓΓΡΑΦΗμπορεί να αρχικοποιηθεί όχι μόνο με σταθερές εκφράσεις, αλλά και από εκφράσεις που περιέχουν μεταβλητές και κλήσεις συναρτήσεων.

Από το βιβλίο της C++ από τον Hill Murray

5.2.4 Αρχικοποίηση Η χρήση συναρτήσεων όπως η set_date() για να διασφαλιστεί ότι η προετοιμασία ενός αντικειμένου κλάσης είναι άκομψη και επιρρεπής σε σφάλματα. Εφόσον πουθενά δεν αναφέρεται ότι το αντικείμενο πρέπει να αρχικοποιηθεί, ο προγραμματιστής μπορεί να ξεχάσει να το κάνει, ή (αυτό

Από βιβλίο Οδηγός βοήθειαςσε C++ συγγραφέας Stroustrap Bjarne

6.6 Εκχώρηση και αρχικοποίηση Θεωρήστε μια πολύ απλή κλάση συμβολοσειράς string:struct string (* char* p, int size; // μέγεθος του διανύσματος που δείχνει το pstring(int sz) (* p = νέος χαρακτήρας; *) ~string() (* διαγραφή p; *) * Μια συμβολοσειρά είναι μια δομή δεδομένων που αποτελείται από ένα διάνυσμα χαρακτήρων και το μήκος αυτού του διανύσματος. Διάνυσμα

Από το βιβλίο Idioms and Styles C++ του Makhmutov Albert

Από το βιβλίο System Programming in περιβάλλον Windows από τον Χαρτ Τζόνσον Μ

R.12.6 Initialization Ένα αντικείμενο μιας κλάσης χωρίς κατασκευαστές, χωρίς ιδιωτικά ή προστατευμένα μέλη, όχι εικονικές λειτουργίεςκαι χωρίς βασικές κλάσεις μπορούν να αρχικοποιηθούν χρησιμοποιώντας μια λίστα αρχικοποιητών (§R.8.4.1). Ένα αντικείμενο κλάσης με κατασκευαστή πρέπει να αρχικοποιηθεί ή να έχει

Από το βιβλίο Υποδομές δημόσια κλειδιά συγγραφέας Polyanskaya Olga Yurievna

Από το βιβλίο The C Programming Language for προσωπικός υπολογιστής συγγραφέας Bochkov S. O.

Βήμα 12 - Εκκίνηση σε δύο βήματα. Όταν δημιουργούμε μια παρουσία χωρίς στοίβα, γράφουμε τον ακόλουθο κώδικα: CClass* cc = new CClass(), Ας προσπαθήσουμε να το καταλάβουμε. new είναι ένας παγκόσμιος τελεστής με τον ορισμό: void* operator new (size_t bytes) Λαμβάνει από τον μεταγλωττιστή τον αριθμό των byte που απαιτούνται για την αποθήκευση του αντικειμένου.

Από το βιβλίο QNX/UNIX [Anatomy of Concurrency] συγγραφέας Τσιλουρίκ Όλεγκ Ιβάνοβιτς

Υποστηρίζεται η προετοιμασία του Winsock Winsock API DLL(WS2_32.DLL), για να αποκτήσετε πρόσβαση στην οποία πρέπει να συνδέσετε τη βιβλιοθήκη WS_232.LIB στο πρόγραμμα. Αυτό το DLL θα πρέπει να προετοιμαστεί χρησιμοποιώντας τη μη τυπική, ειδική για το Winsock συνάρτηση WSAStartup, η οποία θα πρέπει να είναι η πρώτη από

Από το βιβλίο The C Language - A Guide for Beginners από Prata Steven

Αρχικοποίηση Κατά τη φάση αρχικοποίησης, ανάλογα με τις παραμέτρους εισόδου, ορίζονται οι μεταβλητές κατάστασης που είναι απαραίτητες για την επικύρωση της διαδρομής πιστοποίησης. ΣΕ μεταβλητές κατάστασηςΔιατηρούνται διάφοροι περιορισμοί που λαμβάνονται υπόψη κατά την επικύρωση της διαδρομής. Μεταβλητές

Από το βιβλίο Προγραμματισμός για Linux. Επαγγελματική προσέγγιση του Μίτσελ Μαρκ

Αρχικοποίηση Σε μια μεταβλητή σε μια δήλωση μπορεί να εκχωρηθεί μια αρχική τιμή μέσω ενός αρχικοποιητή. Η καταχώρηση του αρχικοποιητή στη δήλωση προηγείται από ένα σύμβολο ίσου =<инициализатор>Οι μεταβλητές οποιουδήποτε τύπου μπορούν να αρχικοποιηθούν. Οι συναρτήσεις δεν αρχικοποιούνται.

Από το βιβλίο C++ για αρχάριους του Lippman Stanley

Αρχικοποίηση παραμέτρων int pthread_mutexattr_init(const pthread_mutexattr_t* attr Η συνάρτηση προετοιμάζει τη δομή του χαρακτηριστικού mutex που επισημαίνεται από την παράμετρο attr). Ο τύπος δεδομένων pthread_mutexattr_t ορίζεται στο αρχείο (προέρχεται από τον τύπο sync_attr_t, ο οποίος με τη σειρά του ορίζεται στο αρχείο

Από το βιβλίο του συγγραφέα

Αρχικοποίηση Mutex int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr Η δομή δεδομένων pthread_mutex_t ορίζεται στο αρχείο). (προέρχεται από τον τύπο sync_t, ο οποίος με τη σειρά του ορίζεται στο αρχείο ) και έχει την ακόλουθη μορφή: struct _sync_t ( /* Μετρητής για αναδρομικό

Από το βιβλίο του συγγραφέα

Αρχικοποίηση δομής Είδαμε πώς αρχικοποιούνται οι μεταβλητές και οι πίνακες: int count = 0;static int fibo=(0, 1, 1, 2, 3, 5, 8); Ναι, εάν η μεταβλητή δομής είναι εξωτερική ή στατική. Εδώ θα πρέπει να ληφθεί υπόψη ότι

Από το βιβλίο του συγγραφέα

5.2.2. Αρχικοποίηση σηματοφόρου Η εκχώρηση και η προετοιμασία ενός σηματοφόρου είναι δύο διαφορετικές λειτουργίες. Για να αρχικοποιήσετε έναν σηματοφόρο, καλέστε τη συνάρτηση semctl(), περνώντας το δεύτερο όρισμα ίσο με μηδέν, και το τρίτο όρισμα είναι ίσο με τη σταθερά SETALL. Το τέταρτο όρισμα πρέπει να είναι τύπου union semun, field

Από το βιβλίο του συγγραφέα

7.9.2. Αρχικοποίηση και αντιστοίχιση Υπενθυμίζεται ότι ένα όνομα πίνακα χωρίς τον καθορισμό ενός ευρετηρίου στοιχείου ερμηνεύεται ως η διεύθυνση του πρώτου στοιχείου. Ομοίως, ένα όνομα συνάρτησης χωρίς να ακολουθεί παρενθέσεις ερμηνεύεται ως δείκτης συνάρτησης. Για παράδειγμα, κατά τον υπολογισμό

Από το βιβλίο του συγγραφέα

14.1. Αρχικοποίηση μιας κλάσης Λάβετε υπόψη τον ακόλουθο ορισμό κλάσης: class Data (public:int ival;char *ptr;);Για να χρησιμοποιήσετε με ασφάλεια ένα αντικείμενο κλάσης, πρέπει να αρχικοποιήσετε σωστά τα μέλη του. Ωστόσο, το νόημα αυτής της ενέργειας είναι για διαφορετικές τάξειςδιαφορετικός. Για παράδειγμα, can ival

Από το βιβλίο του συγγραφέα

14.6. Memberwise Initialization A Η προετοιμασία ενός αντικειμένου μιας κλάσης από ένα άλλο αντικείμενο της ίδιας κλάσης, όπως: Account oldAcct("Anna Livia Plurabelle");Account newAcct(oldAcct) ονομάζεται προεπιλεγμένη προετοιμασία μέλους. Από προεπιλογή - επειδή γίνεται αυτόματα, ανεξάρτητα

Σελίδα 74 από 82

Προ-αρχικοποίηση παραμέτρων συνάρτησης

Η λίστα των παραμέτρων στον ορισμό και το πρωτότυπο μιας συνάρτησης, εκτός από την αντιστοίχιση των τύπων των παραμέτρων, έχει έναν ακόμη σκοπό.

Μια δήλωση παραμέτρου μπορεί να περιέχει έναν αρχικοποιητή, δηλαδή μια έκφραση που πρέπει να παρέχει μια αρχική τιμή για την παράμετρο. Ο αρχικοποιητής παραμέτρου δεν είναι μια σταθερή έκφραση. Η αρχική εκκίνηση των παραμέτρων δεν πραγματοποιείται στο στάδιο της μεταγλώττισης (όπως, για παράδειγμα, η εκχώρηση μνήμης για πίνακες), αλλά απευθείας κατά την εκτέλεση του προγράμματος.

Οι ακόλουθες γραμμές δείχνουν ένα παράδειγμα δήλωσης συνάρτησης με αρχικοποίηση παραμέτρων. Η συνάρτηση XX χρησιμοποιείται για την προετοιμασία της παραμέτρου ww.

Int BigVal;
int XX(int);
int ZZ(int tt, int ww = XX(BigVal));

Η δεύτερη παράμετρος μπορεί να αρχικοποιηθεί με αυτόν τον τρόπο, χωρίς να προσδιορίζεται καθόλου το όνομά της. Η σύνταξη της δήλωσης σας επιτρέπει να το κάνετε αυτό!

Int ZZ(int tt, int = XX(BigVal));

Η μόνη προϋπόθεση για μια τέτοια αρχικοποίηση είναι ο τύπος της παραμέτρου να ταιριάζει με τον τύπο της παράστασης της οποίας η τιμή χρησιμοποιείται κατά την αρχική προετοιμασία.

Τα πρωτότυπα λειτουργιών μπορούν να εντοπιστούν σε διαφορετικά πεδία. Μπορεί ακόμη και να τοποθετηθεί στο σώμα της καθορισμένης λειτουργίας. Κάθε δήλωση συνάρτησης μπορεί να περιέχει τις δικές της επιλογές για δήλωση και αρχικοποίηση παραμέτρων. Αλλά οι πολλαπλές δηλώσεις της ίδιας συνάρτησης εντός του ίδιου πεδίου δεν επιτρέπουν την επαναρχικοποίηση των παραμέτρων. Πρέπει να υπάρχει ένα λογικό όριο σε όλα.

Επιπλέον, η C++ έχει έναν άλλο περιορισμό που σχετίζεται με τη σειρά με την οποία αρχικοποιούνται οι παράμετροι εντός του πεδίου εφαρμογής. Η αρχικοποίηση πραγματοποιείται χωρίς αποτυχία από την τελευταία (δεξιά) παράμετρο στη λίστα δηλώσεων παραμέτρων. Η αρχικοποίηση των παραμέτρων δεν επιτρέπει κενά: οι αρχικοποιημένες παράμετροι δεν μπορούν να εναλλάσσονται με μη αρχικοποιημένες παραμέτρους.

Int MyF1 (int par1, int par2, int par3, int par4 = 10);
int MyF1 (int par1, int par2 = 20, int par3 = 20, int par4);
int MyF1(int par1 = 100, int, int, int);

Η λίστα των παραμέτρων στον ορισμό της συνάρτησης δημιουργείται σύμφωνα με παρόμοιους κανόνες. Οι αρχικοποιητές επιτρέπονται επίσης στη λίστα παραμέτρων του ορισμού μιας συνάρτησης, σε ορισμένες περιπτώσεις, τα ονόματα παραμέτρων μπορούν επίσης να παραληφθούν. Φυσικά, η συμπερίληψη μιας παραμέτρου χωρίς όνομα στην κεφαλίδα ενός ορισμού συνάρτησης καθιστά δύσκολη τη χρήση αυτής της παραμέτρου στην καθορισμένη συνάρτηση. Δεν είναι δυνατή η πρόσβαση σε μια παράμετρο χωρίς όνομα.

Ωστόσο, η μη χρήση της παραμέτρου μπορεί να δικαιολογηθεί. Τέτοιες παράμετροι, ή μάλλον οι προσδιοριστές τους, καθιστούν δυνατή τη μείωση του κόστους τροποποίησης πολύπλοκων προγραμμάτων πολλαπλών μονάδων όταν, ως αποτέλεσμα της αλλαγής μιας συνάρτησης, αλλάζει ο αριθμός των παραμέτρων αυτής της συνάρτησης. Οι περιττές επιλογές μπορούν να απενεργοποιηθούν χωρίς αλλαγή πολλαπλών κλήσεων σε αυτήν τη λειτουργία. Σε αυτήν την περίπτωση, είναι λογικό να αποθηκεύσετε τον συνολικό αριθμό των παραμέτρων της συνάρτησης και το όνομα περιττή παράμετροςαφαιρέστε από τη λίστα παραμέτρων.

Η λίστα των παραμέτρων στον ορισμό και το πρωτότυπο μιας συνάρτησης, εκτός από την αντιστοίχιση των τύπων των παραμέτρων, έχει έναν ακόμη σκοπό.

Μια δήλωση παραμέτρου μπορεί να περιέχει έναν αρχικοποιητή, δηλαδή μια έκφραση που πρέπει να παρέχει μια αρχική τιμή για την παράμετρο. Ο αρχικοποιητής παραμέτρου δεν είναι μια σταθερή έκφραση. Η αρχική εκκίνηση των παραμέτρων δεν πραγματοποιείται στο στάδιο της μεταγλώττισης (όπως, για παράδειγμα, η εκχώρηση μνήμης για πίνακες), αλλά απευθείας κατά την εκτέλεση του προγράμματος.

Οι ακόλουθες γραμμές δείχνουν ένα παράδειγμα δήλωσης συνάρτησης με αρχικοποίηση παραμέτρων. Η συνάρτηση XX χρησιμοποιείται για την προετοιμασία της παραμέτρου ww.

int ZZ(int tt, int ww = XX(BigVal));

Η δεύτερη παράμετρος μπορεί να αρχικοποιηθεί με αυτόν τον τρόπο, χωρίς να προσδιορίζεται καθόλου το όνομά της. Η σύνταξη της δήλωσης σας επιτρέπει να το κάνετε αυτό!

int ZZ(int tt, int = XX(BigVal));

Η μόνη προϋπόθεση για μια τέτοια αρχικοποίηση είναι ο τύπος της παραμέτρου να ταιριάζει με τον τύπο της παράστασης της οποίας η τιμή χρησιμοποιείται κατά την αρχική προετοιμασία.

Τα πρωτότυπα λειτουργιών μπορούν να εντοπιστούν σε διαφορετικά πεδία. Μπορεί ακόμη και να τοποθετηθεί στο σώμα της καθορισμένης λειτουργίας. Κάθε δήλωση συνάρτησης μπορεί να περιέχει τις δικές της επιλογές για δήλωση και αρχικοποίηση παραμέτρων. Αλλά οι πολλαπλές δηλώσεις της ίδιας συνάρτησης εντός του ίδιου πεδίου δεν επιτρέπουν την επαναρχικοποίηση των παραμέτρων. Πρέπει να υπάρχει ένα λογικό όριο σε όλα.

Επιπλέον, η C++ έχει έναν άλλο περιορισμό που σχετίζεται με τη σειρά με την οποία αρχικοποιούνται οι παράμετροι εντός του πεδίου εφαρμογής. Η αρχικοποίηση πραγματοποιείται χωρίς αποτυχία από την τελευταία (δεξιά) παράμετρο στη λίστα δηλώσεων παραμέτρων. Η αρχικοποίηση των παραμέτρων δεν επιτρέπει κενά: οι αρχικοποιημένες παράμετροι δεν μπορούν να εναλλάσσονται με μη αρχικοποιημένες παραμέτρους.

int MyF1 (int par1, int par2, int par3, int par4 = 10);

………………………………….

int MyF1 (int par1, int par2 = 20, int par3 = 20, int par4);

………………………………….

int MyF1(int par1 = 100, int, int, int);

#περιλαμβάνω

int f(int, int=4);

int main(int argc, char* argv)

printf("%d\n", f(2)); //8

printf("%d\n", f(2,3)); //6

int f(int a, int b)

Συναρτήσεις με μεταβλητό αριθμό παραμέτρων

Όταν καλείτε μια συνάρτηση με μεταβλητό αριθμό παραμέτρων, προσδιορίζεται οποιοσδήποτε απαιτούμενος αριθμός ορισμάτων στην κλήση αυτής της συνάρτησης. Στη δήλωση και τον ορισμό μιας τέτοιας λειτουργίας μεταβλητός αριθμόςτα ορίσματα καθορίζονται με μια έλλειψη στο τέλος της λίστας των τυπικών παραμέτρων ή της λίστας των τύπων ορισμάτων.

Όλα τα ορίσματα που δίνονται σε μια κλήση συνάρτησης προωθούνται στη στοίβα. Ο αριθμός των επίσημων παραμέτρων που δηλώνονται για μια συνάρτηση καθορίζεται από τον αριθμό των ορισμάτων που λαμβάνονται από τη στοίβα και εκχωρούνται στις επίσημες παραμέτρους. Ο προγραμματιστής είναι υπεύθυνος για τη σωστή επιλογή πρόσθετων ορισμάτων από τη στοίβα και τον προσδιορισμό του αριθμού των ορισμάτων που υπάρχουν στη στοίβα.

Παραδείγματα συναρτήσεων με μεταβλητό αριθμό παραμέτρων είναι συναρτήσεις από τη βιβλιοθήκη συναρτήσεων γλώσσας SI που εκτελούν λειτουργίες εισαγωγής/εξόδου πληροφοριών (printf, scanf, κ.λπ.). Η συνάρτηση printf() στη βιβλιοθήκη δηλώνεται ως εξής:

int printf(const char* ...);

Αυτό διασφαλίζει ότι οποιαδήποτε κλήση στην printf() θα περάσει το πρώτο όρισμα τύπου const char*. Τα περιεχόμενα αυτής της συμβολοσειράς, που ονομάζεται συμβολοσειρά μορφής, καθορίζουν εάν χρειάζονται πρόσθετα ορίσματα κατά την κλήση. Εάν υπάρχουν μεταχαρακτήρες στη συμβολοσειρά μορφής που ξεκινούν με το σύμβολο %, η συνάρτηση περιμένει την παρουσία αυτών των ορισμάτων.

Ο προγραμματιστής μπορεί να αναπτύξει τις συναρτήσεις του με μεταβλητό αριθμό παραμέτρων. Για την παροχή βολικό τρόποΓια πρόσβαση στα ορίσματα μιας συνάρτησης με μεταβλητό αριθμό παραμέτρων, υπάρχουν τρεις ορισμοί μακροεντολών (μακροεντολές) va_start, va_arg, va_end, που βρίσκονται στο αρχείο κεφαλίδας stdarg.h. Αυτές οι μακροεντολές υποδεικνύουν ότι μια συνάρτηση που αναπτύχθηκε από το χρήστη έχει έναν αριθμό απαιτούμενων ορισμάτων που ακολουθούνται από έναν μεταβλητό αριθμό προαιρετικών ορισμών. Τα απαιτούμενα ορίσματα είναι προσβάσιμα μέσω των ονομάτων τους, όπως και όταν καλείτε μια κανονική συνάρτηση. Για να ανακτήσετε προαιρετικά ορίσματα, χρησιμοποιήστε τις μακροεντολές va_start, va_arg, va_end με την ακόλουθη σειρά.

Η μακροεντολή va_start έχει σχεδιαστεί για να ορίζει το όρισμα arg_ptr στην αρχή της λίστας προαιρετικών παραμέτρων και μοιάζει με μια συνάρτηση με δύο παραμέτρους:

void va_start(arg_ptr, prav_param);

Η παράμετρος prav_param πρέπει να είναι η τελευταία απαιτούμενη παράμετρος της συνάρτησης που καλείται και ο δείκτης arg_prt πρέπει να δηλωθεί με έναν προκαθορισμό στη λίστα των μεταβλητών τύπου va_list με τη μορφή:

va_list arg_ptr;

Η μακροεντολή va_start πρέπει να χρησιμοποιηθεί πριν από την πρώτη χρήση της μακροεντολής va_arg.

Η μακροεντολή va_arg παρέχει πρόσβαση στην τρέχουσα παράμετρο της καλούμενης συνάρτησης και επίσης μοιάζει με μια συνάρτηση με δύο παραμέτρους

type_arg va_arg(arg_ptr,type);

Αυτή η μακροεντολή ανακτά την τιμή του τύπου στη διεύθυνση που καθορίζεται από τον δείκτη arg_ptr, αυξάνει την τιμή του δείκτη arg_ptr κατά το μήκος της παραμέτρου που χρησιμοποιείται (μήκος τύπου) και έτσι η παράμετρος arg_ptr θα δείχνει στην επόμενη παράμετρο της καλούμενης συνάρτησης . Η μακροεντολή va_arg χρησιμοποιείται όσες φορές χρειάζεται για την ανάκτηση όλων των παραμέτρων της συνάρτησης που καλείται.

Η μακροεντολή va_end χρησιμοποιείται μετά την επεξεργασία όλων των παραμέτρων συνάρτησης και θέτει τον προαιρετικό δείκτη της λίστας παραμέτρων στο μηδέν (NULL).

Ας εξετάσουμε τη χρήση αυτών των μακροεντολών για την επεξεργασία των παραμέτρων μιας συνάρτησης που υπολογίζει τη μέση τιμή μιας αυθαίρετης ακολουθίας ακεραίων αριθμών. Εφόσον η συνάρτηση έχει μεταβλητό αριθμό παραμέτρων, θα θεωρήσουμε ότι η τιμή ίση με -1 είναι το τέλος της λίστας. Εφόσον η λίστα πρέπει να έχει τουλάχιστον ένα στοιχείο, η συνάρτηση θα έχει μία απαιτούμενη παράμετρο.

#περιλαμβάνω

#περιλαμβάνω

int sred_znach(int,...);

n=sred_znach(2,3,4,-1); /* κλήση με τέσσερις παραμέτρους */

printf("n=%d\n",n);

n=sred_znach(5,6,7,8,9,-1); /* κλήση με έξι παραμέτρους */

printf("n=%d\n",n);

int sred_znach(int x,...)

int i=0, j=0, άθροισμα=0;

va_start(uk_arg,x); /* ορίστε τον δείκτη uk_arg σε */

/* πρώτη προαιρετική παράμετρος */

αν (x!=-1) άθροισμα=x; /* ελέγξτε αν η λίστα είναι κενή */

αλλιώς επιστροφή (0);

ενώ ((i=va_arg(uk_arg,int))!=-1)

/* επιλέγοντας το επόμενο */

( /* παράμετροι και ελέγξτε */

sum+=i; /* στο τέλος της λίστας */

va_end(uk_arg); /* κλείσιμο της λίστας των παραμέτρων */

Παράδειγμα 2: Μια άλλη επιλογή είναι δυνατή - η πρώτη παράμετρος της συνάρτησης είναι υπεύθυνη για τον αριθμό των στοιχείων που αθροίζονται. Επιπλέον, μπορείτε να αρνηθείτε τη χρήση μακροεντολών και να αναλύσετε τη στοίβα στον κώδικα συνάρτησης.

#περιλαμβάνω

#περιλαμβάνω

int sred_znach2(int,...);

n=sred_znach2(3,2,3,4);

printf("n=%d\n",n);

int sred_znach2(int n,...)

int *pPointer =

για (int i=n ; i; i--) Άθροισμα += *(++pPointer);