imitheos Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Αν δεν απατώμαι, το στάνταρ έχει αλλάξει και το sizeof(char) δεν περιγράφεται πλέον ως guaranteed equal to 1 byte, αλλά ως guaranteed equal to 1 unit... με το "unit" ορισμένο ώς το μικρότερο δυνατό μέγεθος απεικόνισης, όχι απαραίτητα όμως σε LL... ή κάπως έτσι τέλος πάντων. Ψάξτο αν σε ενδιαφέρει, πρέπει να είναι στο C99 αν δεν κάνω λάθος (αν το βρεις βάλε και ένα link να το έχουμε πρόχειρο ) Βαριέμαι να ψάξω ολόκληρο το πρότυπο Στην παράγραφο πάντως που περιγράφει τον sizeof τελεστή και τα τρία πρότυπα αναφέρουν το παρακάτω. The sizeof operator yields the size (in bytes) of its operand. blah blah. When applied to an operand that has type char, unsigned char, or signed char, the result is 1.
migf1 Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Βρήκα αυτό, με ένα γρήγορο googling: http://stackoverflow.com/questions/2215445/are-there-machines-where-sizeofchar-1 Ο χαμός του χαμού. Όντως λένε πως sizeof(char) == 1 αλλά επίσης λένε πως ο sizeof operator επιστρέφει πάντα πλήθος bytes... πιάσε το αυγό και κούρευ' το Νομίζω ο κώδικάς μου δουλεύει ότι και να ισχύει (δεν είμαι σίγουρος όμως, πρέπει να τον ξανακοιτάξω). EDIT: Δίνουν κι αυτά τα 2 links 1. http://c-faq.com/charstring/wchar.html 2. http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.6 (C++, αλλά πρέπει να είναι ίδιο και για C λένε). Θα τα κοιτάξω κάποια στιγμή (μάλλον όταν πραγματικά το χρειαστώ).
imitheos Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Ναι αυτό που λένε ισχύει αλλά είναι διαφορετικό. Μπορεί κάποιος να υλοποιεί το char με όσα bit ( > 8 ) θέλει αλλά το sizeof(char) θα είναι και πάλι 1. Πχ υπάρχουν DSP που έχουν 16bit ή 32bit char και είναι ίδιο μέγεθος με τον int (οπότε και sizeof(int) είναι 1). Σημειοτέον ότι το πρότυπο ορίζει μόνο τιμές. Ενώ ο char θα είναι 16bit μπορεί πάλι να έχει μέγιστη τιμή το 127. Συνήθως αυτές οι υλοποιήσεις που char == int είναι freestanding αλλιώς θα γινόταν χαμός με τις standard συναρτήσεις. Το βάζω σε spoiler για να μη φεύγουμε εκτός θέματος και χαλάμε το thread. Με λίγα λόγια το sizeof(char) δεν χρειάζεται να μπαίνει.
migf1 Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Εντός θέματος είμαστε βρε συ (ερωτήσεις για C είναι ο τίτλος). Οπότε ο μόνος τρόπος να βρούμε πραγματικά σε πόσα bytes αντιστοιχεί ο char είναι με το CHAR_BIT macro;
imitheos Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Εντός θέματος είμαστε βρε συ (ερωτήσεις για C είναι ο τίτλος). Οπότε ο μόνος τρόπος να βρούμε πραγματικά σε πόσα bytes αντιστοιχεί ο char είναι με το CHAR_BIT macro; Ναι αλλά μόνο για αυτό χρησιμεύει (συνήθως για bit shifting και τέτοιες δουλειές). Για να βρεις τις τιμές που μπορεί να αναπαραστήσει ο τύπος πρέπει να χρησιμοποιήσεις τα _MIN, _MAX macros γιατί όπως είπαμε πριν 16bit char δεν σημαίνει απαραίτητα ότι η μέγιστη τιμή του είναι 32767 αλλά μπορεί και πάλι να έχει 127 και τα υπόλοιπα bits να είναι trap.
migf1 Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Nice ΥΓ. Ευτυχώς που η C υποστηρίζει pointer arithmetic από μαμά!
Star_Light Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Παιδια μιας και το θέσατε εχω και εγω 2 ερωτησούλες πανω στους τύπους συγκεκριμενα σε μετατροπές : 1. Σε μια άσκηση έχω δει οτι άν έχουμε int i , long j , unsigned int k η τιμή της παράστασης i+(int) j * k θα ειναι unsigned int. Γιατι ομως? Περα απο τους κανονες για τα implicit conversions ο cast (int) δεν αναγκάζει και το κ να γινει int? ΟΠως σε μια περιπτωση της μορφης -> long i , int j =1000; i= (long) j * j για να αποφυγουμε και το overflow πχ οπου και τα γινονται long . 2. Kαθως διαβαζα τους κανονες μετατροπης (C89) int -> unsigned int -> long int -> unsigned long int η αληθεια ειναι πως δεν βρηκα καποια λογικη... στο ΓΙΑΤΙ γινονται ετσι. Ισως θα υπακουσω και εγω τυφλα στα προτυπα και δεν θα ζαλιστω αλλο... γιατι ενας εγραφε οτι έχεις μετατροπη σε ευρυτερο τυπο πραγμα που δεν ισχυει παρα μονο στην αλλαγη του unsigned int σε long int. Eμενα παντως ο παρακατω κωδικας μου δινει ισα νουμερα για int , unsigned int και long int , unsigned long int. Αρα αυτο το οτι μετατρεπεται στον "narrowest" τυπο που λεει δεν καταλαβαινω τι θελει να πει. Ειναι narrowest αυτος ο οποιος απαιτει λιγοτερα bytes για αποθηκευση. Αφου ισα bytes θελουν. > #include<stdio.h> int main(void) { int a; unsigned int b; long int c; unsigned long int d; printf("%ld , %ld , %ld , %ld " , sizeof a , sizeof b , sizeof c , sizeof d ); return 0; } Ειναι μερικα σημεια στη C πολυ πονοκεφαλος μωρε αδερφακι μου. :/ Υ.Γ Στο μονο που βρισκω μια λογικη ως τωρα ειναι οταν έχουν να μετατραπουν οι floating (αν ενας εκ των 2 τελεστεων ειναι ετσι....) οπου εκει με την μια πας στον ευρυτερο τυπο + οτι αν έχεις εναν unsigned long + float ο unsigned long θα γινει float αλλιως θα στοιχιζε το κλασματικο του μερος.
migf1 Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Παιδια μιας και το θέσατε εχω και εγω 2 ερωτησούλες πανω στους τύπους συγκεκριμενα σε μετατροπές : 1. Σε μια άσκηση έχω δει οτι άν έχουμε int i , long j , unsigned int k η τιμή της παράστασης i+(int) j * k θα ειναι unsigned int. Γιατι ομως? Περα απο τους κανονες για τα implicit conversions ο cast (int) δεν αναγκάζει και το κ να γινει int? ΟΠως σε μια περιπτωση της μορφης -> long i , int j =1000; i= (long) j * j για να αποφυγουμε και το overflow πχ οπου και τα γινονται long . 2. Kαθως διαβαζα τους κανονες μετατροπης (C89) int -> unsigned int -> long int -> unsigned long int η αληθεια ειναι πως δεν βρηκα καποια λογικη... στο ΓΙΑΤΙ γινονται ετσι. Ισως θα υπακουσω και εγω τυφλα στα προτυπα και δεν θα ζαλιστω αλλο... γιατι ενας εγραφε οτι έχεις μετατροπη σε ευρυτερο τυπο πραγμα που δεν ισχυει παρα μονο στην αλλαγη του unsigned int σε long int. Eμενα παντως ο παρακατω κωδικας μου δινει ισα νουμερα για int , unsigned int και long int , unsigned long int. Αρα αυτο το οτι μετατρεπεται στον "narrowest" τυπο που λεει δεν καταλαβαινω τι θελει να πει. Ειναι narrowest αυτος ο οποιος απαιτει λιγοτερα bytes για αποθηκευση. Αφου ισα bytes θελουν. > #include<stdio.h> int main() { int a; unsigned int b; long int c; unsigned long int d; printf("%ld , %ld , %ld , %ld " , sizeof a , sizeof b , sizeof c , sizeof d ); return 0; } Ειναι μερικα σημεια στη C πολυ πονοκεφαλος μωρε αδερφακι μου. :/ Τα implicit conversions βασίζονται στα λεγόμενα "promotion rules" και τα "conversion ranks" (https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules) τα οποία κανείς... γήινος δεν τα θυμάται απ' έξω! Για αυτό όταν δεν είμαστε σίγουροι χρησιμοποιούμε explicit casting. Σε ότι αφορά τα "narrowest" types, το πρότυπο δεν αποκλείει την περίπτωση τα narrower να είναι ίσα με τα wider, διότι εγγυάται μονάχα τα κάτω όριά τους. Αποκλείει όμως κάποιο narrow type να είναι μεγαλύτερο από κάποιο wider. Στο σύστημά σου, κρίνοντας από τα αποτελέσματα που παίρνεις, ο narrower int υλοποιείται με ίδιο μέγεθος με τον wider long.
Timonkaipumpa Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Για αυτό... hex rules (σε συνδυασμό με typedefs, π.χ. uint8 -> unsigned char) τιμή 1 για 8 bit στοιχείο; 0x01 τιμή 10 για 16 bit στοιχείο; 0x000A
migf1 Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Για αυτό... hex rules (σε συνδυασμό με typedefs, π.χ. uint8 -> unsigned char) τιμή 1 για 8 bit στοιχείο; 0x01 τιμή 10 για 16 bit στοιχείο; 0x000A Τα <inttypes.h> ήταν τρομερή προσθήκη στο C99!
Timonkaipumpa Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Τα <inttypes.h> ήταν τρομερή προσθήκη στο C99! Ναι, εάν έχεις χώρο να φορτώνεις .h files Εάν είναι size critical το project (μικρή flash memory, τάξης μερικών kB), τότε τα κάνεις manually (και κόβεις από όπου μπορείς).
Star_Light Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Τα implicit conversions βασίζονται στα λεγόμενα "promotion rules" και τα "conversion ranks" (https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules) τα οποία κανείς... γήινος δεν τα θυμάται απ' έξω! Για αυτό όταν δεν είμαστε σίγουροι χρησιμοποιούμε explicit casting. Σε ότι αφορά τα "narrowest" types, το πρότυπο δεν αποκλείει την περίπτωση τα narrower να είναι ίσα με τα wider, διότι εγγυάται μονάχα τα κάτω όριά τους. Αποκλείει όμως κάποιο narrow type να είναι μεγαλύτερο από κάποιο wider. Στο σύστημά σου, κρίνοντας από τα αποτελέσματα που παίρνεις, ο narrower int υλοποιείται με ίδιο μέγεθος με τον wider long. Ναι βασικα αυτο συμβαινει επειδη δεν μας πειραζει αν ο int ειναι ισος σε bytes με τον unsigned και αρα έχουν ιδιο εύρος τιμών (ιδιο εκθέτη) γιατι δεν προκαλει υπερχειλιση αυτο. Το αντιθετο που λες θα προκαλουσε ομως. Καποιο narrow δηλαδη να ειναι μεγαλυτερο απο καποιο wider.... Δεν προσπαθω να τα μαθω παπαγαλια.. απλα μιας και εκανα τον κοπο και διαβασα αυτους τους κανονες που μου ζαλισαν το κεφαλι ηθελα να καταλαβω το γιατι. EDIT: Άκυρο στους unsigned δεν υπάρχει υπερχειλιση λογω modulo 2^n
migf1 Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Ναι, εάν έχεις χώρο να φορτώνεις .h files Εάν είναι size critical το project (μικρή flash memory, τάξης μερικών kB), τότε τα κάνεις manually (και κόβεις από όπου μπορείς). Σε αυτές τις περιπτώσεις δεν τα χρειάζεσαι καθόλου ρε συ, μιας και μιλάμε για platform specific coding. Οπότε όταν ξέρεις πως στην πλατφόρμα σου είναι π.χ. ο char 1 byte, ο short 2 και ο int 4, κλπ, δεν υπάρχει λόγος να χρησιμοποιήσεις καθόλου το <inttypes.h> ΥΓ. Εκτός αν δεν κατάλαβα σωστά... τι εννοείς "manually" ? Ναι βασικα αυτο συμβαινει επειδη δεν μας πειραζει αν ο int ειναι ισος σε bytes με τον unsigned και αρα έχουν ιδιο εύρος τιμών στον εκθέτη γιατι δεν προκαλει υπερχειλιση αυτο. Το αντιθετο που λες θα προκαλουσε ομως. Καποιο narrow δηλαδη να ειναι μεγαλυτερο απο καποιο wider.... ... Οι signed και οι unsigned είναι πάντα ίσοι σε bytes (ίδιο width δηλαδή), σε οποιονδήποτε τύπο. Μόνο στο arithmetic conversion διαφέρουν, όπου παίρνει προτεραιότητα ο unsigned (αν θυμάμαι σωστά δηλαδή).
Star_Light Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Οι signed και οι unsigned είναι πάντα ίσοι σε bytes (ίδιο width δηλαδή), σε οποιονδήποτε τύπο. Μόνο στο arithmetic conversion διαφέρουν, όπου παίρνει προτεραιότητα ο unsigned (αν θυμάμαι σωστά δηλαδή). Ok. Αρα δεν έχει σημασια αν και αυτο εδω (παρολο που εχει casting που το αναγκαζει σε int) τελικα παράξει unsigned int oλο η τιμη της εκφρασης > i + (int) j * k ;
migf1 Δημοσ. 5 Απριλίου 2012 Δημοσ. 5 Απριλίου 2012 Ok. Αρα δεν έχει σημασια αν και αυτο εδω (παρολο που εχει casting που το αναγκαζει σε int) τελικα παράξει unsigned int oλο η τιμη της εκφρασης > i + (int) j * k ; Αυτό είναι εξαιρετικά σπάνιο να υπάρξει μέσα σε κώδικα, τουλάχιστον όχι χωρίς κάποιο σχόλιο που να εξηγεί τι κάνει και γιατί. Τέτοιοι κώδικες γενικώς είναι παραδείγματα προς αποφυγή.
Προτεινόμενες αναρτήσεις