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

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

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

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

Δημοσίευσηαπό Star_Light » 03 Σεπ 2011, 00:24

Χωρις να έχω δει τα αποτελεσματα των ερωτησεων (επιτηδες για να μην πικραθω) :lol: :lol: :lol: λεω πως παμε καλα πλεον γιατι απο αυτα που σου λεω στα 7-8 στα 10 μου λες οκ ;)
Γνώσεις ⇛ 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/C++

Δημοσίευσηαπό Star_Light » 03 Σεπ 2011, 00:58

Bασικα τo char δεν εχουμε πει οτι ειναι μέγεθος 1 byte ??? πως και το βάζεις 4 ? στα 2 πρωτα?

στο 4 πχ το 1 byte που βάζεις ειναι επειδη τουλαχιστο θα έχει τον κενό χαρακτήρα? ακομη και αν ο χρηστης δεν δωσει καμια συμβολοσειρα.

ΣΤο 5 και 6 συμφωνουμε οκ στο 7 παιρνει την τιμη του μεγέθους του πίνακα ε?

και στο 8 οκ.

ΤΩρα κατι αλλο... δεν ειναι ισοδυναμο να πω ας πουμε οτι το char *s="testing" ειναι ενας δεικτης σε συμβολοσειρα testing με το αρχικοποιημενο string που λες και εσυ?

Π.Σ Στο μεταξυ εκανα και τα test cases και στον κωδικα με την συναρτηση για τις δυναμεις και διαπιστωσα πως ολα οκ εκτος και αν και η βάση αλλα και ο εκθέτης ειναι διψηφιοι εκει πλεον το αποτελεσμα ξεφευγει και δεν δινει σωστες τιμες. Εδω ας πουμε τι θα μπορουσαμε να κανουμε ?
Γνώσεις ⇛ 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/C++

Δημοσίευσηαπό migf1 » 03 Σεπ 2011, 09:42

Star_Light έγραψε:Bασικα τo char δεν εχουμε πει οτι ειναι μέγεθος 1 byte ??? πως και το βάζεις 4 ? στα 2 πρωτα?

Αυτό είναι ένα από τα βασικά σημεία που ήθελα να ξεδιαλύνουμε.

Λοιπόν, στα
Κώδικας: Επιλογή όλων
char *s
char *s = NULL
το s δεν ορίζεται ως σκέτο char (τότε θα είχε μέγεθος 1 byte) αλλά ως δείκτης σε char.

Οι μεταβλητές που ορίζονται ως δείκτες έχουν πάντα το ίδιο μέγεθος στη μνήμη, είτε ορίζονται να δείχνουν σε char, είτε σε int, είτε σε struct είτε σε οποιονδήποτε άλλον τύπο. Το μέγεθος αυτό είναι implementation dependent, αλλά πολύ συχνά είναι ίσο με sizeof( unsigned int ).

Για να δείτε το μέγεθος που πιάνουν οι δείκτες στη δική σας πλατφόρμα/compiler ορίστε έναν οποιονδήποτε δείκτη, π.χ. float *ptr; και κατόπιν τυπώστε το αποτέλεσμα του: sizeof( ptr );

έγραψε:στο 4 πχ το 1 byte που βάζεις ειναι επειδη τουλαχιστο θα έχει τον κενό χαρακτήρα? ακομη και αν ο χρηστης δεν δωσει καμια συμβολοσειρα.
Κώδικας: Επιλογή όλων
char s[] = ""; // αρχικοποιημένο string (1 byte)

Εδώ το s ορίζεται & αρχικοποιείται ως string. Δεν θα έχει τουλάχιστον έναν χαρακτήρα, έχει ήδη μόνο έναν χαρακτήρα (τον μηδενικό) λόγω της συγκεκριμένης αρχικοποίησης και δεν μπορεί να έχει περισσότερους. Οποιαδήποτε μετέπειτα απόπειρα να του βάλουμε περισσότερους από 1 χαρακτήρα θα μας δώσει segmentation-fault (crash).

έγραψε:ΣΤο 5 και 6 συμφωνουμε οκ στο 7 παιρνει την τιμη του μεγέθους του πίνακα ε?
Κώδικας: Επιλογή όλων

char s[] = "testing"; // αρχικοποιημένο string (8 bytes)
char s[8] = "testing"; // αρχικοποιημένο string (8 bytes)
char s[100] = "testing"; // αρχικοποιημένο string (100 bytes)

Ωραία, οι ορισμοί 5 και 6 είναι ισοδύναμοι: ορίζουν κι αρχικοποιούν ένα string με μέγεθος 8 χαρακτήρων (8 bytes). Κανένα από τα 2 δεν μπορεί να δεχτεί περισσότερους από 8 χαρακτήρες, συμπεριλαμβανομένου του μηδενικού στο τέλος.

0 7ος ορισμός είναι διαφορερτικός! Ορίζει ένα string μεγέθους 100 χαρακτήρων (100 bytes) αλλά το αρχικοποιεί με μια τιμή που πιάνει 8 χαρακτήρες (συμπεριλαμβανομένου του μηδενικού χαρακτήρα στο τέλος). Μπορεί όμως να δεχτεί τιμές που εχουν πλήθος έως και 100 χαρακτήρες (συμπεριλαμβανομένου του μηδενικού χαρακτήρα στο τέλος).

έγραψε:και στο 8 οκ.
Κώδικας: Επιλογή όλων
char s[80]; // μη-αρχικοποιημένο string (80 bytes)

Εδώ το ακριβές σχόλιο που έπρεπε να κάνω θα ήταν: // μη-αρχικοποιημένος πίνακας χαρακτήρων (80 bytes). Αντί για "πίνακας" έγραψα "string" για να μη χαθεί τελείως η μπάλα.

Βασικά η μπάλα είναι έτσι κι αλλιώς λίγο χαμένη με τα strings στη C, γιατί δεν τα υποστηρίζει εγγενώς ως ξεχωριστό τύπο δεδομένων (data type). Για να τα διαχειριστούμε μας αναγκάζει να τα ορίσουμε είτε σαν πίνακες χαρακτήρων είτε σαν μια συνεχόμενη σειρά από χαρακτήρες στη μνήμη, με έναν δείκτη στον 1ο από αυτούς. Είτε στην 1η είτε στη 2η περίπτωση (και με εξαίρεση τις επί τούτου αρχικοποιήσεις κατά τον ορισμό των strings) το αφήνει πάνω μας να σηματοδοτήσουμε το τρέχον μήκος του κάθε string με τον μηδενικό χαρακτήρα. Το οποίο όμως τρέχον μήκος δεν ισούται κατά ανάγκη με το συνολικό μέγεθος του string.

Που είναι η μπάλα οεο; :lol:

Πάω να κάνω κάτι δουλίτσες κι επανέρχομαι σε καμιά ωρίτσα για τυχόν απορίες πάνω σε αυτό.

έγραψε:ΤΩρα κατι αλλο... δεν ειναι ισοδυναμο να πω ας πουμε οτι το char *s="testing" ειναι ενας δεικτης σε συμβολοσειρα testing με το αρχικοποιημενο string που λες και εσυ?

Επειδή με τις Ελληνικές ορολογίες δεν τα πάω πολύ καλά (τα έχω διδαχτεί στην αγγλική γλώσσα) αν η "συμβολοσειρά" είναι το ακριβές ισοδύναμο του "string" (και όχι π.χ του "string literal") τότε δεν ισχύει αυτό που γράφεις.

Δείκτης σε string θα μπορούσε π.χ. να είναι κάποιο από τα παρακάτω:
Κώδικας: Επιλογή όλων

char *ps[STRINGSIZE];
char **ps;

τα οποία βασικά είναι πίνακες από strings.

έγραψε:
Π.Σ Στο μεταξυ εκανα και τα test cases και στον κωδικα με την συναρτηση για τις δυναμεις και διαπιστωσα πως ολα οκ εκτος και αν και η βάση αλλα και ο εκθέτης ειναι διψηφιοι εκει πλεον το αποτελεσμα ξεφευγει και δεν δινει σωστες τιμες. Εδω ας πουμε τι θα μπορουσαμε να κανουμε ?

(σε καμιά ωρίτσα που θα επιστρέψω ;) )
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 03 Σεπ 2011, 10:34

Star_Light έγραψε:
...
Π.Σ Στο μεταξυ εκανα και τα test cases και στον κωδικα με την συναρτηση για τις δυναμεις και διαπιστωσα πως ολα οκ εκτος και αν και η βάση αλλα και ο εκθέτης ειναι διψηφιοι εκει πλεον το αποτελεσμα ξεφευγει και δεν δινει σωστες τιμες. Εδω ας πουμε τι θα μπορουσαμε να κανουμε ?

Τελικά πήγε άλλος για τις δουλίτσες :)

Το καλύτερο που έχεις να κάνεις αν θες να σου υπολογίζει πραγματικά τεράστιους αριθμούς είναι να χρησιμοποιήσεις μια εξειδικευμένη μαθηματική βιβλιοθήκη, όπως είναι η GNU MP ή η GNU MPFR (που βασίζεται στην MP).

Πριν από αυτό όμως μπορείς να δοκιμάσεις μερικά πιο εύκολα πράγματα.

Πρώτα-πρώτα βάλε την RaiseToPower() (btw, τι μακρυνάρι είναι αυτό; ... σκέτο power() δεν κάνει; :lol:) αντί για int να επιστρέφει long, ή long long ή ακόμα και unsigned long long.

Έπειτα, δοκίμασε με αλγόριθμο που δεν είναι αναδρομικός, γιατί οι αναδρομές δουλεύουν μέσα στο stack του προγράμματος, που εξαντλείται πολύ νωρίτερα!
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 03 Σεπ 2011, 12:01

Επιστρέφοντας στα strings, ο ορισμός:
Κώδικας: Επιλογή όλων
char s[100];

βασικά ορίζει έναν πίνακα από 100 χαρακτήρες, αυτό δεν είναι εξ' ορισμού string! Τα strings πρέπει να σηματοδοτούν το τρέχον μήκος τους με έναν μηδενικό χαρακτήρα, και ο συγκεκριμένος ορισμός δεν μας εξασφαλίζει κάτι τέτοιο (βασικά μας το εξασφαλίζει ΜΟΝΑΧΑ αν το s το ορίζουμε ως καθολική μεταβλητή... περισσότερα παρακάτω).

Αντίθετα, αρχικοποιώντας ως string τον παραπάνω πίνακα όταν τον ορίζουμε...
Κώδικας: Επιλογή όλων
char s[100] = "testing";

τότε ο 8ος χαρακτήρας του είναι εγγυημένα ο '\0', γιατί λόγω της συγκεκριμένης αρχικοποίησης τον προσθέτει αυτόματα ο compiler. Και μάλιστα το συγκεκριμένο string έχει χώρο για 100 συνολικά χαρακτήρες (δηλαδή μέγιστο μήκος ή το μέγεθος του αν προτιμάται είναι ίσο με 100 bytes). Και άρα μπορούμε με ασφάλεια να χαρακτηρίσουμε τον παραπάνω πίνακα χαρακτήρων ως string.

Ομοίως κι εδώ...
Κώδικας: Επιλογή όλων
char s[] = "testing";
με μόνη διαφορά πως έτσι το s έχει χώρο για 8 και μόνο 8 χαρακτήρες (επειδή δεν ορίσαμε μέγεθος, ο compiler βάζει μόνος του το πλήθος χαρακτήρων στην αρχικοποίηση +1 για τον μηδενικό χαρακτήρα που προσθέτει μόνος του).

Ο παραπάνω τρόπος αρχικοποιήσης είναι ΕΙΔΙΚΗ ΠΕΡΙΠΤΩΣΗ ΑΡΧΙΚΟΠΟΙΗΣΗΣ στη C και λειτουργεί μονάχα για πίνακες χαρακτήρων, ως ένδειξη πως η πρόθεσή μας είναι να τους διαχειριστούμε ως strings!

Ο στάνταρ τρόπος αρχικοποίησης πινάκων στη C είναι οι τιμές των στοιχείων διαχωρισμένες με κόμματα (πλην του τελευταίου} και όλο μαζί μέσα σε άγκιστρα.

Αν λοιπόν αρχικοποιούσαμε το s με τον στάνταρ τρόπο, δηλαδή...
Κώδικας: Επιλογή όλων
char s[100] = { 't', 'e', 's', 't', 'i', 'n', 'g' };

τότε κανονικά δεν μπορούμε να μιλήσουμε για string, γιατί δεν έχουμε βάλει τον '\0' στο τέλος, οπότε λογικά έχουμε έναν απλό πίνακα χαρακτήρων. Στην πράξη όμως το παραπάνω συμπεριφέρεται ως string λόγω μιας άλλης γενικής ιδιότητας της γλώσσας ως προς τους πίνακες, η οποία στην προκειμένη περίπτωση τυγχάνει να λειτουργεί ας το πούμε ευεργετικά για μας.

Η ιδιότητα αυτή είναι πως σε οποιονδήποτε πίνακα, αν αρχικοποιήσουμε στον ορισμό του λιγότερα στοιχεία από το μέγιστο πλήθος στοιχείων που του έχουμε ορίσει, τότε τα υπόλοιπα αρχικοποιούνται αυτόματα με την τιμή 0. Αντίθετα, αν δεν αρχικοποιήσουμε κανένα στοιχείο, τότε ο πίνακας έχει undefined τιμές στα στοιχεία του (εκτός αν είναι δηλωμένος ως καθολική μεταβλητή, οπότε σε αυτή την περίπτωση αρχικοποιείται αυτόματα με όλα τα στοιχεία του ίσα με 0 χωρίς να χρειάζεται το κάνουμε εμείς).

Παράδειγμα με πίνακα από int, για να το καταλάβουμε:

Παράδειγμα 1ο:
Κώδικας: Επιλογή όλων

int numbers[100];
int main( void) {
...
}
με αυτόν τον ορισμό τα 100 στοιχεία του numbers αρχικοποιούνται αυτόματα σε 0, γιατί ο numbers έχει οριστεί ως καθολική μεταβλητή!

Παράδειγμα 2ο:
Κώδικας: Επιλογή όλων

int main( void) {
int numbers[100];
...
}
με αυτόν τον ορισμό τα 100 στοιχεία του numbers έχουν undefined τιμές, γιατί ο numbers έχει οριστεί ως τοπική μεταβλητή!

Παράδειγμα 3ο:
Κώδικας: Επιλογή όλων

int main( void) {
int numbers[100] = { 0 };
...
}
με αυτόν τον ορισμό όλα τα στοιχεία του numbers αρχικοποιούνται σε 0!

Παράδειγμα 4ο:
Κώδικας: Επιλογή όλων

int main( void) {
int numbers[100] = { 5, 5 };
...
}
με αυτόν τον ορισμό τα δυο πρώτα στοιχεία του numbers αρχικοποιούνται σε 5 και όλα τα υπόλοιπα σε 0!

Παράδειγμα 5ο:
Κώδικας: Επιλογή όλων

int main( void) {
int numbers[100] = { 3, 10, 7 };
...
}
με αυτόν τον ορισμό τα πρώτο στοιχείο αρχικοποιείται σε 3, το δεύτερο σε 10, το τρίτο σε 7 και όλα τα υπόλοιπα σε 0!

Παράδειγμα 6ο:
Κώδικας: Επιλογή όλων

int main( void) {
int numbers[2] = { 3, 10, 7 };
...
}
με αυτόν τον ορισμό ο compiler βγάζει ΣΦΑΛΜΑ γιατί επιχειρούμε να αρχικοποιήσουμε περισσότερα στοιχεία από όσα έχουμε ορίσει!

Οπότε, γνωρίζοντας τα παραπάνω, καταλαβαίνουμε πια πως το...
Κώδικας: Επιλογή όλων
char s[100] = { 't', 'e', 's', 't', 'i', 'n', 'g' };

συμπεριφέρεται σαν κανονικό string επειδή όλοι οι χαρακτήρες από τον 'g' και μετά αρχικοποιούνται αυτόματα με μηδενικές τιμές (και όπως έχουμε πει, οι μηδενικές τιμές στους χαρακτήρες είναι '\0' ).

Δείτε όμως αυτό εδώ:

Κώδικας: Επιλογή όλων
char s[7] = { 't', 'e', 's', 't', 'i', 'n', 'g' };

εδώ πλέον ΔΕΝ έχουμε string, διότι αρχικοποιήσαμε ΟΛΑ τα στοιχεία του s και ΔΕΝ υπάρχει μηδενικός χαρακτήρας! Εδώ έχουμε έναν απλό πίνακα χαρακτήρων, κι αν επιχειρήσουμε να τον διαχειριστούμε σαν string, θα έχουμε κρασαρίσματα διότι η συντριπτική πλειοψηφία των στάνταρ συναρτήσεων διαχείρισης strings στη C θεωρούν δεδομένο πως υπάρχει ο μηδενικός χαρακτήρας και σηματοδοτεί το τρέχον μήκος!

ΗΘΙΚΟ ΔΙΔΑΓΜΑ:
--------------------
όταν η πρόθεση μας είναι να χρησιμοποιήσουμε έναν πίνακα χαρακτήρων ως string τον ορίζουμε και τον αρχικοποιούμε με τον ΕΙΔΙΚΟ ΤΡΟΠΟ που μας παρέχει η γλώσσα για αυτό τον σκοπό ( π.χ. "abcd") ώστε να υπάρχει εγγυημένα μηδενικός χαρακτήρας (τον βάζει αυτόματα ο compiler) είτε ο πίνακας είναι καθολική μεταβλητή είτε τοπική.


Επειδή όμως όλες οι κανόνες έχουν εξαιρέσεις, δείτε αυτό...

Κώδικας: Επιλογή όλων
char s[7] = "testing";

εδώ έχουμε ΠΡΟΒΛΗΜΑ!

Αντί ο compiler να μας βγάλει σφάλμα, επειδή δεν του έχουμε αφήσει χώρο να κολλήσει αυτόματα τον μηδενικό χαρακτήρα στο τέλος του s, το θεωρεί ως απλό πίνακα χαρακτήρων, ισοδύναμο δηλαδή με το αμέσως προηγούμενο παράδειγμα. Το μετατρέπει αν προτιμάτε σε ...
Κώδικας: Επιλογή όλων
char s[7] = { 't', 'e', 's', 't', 'i', 'n', 'g' };
οπότε αν εμείς το διαχειριστούμε ως string έχουμε πρόβλημα!

Άφησα για το τέλος, την επίσης ειδική περίπτωση:

Κώδικας: Επιλογή όλων
char *s = "testing";

για να βεβαιωθώ πρώτα πως είμαστε οκ με τα προηγούμενα, που βασίζονται σε λογική πινάκων. Ενώ αυτό εδώ βασίζεται σε λογική δεικτών και πιστεύω είναι καλύτερα να το δούμε ξεχωριστά, αφού καταλάβουμε πρώτα τα περί πινάκων και strings.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό Star_Light » 03 Σεπ 2011, 13:13

Ειμαστε τελειως ενταξει! Εκτος απο το
Κώδικας: Επιλογή όλων
char *s="testing";
που ειπα πως ειναι pointer σε string να ξεκαθαρισω πως εννοουσα οτι το s ειναι δεικτης σε string. Βεβαια αν θεωρειται παλι λαθος αυτο που γράφω ισως θεωρειται επειδη το s επι της ουσιας ειναι απλα ενας δεικτης σε χαρακτηρα οποτε μολις συναντησει τον '\0' θα πουμε οτι τελικα τελειωσε η συμβολοσειρα... Ισως η διατυπωση δεν ειναι σωστη που λεω αλλα εχω καταλαβει τι ακριβως ειναι ;)
Γνώσεις ⇛ 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/C++

Δημοσίευσηαπό Star_Light » 03 Σεπ 2011, 13:27

Οσο για την συναρτηση.... κοιταξε για να βάλω να επιστρεφει long η συνάρτηση λογικα θα πρέπει να αλλαξω και τις μεταβλητες? να τις δηλωσω δηλαδη σαν long ή δεν εχει σημασια οποτε αφηνω το long μονο στον επιστρεφομενο τυπο φερειπειν?

Π.Σ1 Πολυ ενδιαφερον εργαλειακι η MPFR διαβαζα λεει πρεπει να κανεις εκτελεσιμο το mpfr.h στο μεταξυ το εψαξα στους καταλογους μου και στον /lib και στον /usr/include που ελεγε να το ψαξω αλλα δεν το βρηκα πιο συγκεκριμενα εδωσα την

Κώδικας: Επιλογή όλων
ls | grep mpfr.h
οταν ημουν μεσα στον /usr/include αλλα και τον /lib αλλα τιποτα... δεν πειραζει :D

Π.Σ2 Που μας ειπες να ελενξουμε ποσο πιανει ενας δεικτης στο δικο μας συστημα

Κώδικας: Επιλογή όλων
int *ptr;
printf("%ld",sizeof(ptr));


και μου εδωσε αποτελεσμα 8.
Γνώσεις ⇛ 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/C++

Δημοσίευσηαπό migf1 » 04 Σεπ 2011, 12:26

Star_Light έγραψε:Ειμαστε τελειως ενταξει! Εκτος απο το
Κώδικας: Επιλογή όλων
char *s="testing";
που ειπα πως ειναι pointer σε string να ξεκαθαρισω πως εννοουσα οτι το s ειναι δεικτης σε string. Βεβαια αν θεωρειται παλι λαθος αυτο που γράφω ισως θεωρειται επειδη το s επι της ουσιας ειναι απλα ενας δεικτης σε χαρακτηρα οποτε μολις συναντησει τον '\0' θα πουμε οτι τελικα τελειωσε η συμβολοσειρα... Ισως η διατυπωση δεν ειναι σωστη που λεω αλλα εχω καταλαβει τι ακριβως ειναι ;)

Ναι, το ξέρω πως έχεις καταλάβει :)
Με την διατύπωση υπάρχει γενικότερο θέμα, διότι τα strings δεν υποστηρίζονται εγγενώς από τη C, οπότε πολύ συχνά ο καθένας τα διατυπώνει και διαφορετικά :)

Αν συμφωνήσουμε όμως πως κατά βάση τα strings είναι πίνακες χαρακτήρων, τότε λέγοντας δείκτης σε string είναι σαν να λέμε δείκτης σε πίνακα χαρακτήρων. Μιλάμε δηλαδή για διπλό δείκτη και όχι για μονό ;)

Για την μαθηματική βιβλιοθήκη, ψάξε να βρεις το .a αρχείο της για την πλατφόρμα σου (αν διατίθεται)... π.χ. libmpfr.a ή όπως αλλιώς λέγεται, βάλε την στον φάκελο που βρίσκονται και οι υπόλοιπες βιβλιοθήκες του gcc και όταν κάνεις compile το πρόγραμμά σου βάλε στη γραμμή εντολών του gcc στο τέλος ένα -lmpfr.

Αλλιώς βάλε το αρχείο .a σε ένα φάκελο της αρεσκείας σου και δήλωσέ το με κεφαλαίο L στην γραμμή εντολών του gcc.

Αν δεν διατίθεται το .a αρχείο, θα χρειαστεί να κατεβάσεις τον πηγαίο κώδικα της βιβλιοθήκης και να τον κάνεις compile μόνος σου (συνήθως σου δίνουν έτοιμα makefiles για κάθε πλατφόρμα.

Για την άλλη ερώτηση, για το αν χρειάζεται να γίνουν long και τα ορίσματα εκτός από την τιμή επιστροφής της συνάρτησης, λογικά δεν χρειάζεται.

Για το μέγεθος των δεικτών που σου βγάζει 8 bytes, τόσο είναι το σύνηθες σε 64μπιτες πλατφόρμες (και 4 bytes σε 32μπιτες).

Τέλος, για να συνεχίσουμε με τα strings περιμένω το ΟΚ από τον φίλο stamatiou :)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό stamatiou » 04 Σεπ 2011, 14:16

migf1 έγραψε:
Star_Light έγραψε:Ειμαστε τελειως ενταξει! Εκτος απο το
Κώδικας: Επιλογή όλων
char *s="testing";
που ειπα πως ειναι pointer σε string να ξεκαθαρισω πως εννοουσα οτι το s ειναι δεικτης σε string. Βεβαια αν θεωρειται παλι λαθος αυτο που γράφω ισως θεωρειται επειδη το s επι της ουσιας ειναι απλα ενας δεικτης σε χαρακτηρα οποτε μολις συναντησει τον '\0' θα πουμε οτι τελικα τελειωσε η συμβολοσειρα... Ισως η διατυπωση δεν ειναι σωστη που λεω αλλα εχω καταλαβει τι ακριβως ειναι ;)

Ναι, το ξέρω πως έχεις καταλάβει :)
Με την διατύπωση υπάρχει γενικότερο θέμα, διότι τα strings δεν υποστηρίζονται εγγενώς από τη C, οπότε πολύ συχνά ο καθένας τα διατυπώνει και διαφορετικά :)

Αν συμφωνήσουμε όμως πως κατά βάση τα strings είναι πίνακες χαρακτήρων, τότε λέγοντας δείκτης σε string είναι σαν να λέμε δείκτης σε πίνακα χαρακτήρων. Μιλάμε δηλαδή για διπλό δείκτη και όχι για μονό ;)

Για την μαθηματική βιβλιοθήκη, ψάξε να βρεις το .a αρχείο της για την πλατφόρμα σου (αν διατίθεται)... π.χ. libmpfr.a ή όπως αλλιώς λέγεται, βάλε την στον φάκελο που βρίσκονται και οι υπόλοιπες βιβλιοθήκες του gcc και όταν κάνεις compile το πρόγραμμά σου βάλε στη γραμμή εντολών του gcc στο τέλος ένα -lmpfr.

Αλλιώς βάλε το αρχείο .a σε ένα φάκελο της αρεσκείας σου και δήλωσέ το με κεφαλαίο L στην γραμμή εντολών του gcc.

Αν δεν διατίθεται το .a αρχείο, θα χρειαστεί να κατεβάσεις τον πηγαίο κώδικα της βιβλιοθήκης και να τον κάνεις compile μόνος σου (συνήθως σου δίνουν έτοιμα makefiles για κάθε πλατφόρμα.

Για την άλλη ερώτηση, για το αν χρειάζεται να γίνουν long και τα ορίσματα εκτός από την τιμή επιστροφής της συνάρτησης, λογικά δεν χρειάζεται.

Για το μέγεθος των δεικτών που σου βγάζει 8 bytes, τόσο είναι το σύνηθες σε 64μπιτες πλατφόρμες (και 4 bytes σε 32μπιτες).

Τέλος, για να συνεχίσουμε με τα strings περιμένω το ΟΚ από τον φίλο stamatiou :)

ΟΚ! :D
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

Δημοσίευσηαπό Star_Light » 04 Σεπ 2011, 16:54

Λιγο πριν προχωρησουμε εχω κάποιες απορίες.

1.
Στο
Κώδικας: Επιλογή όλων
char s[100]="testing"


μπορει να δεχθεί άλλες 92 τιμές για είσοδο? Πχ απο τον χρήστη... (φυσικά απο τον δείκτη s[5] και μετα )

Απο οσο εχω καταλαβει ενα string ειναι ενας πίνακας χαρακτήρων αλλα μπορω και με βεβαιότητα να πω (συμφωνα με αυτα που εδωσε και ο migf και τα διαβασα αρκετα καλα) οτι ενας πίνακας χαρακτήρων δεν ειναι απαραίτητα ενα string. Οκ?

2. Κανονικα το
Κώδικας: Επιλογή όλων
char s[] = "";


δεν μπορει να περιμένει είσοδο απο τον χρήστη ή πρεπει να του ορίσεις μια τιμή στο μέγεθος (του πίνακα) ωστε να ξέρει ο μεταγλωττιστής απο ποιο σημείο και μετα θα πρεπει να βάλει τον μηδενικο χαρακτηρα ο οποιος και σηματοδοτει το τελος της συμβολοσειρας για να ελενξει με πιο σωστο τροπο την εισοδο του χρηστη?

Και τελος αν

3.
Κώδικας: Επιλογή όλων
char usernme[32];


Αν δηλωσεις δηλαδη εναν πίνακα με στοιχεια παραπανω απο οσα χρειάζεσαι (επειδη πχ το UNIX επιτρέπει μεχρι 8 χαρακτήρες ονοματα) τοτε εδω μπορει να γινει ας πουμε buffer overflow?

: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
Εκτύπωση

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

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