voulaji Δημοσ. 2 Ιουνίου 2008 Δημοσ. 2 Ιουνίου 2008 Μπορεί κάποιος να μου εξηγήσει τι θα τυπώσει στη 2η και 3η γραμμή ο πιο κάτω κώδικας; Ειδικότερα με μπερδεύει το *b. #include <stdio.h> int a,b,c,d; void f(int a, int * { int c; *b=a+*b; a=d+3; c=a+1; printf("a=%d, b=%d, c=%d, d=%d \n", a, * b, c, d); } int main() { a=4; b=3; c=2; d=1; printf("a=%d, b=%d, c=%d, d=%d \n", a, b, c, d); f(b,&c); printf("a=%d, b=%d, c=%d, d=%d \n", a, b, c, d); system("pause");
drmetal Δημοσ. 2 Ιουνίου 2008 Δημοσ. 2 Ιουνίου 2008 Το *b είναι δείκτης που δείχνει στη δεύτερη μεταβλητή που θα περαστεί σαν παράμετρος στην συνάρτηση. Δηλαδή με το να πεις *b = 8 ουσιαστικά αλλάζεις τo εξωτερικό/καθολικό c.
voulaji Δημοσ. 2 Ιουνίου 2008 Μέλος Δημοσ. 2 Ιουνίου 2008 Γνωρίζω ότι το *b είναι δείκτης που δείχνει στη δεύτερη μεταβλητή που θα περαστεί σαν παράμετρος στην συνάρτηση. Δεν κατανοώ όμως πώς θα υπολογιστεί και ποια η σχέση του με το c. Συμπληρωματικά, οι προτεινόμενες λύσεις είναι οι εξης 4: a=4, b=3, c=2, d=1 a=4, b=3, c=5, d=1 a=4, b=3, c=5, d=1 a=4, b=3, c=2, d=1 a=4, b=5, c=5, d=1 a=4, b=3, c=5, d=1 a=4, b=3, c=2, d=1 a=4, b=5, c=5, d=1 a=4, b=3, c=2, d=1 a=4, b=3, c=2, d=1 a=4, b=5, c=2, d=1 a=4, b=3, c=5, d=1
drmetal Δημοσ. 2 Ιουνίου 2008 Δημοσ. 2 Ιουνίου 2008 ουσιαστικά το *b είναι το c. καλά γιατί δεν το τρέχεις να δείς ?
voulaji Δημοσ. 2 Ιουνίου 2008 Μέλος Δημοσ. 2 Ιουνίου 2008 Mα το ερώτημά μου έχει να κάνει με την λειτουργία του κώδικα. Θέλω να καταλάβω πως λειτουργεί.
parsifal Δημοσ. 2 Ιουνίου 2008 Δημοσ. 2 Ιουνίου 2008 Ας κάνουμε μία βήμα-βήμα ανίχνευση (tracing) της εκτέλεσης του παρακάτω κώδικα: >#include <stdio.h> int a, b, c, d; void f(int a, int * { int c; *b = a + *b; a = d + 3; c = a + 1; printf("a=%d, b=%d, c=%d, d=%d\n", a, *b, c, d); } int main(void) { a = 4; b = 3; c = 2; d = 1; printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d); f(b, &c); printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d); return 0; } Πάμε στη main: > a = 4; b = 3; c = 2; /* Έστω ότι η διεύθυνση της μεταβλητής c είναι η 0x1000h d = 1; printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d); Τετριμμένο το αποτέλεσμα της printf, νομίζω. > f(b, &c); Δηλαδή: > f(3, 0x1000); Ο κώδικας της f που θα εκτελεστεί: >void f(int a, int * { int c; *b = a + *b; a = d + 3; c = a + 1; printf("a=%d, b=%d, c=%d, d=%d\n", a, *b, c, d); Στο scope της f, η τοπική μεταβλητή a έχει πάρει τιμή από την κλήση της f στη main, δηλαδή έχει τιμή 3. Η b έχει την τιμή 0x1000. Επίσης, έστω ότι με c_local συμβολίζουμε την c που έχει ορισθεί τοπικά εδώ, και με c_global αυτήν που ορίσθηκε εκτός της συνάρτησης. Ομοίως και για a_local, a_global, b_local, b_global. > *b = a + *b; «Υπολόγισε την τιμή της παράστασης a + *b και ανέθεσέ την στη μεταβλητή στην οποία δείχνει ο δείκτης b, δηλαδή στην c_global». Άρα c_global = 3 + c_global και τελικά η c_global θα έχει τιμή 5. > a = d + 3; Τετριμμένο. H a_local παίρνει την τιμή 4. > c = a + 1; Η c_local παίρνει την τιμή 5. > printf("a=%d, b=%d, c=%d, d=%d\n", a, *b, c, d); Τυπώνει την τιμή της a_local (4), της c_global στην οποία δείχνει ο b (5), της c_local (5) και της d (1). Επιστροφή στη main και εκτέλεση της: > printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d); Τυπώνει την τιμή της a_global (4), της b_global (3), της c_global την οποία μετέβαλε η κλήση της f (5) και της d (1). Εύχομαι να βοήθησα...
voulaji Δημοσ. 2 Ιουνίου 2008 Μέλος Δημοσ. 2 Ιουνίου 2008 Με βοήθησες πάρα πολύ και σε ευχαριστώ. Το μόνο σκοτεινό σημείο σε αυτά που λες είναι το εξής: "...Στο scope της f, η τοπική μεταβλητή a έχει πάρει τιμή από την κλήση της f στη main, δηλαδή έχει τιμή 3..." Γιατί πτοκύπτει αυτό;
parsifal Δημοσ. 2 Ιουνίου 2008 Δημοσ. 2 Ιουνίου 2008 Υπάρχουν 2 τρόποι για πέρασμα παραμέτρων κατά την κλήση μίας συνάρτησης: Δια τιμής και δι' αναφοράς. Στον παραπάνω κώδικα, η f καλείται ως εξής: > f(b, &c); Δηλαδή, μετά την αποτίμηση της b: > f(3, &c); Η συνάρτηση έχει δηλωθεί ως εξής: >void f(int a, int * Άρα, για την πρώτη παράμετρο γίνεται πέρασμα δια τιμής: Όταν αρχίσει να εκτελείται ο κώδικας της συνάρτησης, η a_local θα έχει αρχικοποιηθεί αυτόματα σε 3...
voulaji Δημοσ. 3 Ιουνίου 2008 Μέλος Δημοσ. 3 Ιουνίου 2008 Λοιπόν parsifal για άλλη μια φορά με ξελάσπωσες. Πραγματικά ήταν πολύ αναλυτική η απάντησή σου. Έχω όμως μια ακόμη απορία για τον συγκεκριμένο κώδικα: Αφού η void ορίζεται ως εξής: f(inta, int * και στην main καλείται η f(b,&c), που στην ευχή χρησιμοποιούμε την δήλωση *b=a+*b?
parsifal Δημοσ. 3 Ιουνίου 2008 Δημοσ. 3 Ιουνίου 2008 Αυτό το κομμάτι κώδικα δεν είναι δήλωση, αλλά εντολή ανάθεσης. Εκτός αν εννοείς κάτι άλλο. Χμμμ;
voulaji Δημοσ. 3 Ιουνίου 2008 Μέλος Δημοσ. 3 Ιουνίου 2008 Ναι έκανα λάθος. Αυτήν την εντολή ανάθεσης εννοώ πάντως. Θα μπορούσε να μην υπάρχει ή να ήταν κάπως αλλιώς;
parsifal Δημοσ. 3 Ιουνίου 2008 Δημοσ. 3 Ιουνίου 2008 Θα μπορούσε να μην υπάρχει ή να ήταν κάπως αλλιώς; Δεν εκφράζεσαι ορθολογικά και μπερδεύεις κι εμένα: Ο κώδικας που έχεις δώσει στο 1ο σου post δεν είναι η λύση ενός δοθέντος γνωστού προβλήματος, αλλά ένα απλό παράδειγμα που εκτελεί χαζές, χωρίς νόημα εντολές για να σε βάλει απλά στη διαδικασία του να κατανοήσεις τί συμβαίνει. Άρα, το ερώτημά σου δεν έχει και πολύ νόημα. Αν τώρα η άσκησή σου ζητούσε «Γράψτε μία συνάρτηση με τη βοήθεια της οποίας θα αυξάνουμε την τιμή μίας μεταβλητής π.χ. κατά 1», τότε ναι, το ερώτημά σου θα είχε νόημα. Ακολουθούν ένας λάθος τρόπος και δύο σωστοί: >#include <stdio.h> void increment(int a) { a++; } int main(void) { int a = 0; printf("a = %d\n", a); increment(a); printf("a = %d\n", a); return 0; } >#include <stdio.h> int increment(int a) { return a + 1; } int main(void) { int a = 0; printf("a = %d\n", a); a = increment(a); printf("a = %d\n", a); return 0; } >#include <stdio.h> void increment(int *a) { (*a)++; } int main(void) { int a = 0; printf("a = %d\n", a); increment(&a); printf("a = %d\n", a); return 0; } Αν δεν καταλαβαίνεις τη διαφορά, μη διστάσεις να ξαναρωτήσεις...
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.