Προς το περιεχόμενο

Απορία με τύπους δεδομένων σε συνθήκες


johnykim

Προτεινόμενες αναρτήσεις

Δημοσ.

Γεια σας παιδιά.

 

Έχω ένα πρόβλημα στην γλώσσα 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.Γιατί συμβαίνει αυτό;

Δημοσ.

ποιο compiler χρησιμοποιείς?

τι λειτουργικό?

 

δώσε ένα πρόγραμμα ολοκληρωμένο με το πρόβλημα που αναφέρεις ότι

αντιμετωπίζεις γιατί το λάθος σου είναι κάπου αλλού.

Δημοσ.

Έλεγξε πώς ορίζεις το x και σε τι τιμή το αρχικοποιείς.

Πιθανόν αρχικοποιείται λάθος ή καθόλου οπότε δεν έχει την τιμή που νομίζεις.

Στο σημείο όπου εκτελείται η συνθήκη βάλε ένα brekapoint ή τύπωσε το x για να δεις τη τιμή έχει.

Δεν είναι σοβαρό λάθος...

Δημοσ.

>
#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.

Δημοσ.

scanf("%ld", &x);

 

Για μεταβλητές τύπου long, να χρησιμοποιείς το %ld στις printf/scanf. Και όταν ορίζεις τη main, βάλε και return type (int main()), δε βλάπτει :).

Δημοσ.

@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αλή επιτυχία.

Δημοσ.

@jstark και V.I.Smirnov, ευχαριστώ!

 

Δηλαδή αν δήλωνα scanf("%lf",&x); , θα διάβαζε πραγματικό με μέγεθος long(-2147483648 έως 2147483647);

Δημοσ.

@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 κλπ) που βάζεις δείχνουν πώς θέλεις να ερμηνευτούν οι χαρακτήρες που διαβάζει.

Δημοσ.

Σας ευχαριστώ παιδιά! Εντάξει τα κατάλαβα.:-)

 

@V.I.Smirnov, είσαι πολύ αναλυτικός στις απαντήσεις σου,ευχαριστώ:-) ...αλλά johnykim με λένε...:P

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...