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

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

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

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

Δημοσίευσηαπό migf1 » 02 Σεπ 2011, 15:11

migf1 έγραψε:
stamatiou έγραψε:Τα test cases μου φαίνεται πως βγήκαν σωστά τώρα μπορει και να έκανα και κάνα λάθος, όμως έχω την εντύπωση πως δουλεύει :D

Οκ, μισό να το δω κι εγώ τώρα που λασκάρισα λιγάκι

Έχεις απόλυτο δίκιο! Δουλεύει άψογα! VERY WELL DONE !!!!! :)

Τώρα μένει να το κάνει κι ο Κώστας, να λύσουμε τυχόν απορίες και για να μιλήσουμε για κάποιους έξτρα ελέγχους που δεν κάνει ούτε η κανονική strcmp :)

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

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

Δημοσίευσηαπό Star_Light » 02 Σεπ 2011, 15:19

EEEEEλα ρε σταματιου παικτρονι!!!! @migf1 τσεκαρε αυτο που έγραψα πριν.....

θελω πρωτα να καταλαβω πως γινεται trace ο αλγοριθμος και μετα θα κανω αυτο με τους μετρητες...
Γνώσεις ⇛ 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 » 02 Σεπ 2011, 15:24

Star_Light έγραψε:
Πιστευω πως τον δεικτη στον αλγοριθμο τον μειωνεις.... επειδη ετσι και μονο ετσι θα μπορεσει να γινει η επιστροφη της τιμης μετα την συγκριση (γειτονικων χαρακτηρων).

ΠΧ => s1[]="a" & s2[]="ab"

αρχικα ο s1 δειχνει στο a και ο s2 to ιδιο (μετα ο s2 αμεσως αυξανει κατα ενα και δειχνει στον b
στο τελευταιο return ομως επειδη δεν έχουμε φθασει ακομη στο 2ο βήμα δηλαδη στον 2ο χαρακτηρα παρα ειμαστε μονο στους πρωτους
πριν γινει η αφαιρεση και φυγει το αποτελεσμα απο το τελικο return (επιστραφει δηλαδη) θα πρεπει ο δεικτης να αφαιρεθει μια θεση
δηλαδη να παει στο a παλι συνεπως a-a = 0

Πολύ σωστά! ΕΥΓΕ! :) :) :) :)

Με άλλα λόγια, επειδή στη συνθήκη του while αυξάνεται μονάχα o s2 (χωρίς να ακολουθεί ο s1, αυτός ακολουθεί μονάχα όταν μπει η ροή μέσα στο σώμα του while, και συγκεκριμένα στη συνθήκη του if) τότε μετά την τελευταία επανάληψη του loop (που η ροή διακόπτεται στη συνθήκη του, πριν μπει στο σώμα του) ο s2 έχει φύγει ένα χαρακτήρα πιο δεξιά από αυτόν που του αντιστοιχεί στο 1ο string (δηλαδή τον *s1)... άρα πρέπει να τον φέρουμε μια θέση πίσω, ώστε να αφαιρεθεί ο σωστός *s2 από τον *s1.

Αυτό το πρόβλημα δεν υφίσταται με τον μετρητή γιατί εκεί αυξάνονται ταυτόχρονα τα 2 strings στη συνθήκη του while-loop (εκεί μπερδεύτηκα κι εγώ Γιώργο και σου είπα λανθασμένα αρχικά πως δεν λειτουργεί ο κώδικάς σου).

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

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

Δημοσίευσηαπό Star_Light » 02 Σεπ 2011, 15:48

ειναι αναγκη να κανουμε και τους εξτρα ελεγχους? Εγω θελω να ειμαι ανεξελεγκτος :lol: :lol:

ρε συ με εχει μπερδεψει η if + οτι εκανα μονο την 1η φάση του trace... βεβαια αν έχεις καλη αρχη μετα και το αλλο καλα θα βγει.
Γνώσεις ⇛ 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 » 02 Σεπ 2011, 15:59

Όσο ο φίλος Star_Light ετοιμαστεί (και μέχρι να ξανα-πλακώσει δουλειά εδώ) ας γράψω μερικά πραγματάκια ακόμα στο θέμα μας, χωρίς να ξεφεύγω.

Όπως ίσως έγινε αντιληπτό, η διαχείριση των strings με μετρητές στην πλειοψηφία των περιπτώσεων είναι πολύ πιο εύκολη και κυρίως πολύ λιγότερο επιρρεπής σε λάθη απροσεξίας. Και στην πραγματικότητα δεν υπάρχει κανένα πλεονέκτημα στη διαχείρισή τους με δείκτες, ειδικά αν στο compilation ενεργοποιήσουμε το optimization που έτσι κι αλλιώς τα μετατρέπει σε δείκτες (-Ο, -Ο2 και -O3 στον gcc).

Είναι όμως πολύτιμοι στην διαδικασία εκμάθησης, γιατί μέσω αυτών ξεκαθαρίζει πως δουλεύουν πραγματικά τα πράγματα, κάτι που με τους μετρητές δεν είναι και τόσο προφανές. Όταν προγραμματίζετε πράματα που θέλετε να τα διαθέσετε δημόσια ή να τα πουλήσετε, να χρησιμοποιείτε ΠΑΝΤΑ όποιον κώδικα καταλαβαίνετε καλύτερα, γιατί έτσι μειώνετε σημαντικά τις πιθανότητες να υποπέσετε σε λάθη απροσεξίας, τα μπορεί να μην φανούν αμέσως και να "σκάσουν" όταν πλέον είναι πολύ αργά (δηλαδή όταν χρησιμοποιήσει το πρόγραμμα ο πελάτης μας).

Είτε με δείκτες είτε με μετρητές, ΠΑΝΤΑ να δοκιμάζετε τις συναρτήσεις που φτιάχνετε με όσο το δυνατόν περισσότερα test-cases και μάλιστα έξυπνα επιλεγμένα test-cases για να μη χάνετε πολύτιμο χρόνο. π.χ. με τον τρόπο που γράψαμε αυτή τη συνάρτηση (που δεν χρησιμοποιούμε κάποια μέγιστη τιμή πλήθους χαρακτήρων για να σταματήσουμε το while-loop) τότε, αν δουλεύει σωστά με το test-case:
Κώδικας: Επιλογή όλων

char s1[] = "a", s2[] = "ab";

δεν υπάρχει κανένας λόγος να το τεστάρουμε και με τα...
Κώδικας: Επιλογή όλων

char s1[] = "ab", s2[] = "abc";
char s1[] = abc", s2[] = "abcd";
κλπ

Για τον τρόπος που είναι γραμμένος ο κώδικάς μας όλα τα παραπάνω είναι ουσιαστικά 1 και μόνο test-case :)

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

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

Δημοσίευσηαπό migf1 » 02 Σεπ 2011, 16:00

Star_Light έγραψε:ειναι αναγκη να κανουμε και τους εξτρα ελεγχους? Εγω θελω να ειμαι ανεξελεγκτος :lol: :lol:

ρε συ με εχει μπερδεψει η if + οτι εκανα μονο την 1η φάση του trace... βεβαια αν έχεις καλη αρχη μετα και το αλλο καλα θα βγει.

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

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

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

Λοιπον μεσα στον αλγοριθμο βάζεις ουσιαστικα αυτο

Κώδικας: Επιλογή όλων
if(*s1=='\0')
s1++;
return 0;


αυτο για μενα... με οσα ξερω ως τωρα σημαινει... ΑΝ Ο δεικτης δειχνει στο τελος του C string τοτε αυξησε τον κατα 1 και επεστρεψε 0.
Επομενως δεν καταλαβαινω για ποιο λογο οσο ο s1 δεν δειχνει στο τελος της συμβολοσειρας για ποιο λογο πρεπει να αυξανεται.

Π.Σ Στο μεταξυ εχεις πει πως το προβλημα με τους μετρητες εξαλειφεται επειδη αυξανονται και οι δυο ταυτοχρονα.... εδω στους δεικτες δεν θα μπορουσαμε να το κανουμε αυτο??? πχ

Κώδικας: Επιλογή όλων
while(*s1++==*s2++)
Γνώσεις ⇛ 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 » 02 Σεπ 2011, 16:43

Star_Light έγραψε:Λοιπον μεσα στον αλγοριθμο βάζεις ουσιαστικα αυτο

Κώδικας: Επιλογή όλων
if(*s1=='\0')
s1++;
return 0;


αυτο για μενα... με οσα ξερω ως τωρα σημαινει... ΑΝ Ο δεικτης δειχνει στο τελος του C string τοτε αυξησε τον κατα 1 και επεστρεψε 0.

Έτσι είναι, με τη διαφορά πως αυτό το if βρίσκεται μέσα σε ένα loop, οπότε όλο μαζί σημαίνει:
Κώδικας: Επιλογή όλων
όσο ο δείκτης ΔΕΝ δείχνει στο τέλος του 1ου string προχώρα τον μια θέση και συνέχισε, αλλά μόλις δείξει στο τέλος του string τότε μη συνεχίσεις άλλο κι επέστρεψε απευθείας την τιμή 0

btw, έχεις ξεχάσει τα άγκιστρα στον κώδικα που έδωσες παραπάνω. Χωρίς άγκιστρα, εκτελεί μονάχα το s1++ ( εσύ θες και το: return 0; )

έγραψε:Επομενως δεν καταλαβαινω για ποιο λογο οσο ο s1 δεν δειχνει στο τελος της συμβολοσειρας για ποιο λογο πρεπει να αυξανεται.

Αν δεν τον αυξήσεις, θα μείνει στον 1ο χαρακτήρα του 1ου string καθ' όλη τη διάρκεια του loop και θα συγκρίνει πάντα τον 1ο χαρακτήρα του 1ου string με τους χαρακτήρες του 2ου string (αφού ο s2++ αυξάνεται κανονικά σε κάθε επανάληψη).

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

Κώδικας: Επιλογή όλων
while(*s1++==*s2++)

Αν το κάνεις αυτό, τότε μέσα στο σώμα του while, στο if ( *s1 == '0') αντί να ελέγχεις τον εκάστοτε τρέχοντα χαρακτήρα του 1ου string θα ελέγχεις τον επόμενό του, μιας και το *s1++ στη συνθήκη του while-loop συγκρίνει τον τρέχοντα *s1 με τον τρέχοντα *s2 αλλά αμέσως μετά πάει στους αμέσως επόμενους χαρακτήρες.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 02 Σεπ 2011, 17:11

Και μια μικρή ασκησούλα μέχρι να ετοιμαστεί ο φίλος Star_Light.

Χωρίς ελέγχους εγκυρότητας των ορισμάτων και θεωρώντας δεδομένο πως 2 strings dst και src έχουν οριστεί με ακριβώς το ίδιο μέγιστο μήκος, μπορείτε να φτιάξετε μια συνάρτηση:

Κώδικας: Επιλογή όλων
void s_copy( char *dst, const char *src )

η οποία σε ακριβώς 3 γραμμές (συμπεριλαμβανομένων του ορισμού και της επιστροφής, αλλά εξαιρουμένων των άγκιστρων) να αντιγράφει τα περιεχόμενα του src στο dst;

Δηλαδή...
Κώδικας: Επιλογή όλων

void s_copy( char *dst, const char *s)
{
// μία μόνο γραμμή κώδικα εδώ (δηλαδή ένα και μοναδικό ; στο τέλος της )
return;
}

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

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

Δημοσίευσηαπό Star_Light » 02 Σεπ 2011, 17:43

sorry αλλα ετρωγα.... παω να δω την απαντηση του migf στα if. Παιδια μην σας καθυστερω εγω αν ειναι.... :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
Εκτύπωση

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

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