Stuff Δημοσ. 14 Νοεμβρίου 2003 Δημοσ. 14 Νοεμβρίου 2003 Sorry re paidia alla exo mia erotisi se C... kai epeidi den tin katexo ti C tha ithela ti voitheia sas. Loipon: ------------------------------------------------------------------------------------- Tha ithela mia perigrafi ti ginetai se afto to programma - Ti simvainei an treksoume to parakato C programma se ena computer opou apokthikevei short int values se 8-bits kai int values se 16-bits. short int i; int j = 280; for (i=0; i < j; i++) printf("Hello World"); -------------------------------------------------------------------------------------
Darkchild Δημοσ. 14 Νοεμβρίου 2003 Δημοσ. 14 Νοεμβρίου 2003 Arxika orizeis enan akeraio i mikrou megethous kai enan akeraio j iso me 280. Meta ekteleitai h for pou epanalamvanei thn entolh printf 280 fores. Entos ths for orizeis arxika to i=0 kai gia i= 0 mexri i=279 (i<280) ekteleitai h for. kathe fora pou ekteleitai h for to i auksanetai kata 1 monada. H ekfrasi i++ einai idia me thn i=i+1
HdkiLLeR Δημοσ. 15 Νοεμβρίου 2003 Δημοσ. 15 Νοεμβρίου 2003 Πολύ ωραία τα αναφέρει ο φίλος παραπάνω μα με τον συγκεκριμένο κώδικά θα υπάρξει πρόβλημα εάν o i αποθηκεύεται σε έναν υπολογιστή με εσωτερική αναπαράσταση 8 bit και το j με 16. Εάν έχουμε 8 bit για την αναπαράσταση ενός ακεραίου τύπου short ο οποίος είναι προσημασμένος τότε το εύρος τιμών του αριθμού αυτου(δεδομένου πως ο υπολογιστής χρησιμοποιεί εσωτερικά παράσταση συμπληρώματος ως προς 2) είναι : [-128,127]. Στο τμήμα κώδικά: >for (i=0; i < j; i++) To i παίρνει αρχική τιμή 0(i=0) ή οποία είναι επιτρεπτή αφού ανήκει μέσα στο πεδίο τιμών [-128,127]. H τιμή αυτή θα αυξάνεται σε κάθε επανάληψη του for κατά 1, μέχρι να γίνει i=j=280(που υποτίθεται πως πρέπει να σταματήσει). Το πρόβλημα είναι όμως πως το i δεν θα πάρει ποτέ την τιμή 280 αφού η max θετική τιμή που μπορεί να πάρει είναι +127. Συνεπώς θα συμβεί υπερχείλιση(overflow) και το συγκεκριμένο τμήμα κώδικα που είναι μέσα στο for θα εκτελείται επ' άπειρον μιας και μετά την υπερχειλίση, όταν δηλαδή i=127+1 το i θα γίνει ίσο με (1000000 binary = -128 dec). Και θα συνεχίσει να αυξάνεται πάλι κατά ένα μέχρι να ξαναγίνει υπερχείλιση και πάλι το ίδιο μετά... λόγο του ότι ποτέ δεν θα πάρει την τιμή 280 προκειμένου να σταματήσει η επανάληψη
Stuff Δημοσ. 15 Νοεμβρίου 2003 Μέλος Δημοσ. 15 Νοεμβρίου 2003 i grammi tou kodika printf("Hello World"); den tha ektelestei pote?
Typhoon Δημοσ. 15 Νοεμβρίου 2003 Δημοσ. 15 Νοεμβρίου 2003 Note: Δεν κάνει increment το i οπότε θα παγιδευτεί στο loop.
HdkiLLeR Δημοσ. 15 Νοεμβρίου 2003 Δημοσ. 15 Νοεμβρίου 2003 i grammi tou kodika printf("Hello World"); den tha ektelestei pote? Βασικά δεν ξέρω εάν έγινα κατανοητός με το παραπάνω Post μα αναφέρω ξεκάραθα πως λόγο του ότι το i είναι 8bit μεταβλητή δεν πρόκειται ποτέ να φτάσει στο 280 οπότε να σταματήσει η επανάληψη. Εάν δεν υπήρχε πρόβλημα ο κώδικας printf("Hello World") θα τυπωνότανε 280 φορές. Λόγο του προβλήματος που υπάρχει(overfolw) γίνεται υπερχείλιση της μεταβλητής i. Αρχίζει απο το 0 δηλαδή μετά γίνεται i++ οπότε γίνεται 1, στην επόμενη επανάληψη 2 κλπ κλπ μέχρι να γίνει 127 όταν γίνει 127+1 θα συμβεί υπερχείλιση μιας και η τιμή +128 δεν μπορεί να αναπαρασταθεί με 8bit προσημασμένο ακέραιο. Όταν συμβαίνει υπερχείλιση η τιμή που θα πάρει το i είναι -128. Συνεπώς τι θα γίνει με τον κώδικα είναι απλο, αρχικά τυπώνονται 127 φορές Hello World, στην συνέχεια γίνεται υπερχειλίσει και το i=-128 οπότε -128<280 και θα ξανατυπωθούν άλλα 255 Hello World(μέρχι το -128 να γίνει +127 αφού σε κάθε επανάλληψη θα αυξάνεται κατά 1) και μετά θα ξανασυμβεί το ίδιο και μετά πάλι το ίδιο αφού κάθε φορά που το i θα φτάνει στο +128 θα γίνεται υπερχείλιση. Συνεπώς το τμήμα κώδικα printf("Hello World"); θα εκτελείται ΕΠ ΑΠΕΙΡΟΝ. Typhoon: Note: Δεν κάνει increment το i οπότε θα παγιδευτεί στο loop. To i αυξάνεται κανονικότατα μέσα στο loop, η δομή for() έχει την σύνταξη for(μεταβλητή=αρχική_τιμή , συνθήκη_επανάλληψης, αύξηση) συνεπώς εφ'όσον έχουμε for(i=0; i<j ,i++) στο τέλος κάθε επανάλληψης θα έχουμε αύξηση του ι κατά 1. Η ισοδύναμη έκφραση σε while είναι: > i=0; while(i<j) { ... i++; } και είναι ακριβώς το ίδιο πράγμα με την for(i=0; i<j,i++) οπότε δεν τίθεται θέμα αύξησης του i. To πρόβλημα που παγιδεύεται μέσα στο loop είναι λόγο της υπερχείλισης που συμβαίνει.
nodreams.ct Δημοσ. 15 Νοεμβρίου 2003 Δημοσ. 15 Νοεμβρίου 2003 Έχει απόλυτο δίκιο ο HdkiLLeR. Στην υπερχείληση οι τιμές τις μεταβλητής κάνουν κύκλο. Δηλαδή π.χ. σε προσημασμένη (με πρόσημο δλδ) αναπαράσταση με κώδικα συμπληρώματος ως προς 2 με κ ψηφία αναπαράστασης αναπαρίστανται οι αριθμοί μέσα στο διάστημα [-2^(κ-1) , 2^(κ-1) - 1]. Όταν προσπαθήσεις να κανεις την πράξη (2^κ-1) + 1 θα συμβεί υπερχείλιση και η πράξη θα δώσει λανθασμένο αποτέλεσμα -2^(κ-1). Αναλυτικά: Συμπλήρωμα ως προς 2 Αν ο αριθμός είναι θετικός τότε η αναπαράσταση είναι η συνήθης δυαδική. Αν ο αριθμός έιναι αρνητικός αντιστρέφουμε κάθε ψηφίο της δυαδικης αναπαράστασης και προσθέτουμε 1. Σε κ bits o κώδικας μπορεί να αναπαραστήσει ποσότητες στο διάστημα [-2^(κ-1) , 2^(κ-1) - 1] π.χ. για 8 bits αναπαράσταση που έχει ο φίλος μας αναπαριστά αρθμούς στο [-128,127] Σύμφωνα με τον κώδικα η ελάχιστη τιμή είναι η 10000000 (-128) και η μέγιστη 01111111 (127). Όταν πας λοιπόν να κάνεις την πράξη "01111111 + 1" (δηλαδή την "127 + 1" στο δεκαδικό) συμβαίνει το εξής: 01111111 00000001+ ________ 10000000 το 10000000 όμως είναι το -128 στον κώδικά μας!
HdkiLLeR Δημοσ. 16 Νοεμβρίου 2003 Δημοσ. 16 Νοεμβρίου 2003 Αυτά που αναφέρει παραπάνω ο φίλος είναι ακριβώς το πώς λειτουργεί η υπερχέιλιση, Μια μικρή διόρθωση μόνο... Σύμφωνα με τον κώδικα η ελάχιστη τιμή είναι η 10000000 (-127) και η μέγιστη 01111111 (128). Προφανώς ο nodreams.ct ήθελε να πεί η ελάχιστη τιμή είναι η 10000000 (-128) και η μέγιστη 01111111 (127).
nodreams.ct Δημοσ. 16 Νοεμβρίου 2003 Δημοσ. 16 Νοεμβρίου 2003 Ναι αυτό ήθελα να γράψω, το διόρθωσα. Ο δαίμων του πληκτρολογίου!
philippas Δημοσ. 23 Νοεμβρίου 2003 Δημοσ. 23 Νοεμβρίου 2003 Paidia o kodikas einai mia xara. to range tou short int 16-bit kai tou int einai 32 bit. Opote den ginetai overflow sti sigekrimeni periptosi. gia na deis ti ginetai otan ginetai overflow ftiakse ena project sto VStudio kai kane paste ton parakato kodika: >#include <stdio.h> int main(void) { short int i; //to max einai 32767 int j = 32768; for (i=32766; i < j; i++) printf("Hello World\n"); return 0; } Tora vale ena breakpoint (deksi klik->insert breakpoint) sti grammi me to for() kai trekse to debuger kai kane step into (F10).
philippas Δημοσ. 23 Νοεμβρίου 2003 Δημοσ. 23 Νοεμβρίου 2003 a ok diavaza ta upolipa posts kai ksexasa oti eipe oti den exei tin C. Pantos o kodikas den vgazei overflow kai ektiponei stin othonei 280 fores to hello world.
nodreams.ct Δημοσ. 23 Νοεμβρίου 2003 Δημοσ. 23 Νοεμβρίου 2003 Άλλο έλεγα να διαβάσεις. Αυτό: "Ti simvainei an treksoume to parakato C programma se ena computer opou apokthikevei short int values se 8-bits kai int values se 16-bits."
Stuff Δημοσ. 24 Νοεμβρίου 2003 Μέλος Δημοσ. 24 Νοεμβρίου 2003 Telika isxeioun ola ta proigoumena posts etsi?
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.