lektikos Δημοσ. 15 Νοεμβρίου 2013 Μέλος Δημοσ. 15 Νοεμβρίου 2013 Πολύ διαφωτιστικά όσα μου έγραψες, Οπότε, θα μπορούσαμε στην ανακύκλωση, να βάλουμε και *p!=NULL; Έτσι? @lektikos το σύμβολο / μπορει να χρησιμοποιηθει και σαν διαιρεση και στα σχολια (με ενα αστερακι μετα). Ετσι και το συμβολο * . Μπορει να χρησιμοποιηθει και στον πολλαπλασιασμο και στην δηλωση ενος δεικτη και στην αποαναφοροποιηση του δεικτη (που παιρνεις το περιεχομενο της διευθυνσης που δειχνει ο δεικτης). Οταν δηλωνεις εναν δεικτη ο μεταγλωτιστης ξέρει οτι αυτο το συμβολο ειναι για αυτη την δουλεια επομενως κατα την στιγμη της δηλωσης του μπορει να αρχικοποιησεις τον δεικτη με μια διευθυνση στην προκειμενη με την διευθυνση του string. To str ειναι μια σταθερη διευθυνση και αντιμετωπιζεται σαν δεικτης ΜΟΝΟ οταν περνάει σαν ορισμα σε μια συνάρτηση σε ολες τις υπολοιπες περιπτωσεις ειναι πίνακας και οχι δεικτης. Για παράδειγμα αμα δηλωθει ενας πινακας στην main και δεν τον περνάς σε καποια συνάρτηση τοτε ειναι πινακας. Επισης το συμβολο * διπλα στον p ΣΕ ΟΛΕΣ τις αλλες περιπτωσεις (εκτος της δηλωσης του που εγραψα πριν) αντιμετωπιζεται ως συμβολο αποαναφοροποιησης του δεικτη. Οποτε το χρησιμοποιεις δηλαδη θα παιρνεις το περιεχομενο του. Φυσικα η κατασταση αλλαζει οταν μιλαμε για διπλους δεικτες αλλα αυτο δεν σε απασχολει προς το παρον. Το for ή ανακυκλωση θα σταματησει οταν το *p γινει 0. Δωσει δηλαδη μη αληθη τιμη. Εκτιμηθει σε 0 που ειναι ο ASCII του null character '\0' για αυτο το λογο θα πρεπει ένα εγκυρο C-string να τερματιζει με αυτο τον χαρακτηρα σαν τελευταιο του. Ο βροχος θα σταματησει οταν το string φτασει στο τέλος του.
Star_Light Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 Πολύ διαφωτιστικά όσα μου έγραψες, Οπότε, θα μπορούσαμε στην ανακύκλωση, να βάλουμε και *p!=NULL; Έτσι? Oχι. Διοτι ο NULL ειναι δεικτης ενω το *p οχι. Στην παραπανω προταση χρησιμοποιεις τον συμβολισμο * εκτος δηλωσης αρα δεν θα ειναι συμβολο που λεει στον μεταγλωτιστη οτι προκειται για εναν δεικτη αλλα για ενα στοιχειο(αποαναφοροποιηση -> παιρνουμε το περιεχομενο της μνημης και οχιτ ην διευθυνση της). Το *p ειναι στοιχειο. Δεν ειναι δεικτης. Το NULL ομως ειναι οποτε θα σου κτυπησει επειδη πας να κανεις συγκριση μεταξυ ενος δεικτη και ενος στοιχειου. Αν ομως το * υπηρχε στην δηλωση για παράδειγμα char *p=NULL; /* Έγκυρο εδω το συμβολο * λεει στον μεταγλωτιστη οτι θα ακολουθησει η δηλωση ενος δεικτη και ο δεικτης περιμενει σαν τιμή μια διευθυνση και οχι καποια άλλη αριθμητικη τιμή. */ Eπισης προσοχη : p = p + 1; // Αριθμητικη δεικτων *p = *p + 1; // Αριθμητικη στοιχειων. /* O p πρεπει να δειχνει σε εναν εγκυρο πινακα αλλιως τα παραπανω παράγουν απροσδιοριστη συμπεριφορα */
Star_Light Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 και όμως "έτρεξε" Δεν έχει σημασια. Και άλλα μπορει να τρέξουν αλλα να τρέχουν κατα τύχη. Ενα warning θα το έχεις παρει κανονικα.
migf1 Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 Το σκέτο *p ως έλεγχος ισοδυναμεί με: *p != '\0' Τα strings στη C είναι πίνακες χαρακτήρων που περιέχουν στο τέλος τους τον χαρακτήρα '\0' (ισοδυναμεί με (int) 0 ) . Όταν έχεις χρόνο και διάθεση, ρίξε μια ματιά στο λινκ της υπογραφής μου (pointers και strings, όχι linked-lists) ... νομίζω θα σε βοηθήσει. 1
lektikos Δημοσ. 15 Νοεμβρίου 2013 Μέλος Δημοσ. 15 Νοεμβρίου 2013 Το 'χω αποθηκεύσει στα αγαπημένα μου. Άρχισα να το διαβάζω πριν λίγες ημέρες.Εξαιρετική δουλειά! Ευχαριστώ πολύ για τις επισημάνσεις. 1
migf1 Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 Παρακαλώ, καλή συνέχεια (ευχαριστώ και για τα καλά σου λόγια). 1
georgemarios Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 Να προσθεσω και εγω κατι Το NULL δεν ειναι δεικτης, ειναι ενα define το οποιο 99.99% εχει τη τιμη 0 Ετσι οταν λες p != NULL, τσεκαρεις αν ο δεικτης p εχει τη τιμη 0, δηλαδη "δειχνει" στη θεση μνημης 0, δηλαδη πουθενα. οταν λες *p !=NULL, τσεκαρεις αν στη θεση μνημης που δειχνει ο p (οποια ειναι αυτη) υπαρχει καταχωρημενη η τιμη 0 οποτε, για τον compiler το 2ο δεν ειναι λαθος, νοηματικα ομως ειναι γιατι συγκρινει ανομοια πραγματα (σαν να συγκρινει την ηλικια με το υψος του ενα πραγμα)
imitheos Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 Να προσθεσω και εγω κατι Το NULL δεν ειναι δεικτης, ειναι ενα define το οποιο 99.99% εχει τη τιμη 0 Ετσι οταν λες p != NULL, τσεκαρεις αν ο δεικτης p εχει τη τιμη 0, δηλαδη "δειχνει" στη θεση μνημης 0, δηλαδη πουθενα. οταν λες *p !=NULL, τσεκαρεις αν στη θεση μνημης που δειχνει ο p (οποια ειναι αυτη) υπαρχει καταχωρημενη η τιμη 0 οποτε, για τον compiler το 2ο δεν ειναι λαθος, νοηματικα ομως ειναι γιατι συγκρινει ανομοια πραγματα (σαν να συγκρινει την ηλικια με το υψος του ενα πραγμα) προειδοποίηση: comparison between pointer and integer [enabled by default] if (*p != NULL) ^ Σε C++ είναι όπως το λες. Σε C οι περισσότερες υλοποιήσεις ορίζουν το NULL ως (void *)0 ακριβώς επειδή το νόημα του είναι για δείκτη οπότε δεν ισχύει αυτό που λες (ότι δηλαδή κάνεις απλά σύγκριση με το 0). Επίσης δεν συγκρίνεις με κάποια "θέση μνήμης 0". Το 0 είναι συμβολικό και ισοδυναμεί με οτιδήποτε σημαίνει "null δείκτης" για την αρχιτεκτονική (στις περισσότερες όντως 0). Ας μην τον μπερδέψουμε παραπάνω όμως με τεχνικά θέματα.
Star_Light Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 @georgemarios Κάθε μεταγλωτιστής μπορει να αναπαραστήσει τους δεικτες NULL με διαφορετικό τρόπο και δεν χρησιμοποιούν ολοι μια μηδενική διεύθυνση.Για παράδειγμα κάποιοι μεταγλωτιστές χρησιμοποιούν μη υπαρκτές διευθύνσεις για τον null οποτε με αυτο τον τρόπο η απόπειρα προσβασης μνήμης μεσω ενος null δεικτη μπορει να ανιχνευθει απο το υλικό. Επισης οταν χρησιμοποιούμε το 0 σε περιεχόμενο που ενας δεικτης απαιτειται οι μεταγλωτιστές το αντιμετωπίζουν σαν έναν null δεικτη αντι για έναν ακέραιο 0. Η NULL μακροεντολή παρέχεται απλά για την αποφυγή σύγχυσης η εκχώρηση p=0; θα μπορούσε να εκχωρήσει την τιμή 0 σε μια αριθμητική μεταβλητή ή εναν null σε μια μεταβλητή δείκτη αντιθετα η εκχώρηση p=NULL; κανει ξεκάθαρο οτι p ειναι ένας δείκτης.
georgemarios Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 Δεν διαφωνω, αλλου εστιασα. My point is, το NULL ειναι νουμερο (τουλ στην προκειμενη περιπτωση) και γιαυτο το *p != NULL δεν του κλωτσαει γιατι ουσιαστικα ισοδυναμει με *p != 0 Αντιθέτως, το *p != ((void*)0) δεν θα του εκανε καν compile
Star_Light Δημοσ. 15 Νοεμβρίου 2013 Δημοσ. 15 Νοεμβρίου 2013 Δεν διαφωνω, αλλου εστιασα. My point is, το NULL ειναι νουμερο (τουλ στην προκειμενη περιπτωση) και γιαυτο το *p != NULL δεν του κλωτσαει γιατι ουσιαστικα ισοδυναμει με *p != 0 Αντιθέτως, το *p != ((void*)0) δεν θα του εκανε καν compile Εμενα μου δινει warning αυτο που γράφεις. Το γεγονος οτι ο NULL αντιπροσωπευεται απο το 0 δεν πρεπει νομιζω να μας μπερδεύει. Στην προκειμενη περιπτωση εχεις ελεγχο μεταξυ ενος στοιχειου και ενος δεικτη. Ο NULL ειναι δεικτης το *p δεν ειναι επομενως δεν πρεπει να συγχέονται σε μια έκφραση. Εκεινο που ειναι ιδιο ειναι οτι στην C οι δείκτες ελέγχονται σαν αληθείς ή ψευδεις με τον ίδιο τροπο που ελέγχονται και οι αριθμοί.Ο έλεγχος όλων των μή NULL δεικτών ειναι TRUE ενώ μονο οι NULL ειναι FALSE. Για αυτο το λογο μια if ή ενας while-for που θα αποτιμηθουν σε NULL δινουν FALSE. Αλλα αυτο δεν εχει σχεση με την συγκριση ενος δεικτη και ενος στοιχειου. Προχθες καπως ετσι την πατησα με την κληση μιας συνάρτησης που επαιρνε διπλο δεικτη σαν ορισμα και επειδη η τιμη του δεικτη ηταν NULL νομιζα οτι θα περάσει &NULL.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα