johnykim Δημοσ. 24 Απριλίου 2010 Δημοσ. 24 Απριλίου 2010 Γεια σας παιδιά. Έχω ένα πρόβλημα στην γλώσσα C.Τα αποτελέσματα σε μια if ή σε While δεν βγαίνουν σωστά με τις αντίστοιχες συνθήκες.. Για παράδειγμα: > if (x>5) { printf("\nto x einai megalytero tou 5\n"); } else { printf("\nto x einai mikrotero h iso tou 5\n"); } Όταν η μεταβλητή που είναι στην συνθήκη(το χ στην προκειμένη περίπτωση), είναι long ή double ,βγάζει μόνο την πρώτη εντολή ό,τι και να δώσω.Αν βάλω όμως int ή float, τότε όλα ok.Γιατί συμβαίνει αυτό;
virxen75 Δημοσ. 24 Απριλίου 2010 Δημοσ. 24 Απριλίου 2010 ποιο compiler χρησιμοποιείς? τι λειτουργικό? δώσε ένα πρόγραμμα ολοκληρωμένο με το πρόβλημα που αναφέρεις ότι αντιμετωπίζεις γιατί το λάθος σου είναι κάπου αλλού.
V.I.Smirnov Δημοσ. 24 Απριλίου 2010 Δημοσ. 24 Απριλίου 2010 Έλεγξε πώς ορίζεις το x και σε τι τιμή το αρχικοποιείς. Πιθανόν αρχικοποιείται λάθος ή καθόλου οπότε δεν έχει την τιμή που νομίζεις. Στο σημείο όπου εκτελείται η συνθήκη βάλε ένα brekapoint ή τύπωσε το x για να δεις τη τιμή έχει. Δεν είναι σοβαρό λάθος...
nikolaos_ Δημοσ. 24 Απριλίου 2010 Δημοσ. 24 Απριλίου 2010 Πιθανόν είναι παραξενιά του compiler. Όταν έχεις double γράφε if(x>5.00) καλύτερα.
johnykim Δημοσ. 24 Απριλίου 2010 Μέλος Δημοσ. 24 Απριλίου 2010 > #include <stdio.h> #include <stdlib.h> #include <math.h> main() { long x; printf("dwse timh gia to x\n"); scanf("%l",&x); if (x>5) { printf("\nto x einai megalytero tou 5\n"); } else { printf("\nto x einai mikrotero h iso tou 5\n"); } printf("\n"); system("PAUSE"); return 0; } Είμαι σε Win7 x64 και χρησιμοποιώ την Dev-C++. @V.I.Smirnov,την τιμή την δίνω εγώ από το πληκτρολόγιο. @nikolaos_, έχω δοκιμάσει να βάλω με δεκαδική μορφή την συνθήκη όταν δοκίμασα με double.
jstark Δημοσ. 24 Απριλίου 2010 Δημοσ. 24 Απριλίου 2010 scanf("%ld", &x); Για μεταβλητές τύπου long, να χρησιμοποιείς το %ld στις printf/scanf. Και όταν ορίζεις τη main, βάλε και return type (int main()), δε βλάπτει .
V.I.Smirnov Δημοσ. 25 Απριλίου 2010 Δημοσ. 25 Απριλίου 2010 @johykim Το x δεν λαμβάνει τις τιμές που νομίζεις διότι δεν δίνεις τύπο ορίσματος στη scanf. Η εντολή scanf("%l", &x); είναι ελλιπής. Η scanf έχει την μορφοποίηση %[*][εύρος][μέγεθος][τύπος] (οι αγκύλες σημαίνουν ότι αυτό που περιέχουν είναι προαιρετικό, δεν τις γράφεις στ' αλήθεια) Στο εύρος βάζεις έναν αριθμό που δείχνει πόσοι χαρακτήρες θα διαβαστούν για την τιμή αυτή της μεταβλητής (εδώ του x). Στο μέγεθος βάζεις έναν χαρακτήρα που τροποποιεί το πεδίο τύπου που είναι το αμέσως ακόλουθο. Ο χαρακτήρας αυτός μπορεί να είναι h,l ή L και διαφοροποιεί μεταξύ short και long ή float και double. Το l σημαίνει ότι αυτό που εισάγεις θα ερμηνευτεί ως long ακέραιος αν καθορίσεις να εισαχθεί ακέραιος ή ως double αν καθορίσεις να εισαχθεί πραγματικός. Σωστά το έχεις δώσει l. Σημαίνει ότι ο άριθμός που θα εισάγεις είναι long ή double. Στον τύπο που είναι και το σημαντικότερο πεδίο, βάζεις έναν χαρακτήρα που πληροφορεί την scanf τι τύπος είναι ο χαρακτήρας που θα διαβάσει. Δηλ. αν είναι - πραγματικός θέτεις e,f,g, - ακέραιος θέτεις d, - string θέτεις s κ.α. Εσύ εδώ λαθεμένα δεν έχεις θέσει τίποτε. Δίνοντας l δήλωσες ότι αριθμός που θα εισαχθεί είναι long ή double (αντί short ή float) αλλά δεν δήλωσες τι από τα δύο. Όταν εισάγεις το x ερμηνεύεται τυχαία (προφανώς με αρνητική τιμή) αφού δεν έχει δηλώσει τι τύπος είναι και η συνθήκη δεν εκτελείται με την τιμή που περιμένεις. Το σωστό είναι scanf("%ld", &x); που σημαίνει ότι δίνεις ακέραιο (τέθηκε d) που είναι long (τέθηκε l). Kαλή επιτυχία.
johnykim Δημοσ. 25 Απριλίου 2010 Μέλος Δημοσ. 25 Απριλίου 2010 @jstark και V.I.Smirnov, ευχαριστώ! Δηλαδή αν δήλωνα scanf("%lf",&x); , θα διάβαζε πραγματικό με μέγεθος long(-2147483648 έως 2147483647);
Evgenios1 Δημοσ. 25 Απριλίου 2010 Δημοσ. 25 Απριλίου 2010 @jstark και V.I.Smirnov, ευχαριστώ! Δηλαδή αν δήλωνα scanf("%lf",&x); , θα διάβαζε πραγματικό με μέγεθος long(-2147483648 έως 2147483647); http://en.wikipedia.org/wiki/Scanf τσεκαρε εκει που λεει "Format string* specifications". *Δεν διαβαζεις, αλλα μετατρεπεις.
V.I.Smirnov Δημοσ. 25 Απριλίου 2010 Δημοσ. 25 Απριλίου 2010 @johykim Η πλήρης ανάλυση της scanf είναι πολύπλοκη διότι έχει πολλές παραμέτρους. Γι' αυτό που ρώτησες, αρκεί να θυμάσαι τα εξής. Δυο είναι οι βασικές παράμετροι. (1) Η μια δείχνει το είδος του "αριθμού" που θέλεις να εισάγεις : Μπορεί να είναι ακέραιος, πραγματικός, string, ή/και παραλλαγές αυτών όπως ακέραιος στο δεκαεξαδικό ή οκταδικό σύστημα, πραγματικός σε εκθετική μορφή κλπ. Κάθε μια από αυτές τις περιπτώσεις δηλώνεται με ένα ιδιαίτερο σύμβολο. Π.χ. για ακεραίους είναι το d, για πραγματικούς είναι το f, για sτring το s. Εσύ θέλεις να εισάγεις ακέραιο, συνεπώς θέτεις d. (2) Δεν αρκεί όμως αυτό. Κάθε τύπος υπάρχει σε πολλά μεγέθη και πρέπει να καθορίσεις ποιο θα είναι το "μέγεθός" του από τα διαθέσιμα που μπορεί να έχει. Π.χ. ένας ακέραιος μπορεί να είναι short ή long. Ένας πραγματικός μπορεί να είναι float ή double. Eσύ δίνοντας d καθορίζεις ότι θα εισαχθεί ακέραιος. Πρέπει όμως επίσης να καθορίσεις αν θα είναι short ή long. Αυτό το κάνεις θέτοντας l μπροστά από το d. To ld σημαίνει ότι θα εισαχθεί ακέραιος (d) που θα είναι long. Aν ήθελες ακέραιο int θα ήταν απλά d. Aν ήθελες ακέραιο short θα ήταν hd. Εξάλλου, αν ήθελες να εισάγεις πραγματικό double, θα έγραφες f και θα έθετες μπροστά l, δηλ. lf. Aν ήθελες πραγματικό float θα ήταν απλά f. Για ακέραιους το l σημαίνει ότι θα είναι long, για πραγματικούς ότι θα είναι double. Αν δεν το βάλεις θα είναι απλός int ή float αντίστοιχα. To μέγεθος είναι προαιρετικό και όταν γράφεται τίθεται πριν από τον τύπο.Π.χ. παρατήρησε ότι γράφεται πρώτα τo "μέγεθος" (το l ή h) και μετά ο "τύπος" (εδώ το d). Να θυμάσαι και κάτι άλλο : η scanf απλώς διαβάζει χαρακτήρες. Π.χ. το "12345" μπορεί να είναι ακέραιος, πραγματικός, ακέραιος στο οκταδικό ή δεκαεξαδικό σύστημα, string κλπ Οι σημάνσεις (d,f,g,e,ο, l,h κλπ) που βάζεις δείχνουν πώς θέλεις να ερμηνευτούν οι χαρακτήρες που διαβάζει.
johnykim Δημοσ. 27 Απριλίου 2010 Μέλος Δημοσ. 27 Απριλίου 2010 Σας ευχαριστώ παιδιά! Εντάξει τα κατάλαβα. @V.I.Smirnov, είσαι πολύ αναλυτικός στις απαντήσεις σου,ευχαριστώ ...αλλά johnykim με λένε...
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.