Τα πάντα για την C

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 25 Φεβ 2012, 16:59

migf1 έγραψε:@StartLight: Κοντά έπεσες :) Αλλά όχι στο 1ο εξάμηνο, στο 3ο... στο 1ο είχαμε ξεκινήσει με Pascal, στο 2ο ξεκινήσαμε C (μαζί με μερικές άλλες... Ada, Modula-2, Lisp) και στο 3ο κάναμε 2-3 άλλες επιφανειακά αλλά κατά βάση συνεχίσαμε με C + Αssembly, με την οποία Assembly είχαμε φτιάξει editor, compiler, assembler, linker και loader μιας απλοποιημένης γλώσσας που έμοιαζε με Pascal.



Καλη φαση ρε συ! Εμας η σχολή μας ειχε πολυ ανεβασμενο επιπεδο στα μαθηματικα
αλλα απο προγραμματισμο έπασχε σοβαρα. Την αλλη φορα που εψαχνα για πολυπλοκοτητα
στην Wikipedia και βρηκα κατι λογαριθμους τους καταλαβα αμεσως να φανταστεις δεν χρειαστηκε να
ρωτησω τιποτα ! (Οχι πως πειραζει να κανεις ερωτησεις απλα λεμε τωρα)
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 25 Φεβ 2012, 17:11

A και το '\0' ειναι χαρακτήρας. Τον χρησιμοποιεί η C σαν "flag" για να δειξει το τέλος μιας συμβολοσειρας :PPPPP
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 25 Φεβ 2012, 17:15

Ναι, διαφέρει από την Python... τα διπλά εισαγωγικά δηλώνουν πάντα string ( δηλαδή ειδικοί πίνακες χαρακτήρων, θα τα δεις πιο μετά στο βιβλίο ). Τα μονά εισαγωγικά δηλώνουν πάντα έναν χαρακτήρα. Π.χ. στη C το να γράψεις 'abcd' δίνει λάθος !!!

Για το: ch < '0' τώρα. Βασικά οι compilers τα char τα διαχειρίζονται πάντα ως int, ως δηλαδή τα ακέραια ASCII codes τους... το ίδιο μπορείς να κάνεις και εσύ στα προγράμματά σου. Μπορείς δηλαδή αντί για char να τα δηλώνεις ως int, αλλά για να είσαι συνεπής τότε αντί για '0' θα πρέπει π.χ. να γράφεις 48 (το ASCII code του χαρακτήρα '0').

Βασικά μπορείς να αναμίξεις τους τύπους char και int, καθώς και την απεικόνιση των τιμών τους όπως θέλεις, δεν θα σου βγάλει λάθος o compiler.

Μορφοποιημένος Κώδικας: Επιλογή όλων
char ch1 = 48;  /* ίσο με τον χαρακτήρα '0' */
int ch2 = '1'; /* ίσο με το integer ASCII code 49 */

ch2 = ch1; /* ίσο με τον χαρακτήρα '0' */
ch1 += ch2; /* το ch1 τώρα ισούται με 48 + '0' = 48 + 48 = 96 */

printf( "ch1 as char: %c", ch1 ); /* τυπώνει τον χαρακτήρα του ανάποδου αριστερού εισαγωγικού (άμα δεις το ASCII table, αυτός είναι ο χαρακτήρας με code 96 ) */


Άρα λοιπόν, το ...
Μορφοποιημένος Κώδικας: Επιλογή όλων
ch < '0'

συγκρίνει το ASCII code του ch με το ASCII code του χαρακτήρα '0' (48 είναι το ASCII code).

Θεώρησε πως όλα τα char είναι int, σύμφωνα με το ASCII table. Αν θέλεις να τα διαβάζεις/τυπώνεις ως χαρακτήρες το κάνεις με %c, ενώ αν θέλεις να διαβάζεις/τυπώνεις τα ASCII codes τους το κάνεις με %d. Εσωτερικά τα char αποθηκεύονται & διαχειρίζονται πάντα ως int (ASCII codes) ;)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 25 Φεβ 2012, 17:41

Πολύ ωραία. Τώρα κατάλαβα.

Κάτι ακόμα.
migf1 έγραψε:Επειδή ο τύπος char είναι ορισμένος fixed σε 1 byte μνήμης, το εύρος των έγκυρων τιμών του είναι από 0 έως 255 αν πρόκειται για unsigned char ή από -128 έως 127 αν πρόκειται για signed char (σημείωση: το σκέτο char δεν γνωρίζουμε αν είναι signed ή unsigned ... το στάνταρ το αφήνει στην κρίση του κάθε compiler, συνήθως είναι signed αλλά δεν μπορούμε να το θεωρήσουμε δεδομένο για όλους τους compilers).

Ποια ακριβώς είναι η διαφορά των signed και unsigned char;
Αν κατάλαβα καλά οι unsigned char είναι αυτοί που απεικονίζονται στο ASCII table που έδωσες προηγουμένως. Οι signed;

Edit: Μήπως απλά αλλάζει ο integer ASCII code; Δηλαδή ο unsigned 'A' ισοδυναμεί με 65, και ο signed 'A' με 65 - 128 δηλ. -63;
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό migf1 » 25 Φεβ 2012, 21:22

Ilias95 έγραψε:Ποια ακριβώς είναι η διαφορά των signed και unsigned char;
Αν κατάλαβα καλά οι unsigned char είναι αυτοί που απεικονίζονται στο ASCII table που έδωσες προηγουμένως. Οι signed;

Edit: Μήπως απλά αλλάζει ο integer ASCII code; Δηλαδή ο unsigned 'A' ισοδυναμεί με 65, και ο signed 'A' με 65 - 128 δηλ. -63;

Βασικά ίσως δεν πρέπει να σε μπλέξω από τώρα με αυτά, πιθανότατα να τα καλύπτει πιο κάτω το βιβλίο.

Σε γενικές γραμμές, ο καθένας από τους βασικούς τύπους δεδομένων (char, int, float, double) καταλαμβάνει συγκεκριμένο μέγεθος μνήμης για κάθε μεταβλητή που ορίζουμε τέτοιου τύπου. Το στάνταρ εγγυάται τα ελάχιστα μεγέθη μνήμης για τον κάθε τύπο, αλλά αφήνει ως implementation dependent το ακριβές μέγεθος που τελικά καταλαμβάνει ο κάθε τύπος στην κάθε πλατφόρμα/compiler.

Για παράδειγμα, τα ελάχιστα (εγγυημένα) μεγέθη μνήμης για τους τύπους char και int είναι 1 και 2 bytes αντίστοιχα. Για να δεις όμως ακριβώς πόσα bytes καταλαμβάνει ο κάθε τύπος στο δικό σου σύστημα, μπορείς να χρησιμοποιήσεις τον τελεστή sizeof...

Μορφοποιημένος Κώδικας: Επιλογή όλων
...
printf( "Size of char: %u\n", sizeof(char) );
printf( "Size of int: %u\n", sizeof(int) );
printf( "Size of float: %u\n", sizeof(float) );
printf( "Size of double: %u\n", sizeof(double) );


Αφήνοντας στην άκρη προς το παρόν τους τύπους float και double που αντιπροσωπεύουν αριθμούς κινητής υποδιαστολής (και διαχειρίζονται με διαφορετικό τρόπο εσωτερικά) οι ακέραιοι τύποι (δηλαδή οι char και int) μπορούν να απεικονίζουν είτε αποκλειστικά θετικές τιμές, είτε θετικές και αρνητικές.

Αποκλειστικά θετικές τιμές μπορούν να απεικονίζουν όταν τους χρησιμοποιείς με το πρόθεμα unisgned που σημαίνει χωρίς πρόσημο. Αν τους χρησιμοποιείς με το πρόθεμα signed σημαίνει πως μπορούν να διαχειριστούν και θετικές και αρνητικές τιμές.

Ας πάρουμε τον τύπο int κι ας υποθέσουμε πως στο σύστημά σου καταλαμβάνει 2 bytes μνήμης, την ελάχιστη χωρητικότητα που εγγυάται το στάνταρ (στην πραγματικότητα θα καταλαμβάνει μάλλον 4 bytes, ίσως και 8, διασταύρωσε το στο σύστημά σου με: sizeof(int) ).

Αυτά λοιπόν τα 2 bytes αποτελούνται από 16 bits, μιας και το κάθε byte αποτελείται από 8 bits (αυτό είναι χαρακτηριστικό των υπολογιστών και όχι συγκεκριμένα της C ). Για να μη σε μπλέξω (από τώρα) με endiadness καθώς και τους διαφορετικούς τρόπους εσωτερική απεικόνισης των αρνητικών αριθμών, θα κάνω στη συνέχεια ορισμένες υπερ-απλουστεύσεις, προκειμένου να είναι πιο κατανοητά...

Θεωρώντας πως η σειρά των bits αλλά και των bytes πάει από αριστερά προς τα δεξιά, με τα μεγαλύτερα πρώτα, τα 2 bytes του κάθε int διατάσσονται στη μνήμη κάπως έτσι...

Μορφοποιημένος Κώδικας: Επιλογή όλων
2o byte                 1o byte
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00

Τα bits μπορούν να είναι είτε αναμμένα (1) είτε σβηστά (0) με τα σβηστά να αντιστοιχούν σε μηδενική τιμή.

Άρα λοιπόν, αν ορίσουμε έναν ακέραιο n χωρίς πρόσημο και του αναθέσουμε την τιμή 0...

Μορφοποιημένος Κώδικας: Επιλογή όλων
unsigned int n = 0;

η απεικόνισή του στη μνήμη θα είναι κάπως έτσι...

Μορφοποιημένος Κώδικας: Επιλογή όλων
2o byte                 1o byte
15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Αυτή είναι η περιβόητη δυαδική απεικόνιση (binary representation) που χρησιμοποιούν οι υπολογιστές εσωτερικά για να αποθηκεύουν πληροφορίες.

Ο κάθε αριθμός αναπαριστάνεται ανάβοντας ή/και σβήνοντας bits στις κατάλληλες θέσεις και υπολογίζοντας κατόπιν το συνολικό άθροισμα των δυνάμεων του 2 στις θέσεις που υπάρχουν αναμμένα bits. Η μέγιστη δυνατή τιμή που μπορούν να απεικονίσουν 2 bytes είναι όταν όλα τους τα bits είναι αναμμένα, και άρα ισούται με το εξής άθροισμα...

Μορφοποιημένος Κώδικας: Επιλογή όλων
2^15 + 2^14 + 2^13 + 2^12 + 2^11 + 2^10 + 2^9 + 2^8 + 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 =
32768 + 16383 + 8192 + ... + 4 + 2 + 1 =
65535


Άρα λοιπόν ένας unsigned int στη C μπορεί να διαχειριστεί εγγυημένα από το στάνταρ θετικές τιμές στο εύρος 0 έως 65535 (στα 4 bytes αυτό το όριο ανεβαίνει στα 4,294,967,295 και ούτω κάθε εξής).

έγραψε:
Άλλο ένα παράδειγμα για εμπέδωση του υπολογισμού, ο αριθμός 10 αποθηκευμένος σε δυαδική μορφή, σε 2 bytes (δηλαδή σε 16 bits) ισούται με: 0000000000001010, δηλαδή με: 2^3 + 0 + 2^1 + 0 = 8 + 0 + 2 + 0 = 8 + 2

Όταν όμως ο τύπος int δηλωθεί ως signed int (που είναι το default αν δεν καθορίσουμε τίποτα... αντίθετα το σκέτο char είναι implementation dependent) τότε στην πιο απλή περίπτωση 1 ακριανό bit (από τα συνολικά 16 bits των 2 bytes) χρησιμοποιείται για το πρόσημο.

Αμέσως λοιπόν χάνουμε ένα bit από το συνολικό εύρος τιμών που μπορούν να απεικονίσουν τα 2 μας bytes, συν πως ότι απομένει διαχωρίζεται στη μέση, μιας και πρέπει να απεικονιστούν και αρνητικές τιμές). Άρα το τελικό εύρος τιμών αλλάζει σε: –32,768 έως 32,767

Εκτός από signed και unsigned που καθορίζουν το εύρος τιμών των ακέραιων τύπων int και char, έστω κι έμμεσα, ειδικά για τον int υπάρχουν και τα short και long (και long long, από την αναθεώρηση C99 και μετά) που εξειδικεύουν ακόμα περισσότερο το μέγεθος που καταλαμβάνει στη μνήμη ο τύπος int. Το long μπορεί να χρησιμοποιηθεί και στον τύπο double.

Για παράδειγμα, μια μεταβλητή ορισμένη ως...

Μορφοποιημένος Κώδικας: Επιλογή όλων
long int n;

ή ως...

Μορφοποιημένος Κώδικας: Επιλογή όλων
unsigned long int n;

καταλαμβάνει εγγυημένα από το στάνταρ της γλώσσας τουλάχιστον 4 bytes στην μνήμη.

Μιας και το στάνταρ εγγυάται μονάχα τα ελάχιστα μεγέθη των τύπων, θα βρεις αρκετούς compilers που για παράδειγμα υλοποιούν με 4 bytes τόσο τους int όσο και τους long int.

Ρίξε μια ματιά και σε αυτό το link: http://rajkishor09.hubpages.com/hub/Dat ... C-Language
και σε αυτό: http://en.wikipedia.org/wiki/C_data_types

Τα εύρη τιμών των τύπων υπάρχουν στα στάνταρ header αρχεία limits.h (για ακέραιους) και float.h (για κινητής υποδιαστολής) συνήθως υλοποιημένα με #define. Οι τιμές τους διαφέρουν από πλατφόρμα σε πλατφόρμα ή/και από compiler σε compiler, αλλά αν θες για παράδειγμα να χρησιμοποιήσεις/αναφερθείς με portable τρόπο στην μέγιστη ή στην ελάχιστη τιμή ενός signed int μπορείς να το κάνεις με τα INT_MAX και INT_MIN, αντίστοιχα (και με #include <limits.h> στον κώδικά σου).

Η αναθεώρηση C99 έχει προσθέσει κι άλλα header files, όπως το inttypes.h που καθορίζει νέους τύπους με συγκεκριμένα, ακριβή μεγέθη, όπως π.χ.: int8_t & uint8_t (ακριβώς 8 bits), int16_t & uint16_t (ακριβώς 16 bits) κλπ.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Ilias95 » 25 Φεβ 2012, 21:58

:bow:
Θα επιστρέψω στο παραπάνω ποστ σου μόλις προχωρήσω λίγο περισσότερο για να καταλάβω κάποια πράγματα καλύτερα.
Βλέπω ότι αναλύεις και πολλά πράγματα ανεξάρτητα της C. Το έκανα ήδη bookmark.
Ευχαριστώ πολύ!
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό stamatiou » 25 Φεβ 2012, 23:31

Τώρα θα βάζουμε ασκήσεις από αυτο το βιβλίο;
1Γνώσεις→Linux: Αρχάριος┃Προγραμματισμός:Αρχάριος┃Αγγλικά:Μέτριος
2Λειτουργικό→Arch Linxu 32bit
3Προδιαγραφές→2x AMD AthlonX2 DualCore QL-66 ‖ RAM 1751 MiB ‖ Hewlett-Packard 308C - Hewlett-Packard Compaq 615
4Κάρτες γραφικών:ATI RS780M/RS780MN [Radeon HD 3200 Graphics][1002:9612]
5Δίκτυα:eth0:Marvell 88E8042 PCI-E Fast Ethernet Controller [11ab:4357] (rev 10)⋮eth1: Broadcom BCM4312 802.11b/g LP-PHY [14e4:4315](rev 01)
Πρωσοπική Ιστοσελίδα: http://giwrg98.co.cc
Άβαταρ μέλους
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 26 Φεβ 2012, 04:50

stamatiou έγραψε:Τώρα θα βάζουμε ασκήσεις από αυτο το βιβλίο;


O Καθενας κανει οποια γουστάρει :D
Ανοιξε το βιβλίο βρές μια ασκησούλα κοιταξε την καλα , καμάκωσε την !!!!
Και ορμα !!!!!!
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό Star_Light » 26 Φεβ 2012, 05:03

migf1 δηλαδη ενας unsigned int στον αριθμο 65536 θα κρασάριζε??? ή δεν εχει καμια σχεση αυτο που λεω????

Btw τα 16 bits που έχεις πιο πάνω αντιστοιχούν σε μια λέξη? Ενω πχ τα 8 bit ειναι τα nibbles
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

Re: Τα πάντα για την C

Δημοσίευσηαπό stamatiou » 26 Φεβ 2012, 11:40

Μήπως θα ήταν καλύτερα να ξεκινήσουμε όλοι μαζί το βιβλίο απο την αρχή και σε κάθε κεφάλαιο αν έχουμε κάποια απόρροια ή
δεν μπορούμε να λύσουμε μια άσκηση θα την κάνουμε ποστ εδώ. Μηπως θα μας βοηθήσει στο να μην ασχολούμαστε αποσπασματικά;
1Γνώσεις→Linux: Αρχάριος┃Προγραμματισμός:Αρχάριος┃Αγγλικά:Μέτριος
2Λειτουργικό→Arch Linxu 32bit
3Προδιαγραφές→2x AMD AthlonX2 DualCore QL-66 ‖ RAM 1751 MiB ‖ Hewlett-Packard 308C - Hewlett-Packard Compaq 615
4Κάρτες γραφικών:ATI RS780M/RS780MN [Radeon HD 3200 Graphics][1002:9612]
5Δίκτυα:eth0:Marvell 88E8042 PCI-E Fast Ethernet Controller [11ab:4357] (rev 10)⋮eth1: Broadcom BCM4312 802.11b/g LP-PHY [14e4:4315](rev 01)
Πρωσοπική Ιστοσελίδα: http://giwrg98.co.cc
Άβαταρ μέλους
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

ΠροηγούμενηΕπόμενο

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι