ασκήσεις ακριβείας

Posted by Νεόφυτος Δημητρίου Sun, 06 Apr 2008 13:18:29 EEST

τι μπορεί να μην πάει καλά με τον πιο κάτω κώδικα;

  char *x, *y;   // code omitted for clarity   for (x = strrchr(y, '.') - 1; x > y; x--) {        // code omitted for clarity   }

Posted in C, Pointers | 13 comments

    Reader's Comments

  1. η αρχικοποίηση του y και ο έλεγχος αν δεν υπάρχει καθόλου '.' στο y πριν το loop εν μέσα στο code omitted;

    -- Ελένη Γεωργίου ~geleni, April 06, 2008

  2. Το encoding να είναι UTF-8 και να μην μπορείς με x– να κινηθείς σωστά μέσα στο string (όταν βάζεις μη αγγλικό κείμενο).

    -- Αυγουστίνος Καδής ~avgoustinos, April 06, 2008

    • Η αρχικοποίηση του y γίνεται μέσα στο πρώτο code omitted. Το y μπορεί να είναι η συμβολοσειρά localhost (χωρίς τελεία).
    • Το y μπορείτε να θεωρήσετε ότι είναι μια IP διεύθυνση ή ένα domain.

    -- Νεόφυτος Δημητρίου ~k2pts, April 06, 2008

  3. Τι μπορεί να μην πάει καλά:

    1-βλ. σχόλιο Ελένης

    2-βλ. σχόλιο Αυγουστίνου

    3-να ξεκινά ή να τελειώνει το y με τελεία (δεν νομίζω να επιτρέπεται αλλά τέλος πάντων)

    4-ίσως 2 τελείες συνεχόμενες στο y

    5-το x > y δεν είμαι σίγουρος πώς δουλεύει με pointers

    6-ο προγραμματιστής που κάθεται και προγραμματίζει σε C

    -- Κωνσταντίνος Κωνσταντίνου ~constandinos, April 06, 2008

  4. Η απάντηση πρέπει να είναι συγκεκριμένη (είπαμε, ασκήσεις ακριβείας). Λάβε υπόψη ότι έχεις ταλαιπωρηθεί να βρεις που είναι το πρόβλημα στον κώδικα. Χρησιμοποίησες gdb κι έχεις καταλήξει στο υπόψη κομμάτι κώδικα. Πρέπει να εντοπίσεις τι ακριβώς φταίει και να το διορθώσεις. Διαφορετικά, δεν έχει λογαριασμούς email για τα μέλη του phigita.net.

    -- Νεόφυτος Δημητρίου ~k2pts, April 06, 2008

  5. Μα δεν ανάφερες πουθενά ποιο είναι το σύμπτωμα :P

    -- Γεωργία Γεωργίου ~georgia, April 06, 2008

  6. Ήταν να πω segmentation fault αλλά δεν θα ήταν ακριβής η περιγραφή λόγω του κώδικα που λείπει. Το segmentation fault, ωστόσο, προκύπτει εξαιτίας του τι δεν πάει καλά στον κώδικα που δημοσιεύω.

    -- Νεόφυτος Δημητρίου ~k2pts, April 06, 2008

  7. Σε περιπτωση που δεν υπάρχει '.' στο y τότε αυτό: strrchr(y, '.') επιστρέφει NULL.

    και έχουμε το εξής περίεργο:

    This is y:eg30

    1. x=-1

    2. y=6685040

    3. x > y =1 // το περίεργο

    4. (1==1)=1

    Υποθέτω ότι αρνητική τιμή σε pointer δεν έχει νόημα άρα εάν ένας pointer έχει αρνητική τιμή τότε η C … συγχύζεται :P.

    Άρα, η συνθήκη του for είναι αληθής και θα έχεις segmentation fault μέσα στο for εάν προσπαθήσεις να διαβάσεις το *x.

    -- Γεωργία Γεωργίου ~georgia, April 06, 2008

  8. Χωρίς να γνωρίζουμε τι ακολουθεί στα σχόλια επιχειρώ:

    Άμα το y περιέχει string χωρίς '.' το loop αδυνατεί να εκτελεστεί γιατί με βάση τον κώδικα σωστής κυκλοφορίας: http://www.cplusplus.com/reference/clibrary/cstring/strrchr.html "If the value is not found, the function returns a null pointer."

    Αν και λογικά το loop δεν θα έπρεπε να εκτελεστεί καθόλου, η Dec-C++ ξεκινά από αρνητικό αριθμό για pointer και συνεχίζει ακάθεκτη μειώνοντας το αριθμό (-1 σε -2 π.χ.)

    Μιας και δεν νομίζω να είναι το πιο πάνω το πρόβλημα επιχειρώ με τα επόμενα:

    Ο κώδικας παραβλέπει το τελευταίο κομμάτι μετά το κόμμα, πχ το "first.last" δεν θα προσπέλασε καθόλου το last

    Και τέλος μιας και πρόκειται για άσκηση ακριβείας (ποντάρω σε αυτό να είναι το πρόβλημα!): Ο κώδικας δεν θα προσπελάσει ένα χαρακτήρα από τις "πρώτες ομάδες" (με βάση το ποιο πάνω το "first.second.last" το last δεν θα προσπελαστεί ποτέ) οπότε ανάλογα με την χρήση του x θα παίρναμε μόνο "irst.second" ή "first.secon"

    Φυσικά τα πιο πάνω προβλήματα λύνονται προσθέτοντας απλός μια τελεία στην αρχή και μια στο τέλος του αλφαριθμητικού που περιέχονται στο y[]

    -- Πέτρος Πέτρου ~pellaras, April 06, 2008

  9. Η Γεωργία επρόλαβαιν με, παρακαλώ όπως γίνει ban!

    Ευχαριστώ!

    -- Πέτρος Πέτρου ~pellaras, April 06, 2008

  10. ;)

    -- Γεωργία Γεωργίου ~georgia, April 06, 2008

  11. Σωστά!

    Το "περίεργο" είναι ότι ο κώδικας εκτελείται όταν η strrchr επιστρέφει NULL. Σε αυτή την περίπτωση, το x αρχικοποιείται με τη θέση μνήμης 0 (για το NULL) - 1. Αν εξετάσεις την τιμή του x ως ακέραιο τότε φαινομενικά θα έχεις (-1 > 6685040) ενώ στην πραγματικότητα έχεις θέση μνήμης 0xffffffff η οποία είναι όντως μεγαλύτερη του 0x660170 (=6685040). Το πρόβλημα λύνεται μεταφέροντας το -1 από την αρχικοποίηση του x ή μετατρέποντας (casting) σε ακέραιους τα x και y πριν από το σχετικό έλεγχο (int) x > (int) y.

    Τώρα να δούμε τι θα πει ο Βλαδίμηρος που έγραψε τον κώδικα (εκείνου του δουλεύει — έχω την εντύπωση ότι του δουλεύει επειδή δεν έχει δοκιμάσει με y χωρίς τελείες, π.χ. localhost).

    Γεωργία: το βραβείο σου θα το παραλάβεις στην επόμενη phigito-συνάντηση.

    -- Νεόφυτος Δημητρίου ~k2pts, April 06, 2008

  12. :D. Πρέπει να επισημάνω ότι η Ελένη έκανε την αρχή με το σχόλιό της.

    -- Γεωργία Γεωργίου ~georgia, April 06, 2008