Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

@ts:

 

Έστω ότι ορίζεις 2 συναρτήσεις a και b:

 

void a( void )
{
    b();
}

void b( void )
{
    ...
}
Ο κομπάιλερ θα χτυπήσει έρρορ στον ορσιμό της a, επειδή δεν ξέρει τι είναι το b().

 

Μια λύση είναι να ορίσεις την b πριν την a:

void b( void )
{
    ...
}
void a( void )
{
    b();
}
Μια άλλη λύση είναι να διατηρήσεις τον αρχικό κώδικα, αλλά να δηλώσεις την b() πριν την χρησιμοποιήσεις (και πριν την ορίσεις):

void b( void );  // declaration

void a( void )
{
    b();
}

// definition
void b( void )
{
    ...
}
Αν δεν με απατάει η μνήμη μου, θα μπορούσες εναλλακτικά να δηλώσεις την b() μέσα στην a():

void a( void )
{
    void b( void); // declaration
    b();
}
void b( void )
{
    ...
}
αλλά τσέκαρέ το στον compiler σου αυτό το τελευταίο γιατί δεν είμαι 100% σίγουρος.

 

Ο ορισμός της b() δεν χρειάζεται να είναι στο ίδιο αρχείο με τον ορισμό της a(). Θα μπορούσε ας πούμε να ορίζεται σε ένα αρχείo b.c, και η δήλωση της με το extern keyword να βρίσκεται σε ένα αρχείο b.h Με αυτό το παράδειγμα, σε όποιο αρχείο θες να χρησιμοποιήσεις την b() κάνεις #include "b.h" και προφανώς στον compiler προσθέτεις και το b.c αρχείο.

 

Οι μεταβλητές λειτουργούν με παραπλήσια λογική, αλλά όχι ακριβώς γιατί εκείνες έχουν πιο σύνθετο scope από τις συναρτήσεις. Π.χ. μπορεί να είναι internally global, externally global, ή local σε κάποια συνάρτηση. Ενώ οι συναρτήσεις δεν μπορούν να έχουν local scope μέσα σε άλλη συνάρτηση, γιατί η γλώσσα δεν επιτρέπει nested functions. Έχουν είτε intenal είτε external linkage, το οποίο σε γενικές γραμμές μεταφράζεται σε file scope (βασικά σε source module scope ή αλλιώς σε compilation unit scope);

 

Οπότε, στο παράδειγμα που έδωσες:

extern int F;
...
int main( void )
{
    F = 9;
}
ο κώδικας θα δουλέψει αν το F το έχεις ορίσει σε κάποιο άλλο αρχείο, το οποίο το έχεις συμπεριλάβει στο compilation. Έτσι σκέτο όπως το έχεις όμως δεν θα δουλέψει, γιατί το F δεν το ορίζεις πουθενά.

Αν κάνεις αυτό που είπε από λάθος ο gon:

extern int F;
...
int main( void )
{
    int F;
    F = 9;
    ...
}
τότε όπως πολύ σωστά παρατήρησε ο albnik, έχεις 2 μεταβλητές. Μια καθολική F με external linkage την οποία την έχεις μεν δηλώσει αλλά δεν δείχνεις που την έχεις ορίσει (κάποιος που βλέπει αυτό τον κώδικα υποθέτει πως την έχεις ορίσει σε κάποιο άλλο αρχείο, που θα συμπεριλάβεις στο compilation), κι έχεις και μια F η οποία είναι local στην main() και που στην ουσία μέσα στην main κάνει shadow την εξωτερική καθολική.

 

Μαλιστα. Οποτε, για να κανω μια ανασκοπηση.Πρεπει ΠΑΝΤΑ να δηλωνω καπου μια υπαρχουσα μεταβλητη. Αμα θελω να δηλωσω μια μεταβλητη σε εξωτερικο αρχειο. Θα γραψω ΠΧ extern int F;  ΑΝ ομως ειναι στο ιδιο το αρχειο, θα γραψω ΠΧ int F;

 

Σωστα ??

Δημοσ.

Μαλιστα. Οποτε, για να κανω μια ανασκοπηση.Πρεπει ΠΑΝΤΑ να δηλωνω καπου μια υπαρχουσα μεταβλητη. Αμα θελω να δηλωσω μια μεταβλητη σε εξωτερικο αρχειο. Θα γραψω ΠΧ extern int F;  ΑΝ ομως ειναι στο ιδιο το αρχειο, θα γραψω ΠΧ int F;

 

Σωστα ??

Ίσως ναι, ίσως όχι. Εξαρτάται από το αν έχεις κατανοήσει σωστά τους όρους "ορισμός" (definition) και "δήλωση" (declaration).

 

Για να χρησιμοποιήσεις μια μεταβλητή (μια συνάρτηση, έναν τύπο, κλπ) πρέπει υποχρεωτικά να την έχεις ορίσει κάπου. Στην περίπτωση της συνάρτησης, ίσως σε βοηθήσει να το κατανοήσεις καλύτερα θεωρώντας τον "ορισμό" της συνάρτησης ως λειτουργικά συνώνυμο της "υλοποίησης" (implementation) της συνάρτησης.

 

Αν σκοπεύεις να χρησιμοποιήσεις/αναφερθείς σε μια συνάρτηση πριν την ορίσεις, τότε πρέπει πρώτα να δηλώσεις την υπογραφή της (το prototype της, όπως λέγεται συνήθως). Δηλαδή, "δήλωση", "υπογραφή" και "πρότυπο" χρηστικά είναι ισοδύναμα στην περίπτωση της συνάρτησης.

 

Από την άλλη μεριά, αν φροντίζεις να ορίζεις τις συναρτήσεις σου πριν τις χρησιμοποιήσεις, τότε δεν χρειάζεται να τις δηλώνεις κιόλας.

 

Θα έχεις συναντήσει φαντάζομαι κώδικες όπου η main() ορίζεται στο τέλος του αρχείου, και κώδικες όπου η main() ορίζεται στην αρχή του αρχείου. Στην 2η περίπτωση, πάνω από την main() υπάρχουν δηλώσεις (πρότυπα, υπογραφές) όλων των συναρτήσεων που χρησιμοποιεί η main(). Στην 1η περίπτωση, δεν χρειάζεται κάτι τέτοιο.

 

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

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...