Περάστε με αναφορά ή να περάσει από την αξία;

ψήφοι
48

Κατά την εκμάθηση μιας νέας γλώσσας προγραμματισμού, ένα από τα πιθανά εμπόδια που μπορεί να συναντήσετε είναι το ζήτημα αν η γλώσσα είναι, εξ ορισμού, να περάσει προς την αξία ή pass-by-αναφοράς .

Έτσι, εδώ είναι η ερώτησή μου προς όλους εσάς, στην αγαπημένη σας γλώσσα, πώς είναι πραγματικά γίνει; Και ποιες είναι οι πιθανές παγίδες ;

Η αγαπημένη σας γλώσσα μπορεί, φυσικά, να είναι οτιδήποτε έχετε παίξει ποτέ με: λαϊκή , σκοτεινές , απόκρυφα , νέα , παλιά ...

Δημοσιεύθηκε 05/08/2008 στις 09:56
πηγή χρήστη
Σε άλλες γλώσσες...                            


11 απαντήσεις

ψήφοι
31

Εδώ είναι η δική μου συμβολή για τη γλώσσα προγραμματισμού Java .

πρώτα ένα τμήμα κώδικα:

public void swap(int x, int y)
{
  int tmp = x;
  x = y;
  y = tmp;
}

καλώντας τη μέθοδο αυτή θα έχει ως αποτέλεσμα αυτό:

int pi = 3;
int everything = 42;

swap(pi, everything);

System.out.println("pi: " + pi);
System.out.println("everything: " + everything);

"Output:
pi: 3
everything: 42"

ακόμη και με «πραγματική» αντικείμενα θα δείξει ένα παρόμοιο αποτέλεσμα:

public class MyObj {
    private String msg;
    private int number;

    //getters and setters
    public String getMsg() {
        return this.msg;
    }


    public void setMsg(String msg) {
        this.msg = msg;
    }


    public int getNumber() {
        return this.number;
    }


    public void setNumber(int number) {
        this.number = number;
    }

    //constructor
    public MyObj(String msg, int number) {
        setMsg(msg);
        setNumber(number);
    }
}

public static void swap(MyObj x, MyObj y)
{
    MyObj tmp = x;
    x = y;
    y = tmp;
}

public static void main(String args[]) {
    MyObj x = new MyObj("Hello world", 1);
    MyObj y = new MyObj("Goodbye Cruel World", -1); 

    swap(x, y);

    System.out.println(x.getMsg() + " -- "+  x.getNumber());
    System.out.println(y.getMsg() + " -- "+  y.getNumber());
}


"Output:
Hello world -- 1
Goodbye Cruel World -- -1"

Έτσι, είναι σαφές ότι η Java περνάει τις παραμέτρους της με βάση την αξία , ως αξία για τα pi και τα πάντα και τα αντικείμενα MyObj δεν ανταλλάσσονται. Πρέπει να γνωρίζετε ότι «με την τιμή» είναι ο μόνος τρόπος με java για να περάσετε παραμέτρους σε μια μέθοδο. (για παράδειγμα, μια γλώσσα όπως η C ++ επιτρέπει ο κύριος του έργου για να περάσει μια παράμετρο σε σχέση με τη χρήση « και » μετά το είδος της παραμέτρου)

τώρα το δύσκολο μέρος , ή τουλάχιστον το μέρος που θα μπερδέψει τα περισσότερα από τα νέα προγραμματιστές java: (δανεισμένη από javaworld )
Αρχικός συντάκτης: Tony Sintes

public void tricky(Point arg1, Point arg2)
{
    arg1.x = 100;
    arg1.y = 100;
    Point temp = arg1;
    arg1 = arg2;
    arg2 = temp;
}
public static void main(String [] args)
{
    Point pnt1 = new Point(0,0);
    Point pnt2 = new Point(0,0);
    System.out.println("X: " + pnt1.x + " Y: " +pnt1.y); 
    System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
    System.out.println(" ");
    tricky(pnt1,pnt2);
    System.out.println("X: " + pnt1.x + " Y:" + pnt1.y); 
    System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  
}


"Output
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0"

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

περισσότερα από Tony Sintes:

Η μέθοδος αλλάζει με επιτυχία την αξία των pnt1, παρόλο που έχει περάσει από την τιμή? Ωστόσο, μια συμφωνία ανταλλαγής των pnt1 και ΡΝΤ2 αποτύχει! Αυτή είναι η κύρια πηγή της σύγχυσης. Στη μέθοδο κύριας (), pnt1 και ΡΝΤ2 είναι τίποτα περισσότερο από αναφορές αντικειμένου. Όταν περνάτε pnt1 και ΡΝΤ2 με τη μέθοδο δύσκολο (), Java περνάει τις αναφορές από την αξία ακριβώς όπως και κάθε άλλη παράμετρο. Αυτό σημαίνει ότι οι αναφορές πέρασε με τη μέθοδο είναι πραγματικά αντίγραφα των πρωτότυπων αναφορών. Το Σχήμα 1 παρακάτω δείχνει δύο αναφορές που δείχνουν προς το ίδιο αντικείμενο μετά Java περνά ένα αντικείμενο σε μία μέθοδο.

Σχήμα 1 http://www.javaworld.com/javaworld/javaqa/2000-05/images/03-qa-0512-pass2b.gif

Συμπέρασμα ή μια μακρά ιστορία σύντομη:

  • Java περνάει τις παραμέτρους με βάση την αξία
  • «κατ 'αξία» είναι ο μόνος τρόπος σε Java για να περάσει μια παράμετρο σε μία μέθοδο
  • χρησιμοποιώντας μεθόδους από το αντικείμενο δίνεται ως παράμετρος θα μεταβάλει το αντικείμενο ως οι αναφορές δείχνουν τα αρχικά αντικείμενα. (αν ότι η ίδια μέθοδος μεταβάλλει κάποιες τιμές)

χρήσιμοι σύνδεσμοι:

Απαντήθηκε 05/08/2008 στις 09:56
πηγή χρήστη

ψήφοι
20

Εδώ είναι ένα άλλο άρθρο για τη γλώσσα προγραμματισμού C #

γ # περνάει τα επιχειρήματά της με βάση την αξία (από προεπιλογή)

private void swap(string a, string b) {
  string tmp = a;
  a = b;
  b = tmp;
}

καλώντας αυτήν την έκδοση της ανταλλαγής θα πρέπει ως εκ τούτου δεν αποτελέσματος:

string x = "foo";
string y = "bar";
swap(x, y);

"output: 
x: foo
y: bar"

Ωστόσο, σε αντίθεση με java γ # δεν δώσει στον κύριο του έργου την ευκαιρία να περάσετε παραμέτρους με αναφορά , αυτό γίνεται με τη χρήση τη λέξη-κλειδί «διαιτητή» πριν από τον τύπο της παραμέτρου:

private void swap(ref string a, ref string b) {
  string tmp = a;
  a = b;
  b = tmp;
} 

η ανταλλαγή θα αλλάξει την τιμή της παραμέτρου αναφέρεται:

string x = "foo";
string y = "bar";
swap(x, y);

"output: 
x: bar
y: foo"

γ # έχει επίσης έξω λέξη-κλειδί , και η διαφορά μεταξύ του διαιτητή και έξω είναι μια λεπτή μία. από το MSDN:

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

και

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

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

συμπέρασμα:

  • γ # περνά τις παραμέτρους της, από προεπιλογή, με βάση την αξία
  • αλλά όταν χρειάζεται παράμετροι μπορούν επίσης να περάσει με αναφορά χρησιμοποιώντας τη λέξη-κλειδί διαιτητή
  • εσωτερική μεθόδους από μία παράμετρο περάσει από τιμή θα μεταβάλει το αντικείμενο (εάν η ίδια μέθοδος μεταβάλλει κάποιες τιμές)

χρήσιμοι σύνδεσμοι:

Απαντήθηκε 05/08/2008 στις 17:40
πηγή χρήστη

ψήφοι
19

Python χρησιμοποιεί pass-by-αξία, αλλά επειδή όλες αυτές οι αξίες είναι οι αναφορές αντικείμενο, το καθαρό αποτέλεσμα είναι κάτι σαν pass-by-αναφοράς. Ωστόσο, Python προγραμματιστές σκέφτονται περισσότερο για το αν ένα είδος αντικειμένου είναι ευμετάβλητος και αμετάβλητος . Μεταβλητή αντικείμενα μπορεί να αλλάξει επί τόπου (π.χ., λεξικά, κατάλογοι, καθορίζονται από το χρήστη αντικείμενα), ενώ αμετάβλητα αντικείμενα δεν μπορούν (π.χ., ακέραιοι, χορδές, πλειάδες).

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

>>> def do_something(a, b):
...     a = "Red"
...     b.append("Blue")
... 
>>> a = "Yellow"
>>> b = ["Black", "Burgundy"]
>>> do_something(a, b)
>>> print a, b
Yellow ['Black', 'Burgundy', 'Blue']

Η γραμμή a = "Red"απλώς δημιουργεί μια τοπική ονομασία, aγια την τιμή συμβολοσειράς "Red"και δεν έχει καμία επίδραση στην πέρασε στο επιχείρημα (που τώρα κρύβεται, όπως aπρέπει να αναφέρεται στον τοπικό όνομα από τότε). Εκχώρηση δεν είναι μια πράξη επί τόπου, ανεξάρτητα από το αν το επιχείρημα είναι ευμετάβλητος και αμετάβλητος.

Η bπαράμετρος είναι μια αναφορά σε ένα μεταβλητό αντικείμενο λίστα, και η .append()μέθοδος εκτελεί μια επέκταση σε θέση της λίστας, στερέωση στη νέα "Blue"τιμή συμβολοσειράς.

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

Μόλις η συνάρτηση επιστρέφει, η εκ νέου ανάθεση της aδεν είχε καμία επίδραση, ενώ η επέκταση του bδείχνει σαφώς pass-by-αναφορά σημασιολογία κλήση στυλ.

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

>>> a = ["Purple", "Violet"]
>>> do_something(a, b)
>>> print a, b
['Purple', 'Violet'] ['Black', 'Burgundy', 'Blue', 'Blue']

Εάν δεν θέλετε λίστα σας έχει τροποποιηθεί με την κάλεσε τη λειτουργία, θα πρέπει να χρησιμοποιήσετε αντί για το αμετάβλητο τύπου πλειάδα (προσδιορίζονται από τις παρενθέσεις με την κυριολεκτική μορφή, αντί αγκύλες), η οποία δεν υποστηρίζει την επιτόπια .append()μέθοδο:

>>> a = "Yellow"
>>> b = ("Black", "Burgundy")
>>> do_something(a, b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in do_something
AttributeError: 'tuple' object has no attribute 'append'
Απαντήθηκε 23/08/2008 στις 17:50
πηγή χρήστη

ψήφοι
7

Επειδή δεν έχω δει μια απάντηση Perl ακόμα, σκέφτηκα να γράψω ένα.

Κάτω από το καπό, Perl λειτουργεί αποτελεσματικά ως pass-by-αναφοράς. Οι μεταβλητές ως επιχειρήματα κλήση της συνάρτησης πέρασε referentially, οι σταθερές πέρασε ως μόνο για ανάγνωση αξίες, και τα αποτελέσματα των εκφράσεων πέρασε ως προσωρινές αποκαταστάσεις. Οι συνήθεις ιδιώματα για να κατασκευάσει καταλόγους επιχείρημα ανάθεση λίστα από @_, ή shiftέχουν την τάση να κρύψει αυτό από το χρήστη, δίνοντας την εντύπωση pass-by-τιμής:

sub incr {
  my ( $x ) = @_;
  $x++;
}

my $value = 1;
incr($value);
say "Value is now $value";

Αυτό θα εκτυπώσετε Value is now 1επειδή το $x++έχει αυξάνεται το λεξιλογικό μεταβλητές που δηλώνονται στο πλαίσιο του incr()λειτουργία, παρά τη μεταβλητή πέρασε. Αυτό pass-by-τιμής στυλ είναι συνήθως αυτό που ήθελε περισσότερο χρόνο, όπως οι λειτουργίες που τροποποιούν τα επιχειρήματά τους είναι σπάνιες σε Perl, και το στυλ θα πρέπει να αποφεύγεται.

Ωστόσο, αν για κάποιο λόγο αυτή η συμπεριφορά είναι ιδιαίτερα επιθυμητή, μπορεί να επιτευχθεί με τη λειτουργία απευθείας σε στοιχεία του @_πίνακα, επειδή θα είναι ψευδώνυμα για τις μεταβλητές πέρασε σε λειτουργία.

sub incr {
  $_[0]++;
}

my $value = 1;
incr($value);
say "Value is now $value";

Αυτή τη φορά θα εκτυπώσει Value is now 2, επειδή η $_[0]++έκφραση αυξάνεται η πραγματική $valueμεταβλητή. Ο τρόπος με τον οποίο δουλεύει αυτό είναι ότι κάτω από το καπό @_δεν είναι ένα πραγματικό σειρά όπως και οι περισσότερες άλλες διατάξεις (όπως θα επιτυγχανόταν με my @array), αλλά αντ 'αυτού τα στοιχεία της ενσωματωμένης απευθείας από τα επιχειρήματα που πέρασε σε μια κλήση συνάρτησης. Αυτό σας επιτρέπει να δημιουργήσετε pass-by-αναφορά σημασιολογία αν αυτό θα απαιτηθούν. Τα επιχειρήματα κλήση της συνάρτησης που είναι απλό μεταβλητές εισαχθεί ως έχει σε αυτήν την σειρά, και οι σταθερές ή τα αποτελέσματα των πιο σύνθετες εκφράσεις εισαχθεί ως μόνο για ανάγνωση προσωρινές αποκαταστάσεις.

Ωστόσο, είναι εξαιρετικά σπάνιο να το κάνετε αυτό στην πράξη, επειδή Perl υποστηρίζει τιμές αναφοράς? δηλαδή, οι τιμές που αναφέρονται σε άλλες μεταβλητές. Κανονικά είναι πολύ σαφέστερο να κατασκευάσει μια λειτουργία που έχει μια προφανή παρενέργεια σε μια μεταβλητή, με το πέρασμα σε μια αναφορά στην εν λόγω μεταβλητή. Αυτό είναι μια σαφής ένδειξη για τον αναγνώστη στο callsite, ότι σημασιολογία αναφοράς pass-by-είναι σε ισχύ.

sub incr_ref {
  my ( $ref ) = @_;
  $$ref++;
}

my $value = 1;
incr(\$value);
say "Value is now $value";

Εδώ ο \χειριστής δίδει μία αναφορά με τον ίδιο τρόπο όπως και η &διεύθυνση-του φορέα στον C.

Απαντήθηκε 13/04/2012 στις 16:33
πηγή χρήστη

ψήφοι
6

Υπάρχει μια καλή εξήγηση εδώ για .NET.

Πολλοί άνθρωποι είναι έκπληξη το γεγονός ότι τα αντικείμενα αναφοράς είναι στην πραγματικότητα πέρασε σε αξία (και στις δύο C # και Java). Είναι ένα αντίγραφο της διεύθυνσης στοίβα. Αυτό αποτρέπει μία μέθοδο από την αλλαγή, όπου το αντικείμενο επισημαίνει πράγματι να, αλλά εξακολουθεί να επιτρέπει μια μέθοδος για να αλλάξετε τις τιμές του αντικειμένου. Στην C # είναι δυνατόν του να περάσει μια αναφορά με αναφορά, που σημαίνει ότι μπορείτε να αλλάξετε, όπου μια πραγματική σημεία αντικείμενο για να.

Απαντήθηκε 06/08/2008 στις 23:43
πηγή χρήστη

ψήφοι
5

Μην ξεχνάτε υπάρχει επίσης περάσει από το όνομα , και να περάσει από την τιμή-αποτέλεσμα .

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

Περάστε από το όνομα σημαίνει ότι οι τιμές υπολογίζονται μόνο όταν χρησιμοποιούνται στην πραγματικότητα, και όχι κατά την έναρξη της διαδικασίας. Algol που χρησιμοποιούνται pass-by-name, αλλά μια ενδιαφέρουσα παρενέργεια είναι ότι είναι πολύ δύσκολο να γράψω μια διαδικασία ανταλλαγής ( αναφοράς ). Επίσης, η έκφραση πέρασε από όνομα επανεκτιμάται κάθε φορά που γίνεται πρόσβαση, το οποίο μπορεί επίσης να έχει παρενέργειες.

Απαντήθηκε 05/08/2008 στις 11:00
πηγή χρήστη

ψήφοι
4

Ό, τι λέτε και να περάσει προς την αξία ή pass-by-αναφοράς πρέπει να είναι συνεπής σε πολλές γλώσσες. Η πιο κοινή και συνεπή ορισμό που χρησιμοποιείται σε πολλές γλώσσες είναι ότι με pass-by-αναφορά, μπορείτε να περάσετε μια μεταβλητή σε μια συνάρτηση «κανονικά» (δηλαδή χωρίς να λαμβάνονται ρητά διεύθυνση ή κάτι τέτοιο), και η λειτουργία μπορεί να αναθέσει σε (δεν μεταλλάσσονται τα περιεχόμενα της) η παράμετρος μέσα στη συνάρτηση και θα έχει το ίδιο αποτέλεσμα με την ανάθεση στη μεταβλητή στην κλήση πεδίο.

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

Η συντριπτική πλειοψηφία των γλωσσών συμπεριλαμβανομένων των C , Java , Python , Ruby , το JavaScript , Σχέδιο , OCaml , Standard ML , Go , Objective-C , Smalltalk , κλπ είναι όλα pass-by-τιμή μόνο . Περνώντας μια τιμή του δείκτη (μερικές γλώσσες είναι μια «αναφορά» κλήση) δεν μετράει ως πέρασμα με αναφορά? ανησυχούμε μόνο για το πράγμα που πέρασε, ο δείκτης, δεν το πράγμα επεσήμανε.

Γλώσσες όπως η C ++ , C # , PHP είναι εξ ορισμού pass-by-αξίας, όπως τα παραπάνω γλώσσες, αλλά οι λειτουργίες μπορούν να δηλώσουν ρητά τις παραμέτρους για να περάσει-από-αναφορά, χρησιμοποιώντας &ή ref.

Perl είναι πάντα pass-by-αναφοράς? Ωστόσο, στην πράξη, οι άνθρωποι αντιγράψετε σχεδόν πάντα τις τιμές μετά από να πάρει την, ως εκ τούτου, χρησιμοποιώντας το σε ένα πέρασμα-από-τιμής τρόπο.

Απαντήθηκε 13/04/2012 στις 21:00
πηγή χρήστη

ψήφοι
4

με βάση την αξία

  • είναι πιο αργή από ό, τι σε σχέση δεδομένου ότι το σύστημα πρέπει να αντιγράψετε την παράμετρο
  • χρησιμοποιείται για την είσοδο μόνο

με αναφορά

  • πιο γρήγορα αφού μόνο ένας δείκτης έχει περάσει
  • χρησιμοποιείται για είσοδο και έξοδο
  • μπορεί να είναι πολύ επικίνδυνο αν χρησιμοποιηθεί σε συνδυασμό με τις παγκόσμιες μεταβλητές
Απαντήθηκε 05/08/2008 στις 10:10
πηγή χρήστη

ψήφοι
3

Όσον αφορά J , ενώ υπάρχει μόνο, AFAIK, περνώντας από την αξία, υπάρχει μια μορφή που διέρχεται δι 'αναφοράς η οποία επιτρέπει τη μετακίνηση πολλά δεδομένα. Μπορείτε απλά να περάσει κάτι που είναι γνωστό ως locale σε ένα ρήμα (ή λειτουργία). Μπορεί να είναι ένα στιγμιότυπο μιας κλάσης ή απλά για ένα γενικό δοχείο.

spaceused=: [: 7!:5 <
exectime =: 6!:2
big_chunk_of_data =. i. 1000 1000 100
passbyvalue =: 3 : 0
    $ y
    ''
)
locale =. cocreate''
big_chunk_of_data__locale =. big_chunk_of_data
passbyreference =: 3 : 0
    l =. y
    $ big_chunk_of_data__l
    ''
)
exectime 'passbyvalue big_chunk_of_data'
   0.00205586720663967
exectime 'passbyreference locale'
   8.57957102144893e_6

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

Απαντήθηκε 21/11/2009 στις 18:14
πηγή χρήστη

ψήφοι
2

PHP έχει επίσης περάσει από την αξία.

<?php
class Holder {
    private $value;

    public function __construct($value) {
        $this->value = $value;
    }

    public function getValue() {
        return $this->value;
    }
}

function swap($x, $y) {
    $tmp = $x;
    $x = $y;
    $y = $tmp;
}

$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);

echo $a->getValue() . ", " . $b->getValue() . "\n";

έξοδοι:

a b

Ωστόσο, σε PHP4 αντικείμενα υποβλήθηκαν σε επεξεργασία όπως αρχέτυπα . Που σημαίνει:

<?php
$myData = new Holder('this should be replaced');

function replaceWithGreeting($holder) {
    $myData->setValue('hello');
}

replaceWithGreeting($myData);
echo $myData->getValue(); // Prints out "this should be replaced"
Απαντήθηκε 11/08/2008 στις 03:21
πηγή χρήστη

ψήφοι
-1

Από προεπιλογή, ANSI / ISO C χρησιμοποιεί είτε - αυτό εξαρτάται από το πώς θα κηρύξει τη λειτουργία και τις παραμέτρους της.

Αν δηλώνετε τις παραμέτρους λειτουργίας σας ως δείκτες τότε η λειτουργία θα περάσει-από-αναφορά, και αν δηλώνουν τις παραμέτρους λειτουργίας σας ως μεταβλητές δεν-δείκτη, τότε η λειτουργία θα είναι pass-by-τιμής.

void swap(int *x, int *y);   //< Declared as pass-by-reference.
void swap(int x, int y);     //< Declared as pass-by-value (and probably doesn't do anything useful.)

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

float *FtoC(float temp)
{
    float c;
    c = (temp-32)*9/5;
    return &c;
}

Θα μπορούσε, όμως, να επιστρέψει μια αναφορά σε μια στατική μεταβλητή ή ένα δείκτη που ψηφίστηκε από τη λίστα παραμέτρων.

float *FtoC(float *temp)
{
    *temp = (*temp-32)*9/5;
    return temp;
}
Απαντήθηκε 13/01/2011 στις 21:48
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more