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

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

Δημοσ.

παιδιά καλησπέρα.. πως μπορώ να χρησιμοποιήσω το ίδιο πρόγραμμα αλλα να εισάγω με scanf τις λέξεις και όχι απο την main?

Δημοσ.

παιδιά καλησπέρα.. πως μπορώ να χρησιμοποιήσω το ίδιο πρόγραμμα αλλα να εισάγω με scanf τις λέξεις και όχι απο την main?

 

Καλημέρα,

 

τι κώδικα έχεις προσπαθήσει να γράψεις μέχρι στιγμής και σε ποιο σημείο έχεις κολλήσει;

Δημοσ.

Χαίρετε. Διαβάζοντας τον κώδικα που παρέθεσε ο migf1 δεν καταλαβαίνω γιατί στο κώδικα εκχωρεί με τύπο δεδομένων unsigned short int τις μεταβλητές i και wlast σε OU. Όπως και να ‘χει μπράβο σε όσους παραθέτουν καλογραμμένο και ευανάγνωστο κώδικα. Καλή συνέχεια σε όλους.

Δημοσ.

Χαίρετε. Διαβάζοντας τον κώδικα που παρέθεσε ο migf1 δεν καταλαβαίνω γιατί στο κώδικα εκχωρεί με τύπο δεδομένων unsigned short int τις μεταβλητές i και wlast σε OU. Όπως και να ‘χει μπράβο σε όσους παραθέτουν καλογραμμένο και ευανάγνωστο κώδικα. Καλή συνέχεια σε όλους.

 

Χαίρεται, κι ευχαριστώ για τα καλά λόγια (αν δλδ συμπεριλαμβάνεις και μένα σε αυτά :) ).

 

Χρησιμοποίησα unsigned για να γίνεται εμφανές εξαρχής πως δεν προορίζονται να έχουν αρνητικές τιμές αυτές οι μεταβλητές. To short ομοίως για να φαίνεται πως δεν προορίζονται για τιμές μεγαλύτερες των 2 bytes.

Δημοσ.

Το U (Unsigned) δίπλα στο 0 ήταν το σημείο που με μπέρδεψε. Ευχαριστώ πολύ για την απάντηση.

Δημοσ.

Το U (Unsigned) δίπλα στο 0 ήταν το σημείο που με μπέρδεψε. Ευχαριστώ πολύ για την απάντηση.

Α οκ, αν και κατά κανόνα είναι περιττό μιας και γίνεται implicitly casted. Κάνει όμως πιο προφανή οπτικά την πρόθεση.

Δημοσ.

Το U (Unsigned) δίπλα στο 0 ήταν το σημείο που με μπέρδεψε. Ευχαριστώ πολύ για την απάντηση.

Α οκ, αν και κατά κανόνα είναι περιττό μιας και γίνεται implicitly casted. Κάνει όμως πιο προφανή οπτικά την πρόθεση.

Γενικά είναι όπως το λέει ο migf1 δηλαδή δείχνει την πρόθεση οπότε κάνει πιο ευανάγνωστο τον κώδικα. Αν όμως σκοπεύεις κάπου να χρησιμοποιήσεις bitwise τελεστές τότε καλό είναι σε κάθε σταθερά να ορίζεις τι πρόθεση έχεις γιατί μπορεί υπό συνθήκες να έχει διαφορά στο αποτέλεσμα.

 

#include <stdio.h>

int main(void)
{
	long a, b;
	unsigned long c, d;

	a = ~0;
	b = ~0U;
	c = ~0;
	d = ~0U;
	/* se 32bit to sosto format 8a itan %d(%08x) */
	printf("a=%ld(%016lx) - b=%ld(%016lx)\n",a,a,b,;
	printf("c=%lu(%016lx) - d=%lu(%016lx)\n",c,c,d,d);

	return 0;
}
32bit

% gcc -Wall -m32 tmp.c 
% ./a.out 
a=-1(ffffffff) - b=-1(ffffffff)
c=4294967295(ffffffff) - d=4294967295(ffffffff)

64bit (LP64 μοντέλο όπως Linux, *BSD, κτλ)

% gcc -Wall tmp.c     
% ./a.out 
a=-1(ffffffffffffffff) - b=4294967295(00000000ffffffff)
c=18446744073709551615(ffffffffffffffff) - d=4294967295(00000000ffffffff)
Καταρχήν μια σταθερά (εκτός αν εκφράζεται σε δεκαεξαδική μορφή) θεωρείται πάντα int εκτός αν δεν χωράει στο εύρος του int. Το 0 χωράει οπότε οπουδήποτε στον κώδικά μας έχουμε σκέτο 0 αυτό έχει τύπο int. Έτσι όταν χρησιμοποιείς το Bitwise Not αλλάζεις σε 1 τόσα bit όσα έχει ο τύπος int. Σε μια κλασική 32bit πλατφόρμα, οι τύποι int (που είπαμε ότι έχει η σταθερά 0) και long (που είναι οι μεταβλητές a και b ) έχουν ίδιο μέγεθος οπότε δεν βλέπουμε διαφορά μεταξύ του ~0 και ~0U. Ότι δίνει το printf στην a δίνει και στην b και όμοια για unsigned στις c και d.

 

Αν όμως θέλουμε να αποθηκεύσουμε το αποτέλεσμα σε τύπο με μεγαλύτερο εύρος από τον int τότε τι θα γίνει με τα περισσευούμενα bits ?

 

Στην περίπτωση της μεταβλητής a έχουμε ~0 οπότε είπαμε ότι έχουμε int δηλαδή τύπο με πρόσημο και έχουμε αρνητική τιμή. Επειδή λοιπόν έχουμε αρνητική τιμή θα γίνει sign extend δηλαδή στο αρχικό -1 των 32bit (0xFFFFFFFF) θα συμπληρωθούν παντού άσοι και αυτό θα γίνει -1 των 64bit (0xFFFFFFFFFFFFFFFF) όπως βλέπουμε και από το printf.

 

Ας δούμε τώρα την περίπτωση του 0U που έχουμε στην μεταβλητή b. Αφού υπολογιστεί το Bitwise Not θα έχουμε και πάλι τα ίδια ακριβώς bit αλλά ο compiler ξέρει ότι δεν έχεις πρόσημο οπότε δεν γίνεται sign extend και όσα παραπάνω bit έχεις θα έχουν μηδενική τιμή. Για αυτό το λόγο στη τιμή 4294967295 των 32bit (0xffffffff) συμπληρώνονται παντού μηδενικά και γίνεται 4294967295 των 64bit (0x00000000ffffffff).

 

Έτσι ο ίδιος ακριβώς κώδικας δίνει διαφορετικό αποτέλεσμα για τη σκέτη σταθερά 0 σε σχέση με την 0U (για αυτό το λόγο σε μερικά προγράμματα βλέπεις να έχουν γράψει 0LL ή 0ULL δηλαδή unsigned long long που είναι ο μεγαλύτερος τύπος που υποστηρίζεται ώστε να είναι καλυμμένη η ανάθεση σε οποιοδήποτε τύπο).

Δημοσ.

Καλημέρα. Η τεκμηρίωση του κώδικα είναι πολύ καλή και χρήσιμη συνήθεια για τους ανθρώπους που διαβάζουν κώδικα. Επίσης συνεισφέρει στην μάθηση και βοηθά στην βαθύτερη κατανόηση του σχολιασμένου κώδικα.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...