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

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

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

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

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

migf1 έγραψε:
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 αλλά αμέσως μετά πάει στους αμέσως επόμενους χαρακτήρες.


Μαλιστα... δηλαδη αν υποθέσουμε πως έχουμε μια while και μεσα της μια if εστω οτι παμε με τον παλιο ισχυρισμο οτι δηλαδη αν ο δεικτης δειχνει ... |αφου δεν δειχνει| επομενως ΟΣΟ ΔΕΝ δειχνει...... οκ τωρα το δεχομαι. ΑΠλα επρεπε να κάνω εναν "λογισμο" και μια συνθεση στις προτασεις πρωτα. Επομενως παω να κανω ενα ακομη trace για την 2η φάση μετα το (a-a) που εδειξα παραπανω.
Γνώσεις ⇛ 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 » 02 Σεπ 2011, 18:15

migf1 έγραψε:


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


Ειναι σαν να θέλουμε να συγκρίνουμε τον ρυθμό με τον οποίο περπατάνε 2 άτομα Α και Β. Το s1++ ωθει το ατομο Α να κανει ενα βημα ενω το s2++ ωθει το ατομο Β να κανει ενα αλλο βημα. Αν μονο το ατομο Β κανει βηματα προς τα εμπρος (μονο αυτου ο δεικτης αυξανεται κατα 1) και οχι του Α τοτε η συγκριση δεν θα ειναι αξιοπιστη.

Π.Σ Περιμενω τον υπερ-δασκαλο της C κυριο κυριο migf1 να επιβεβαιωσει ωστε να δωσω την 2η φαση του trace και στην συνεχεια να φυγω σφαιρατος να καθαρισω το δωματιο μου γιατι βρωμοκοπαει και δεν ειναι καταλληλο για επισκέψεις απο κοπελες :lol: :lol:
Γνώσεις ⇛ 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 » 02 Σεπ 2011, 18:57

να ρωτησω και κατι ακομα... το

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


μπορεις να θεωρησεις πως ειναι ισοδυναμο με

Κώδικας: Επιλογή όλων
for(s1; *s1==*s2; 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, 18:58

:lol:

Ναι κάπως έτσι είναι, με τον βηματισμό που είπες. Αλλά γιατί σε δυσκολεύει ακόμα τόσο πολύ; Δεν σε βοηθάει αυτό που σας έγραψα, το ότι δηλαδή να φαντάζεστε τα s σαν βελάκια και τα *s σαν χαρακτήρες;

char *s1[] = "abcd", s2[] = "ab";
Κώδικας: Επιλογή όλων

s1
|
abcd\0 ab\0
|
s2

s1++;
Κώδικας: Επιλογή όλων

s1
|
abcd\0 ab\0
|
s2

s2++;
Κώδικας: Επιλογή όλων

s1
|
abcd\0 ab\0
|
s2

ΥΓ. Ναι, ισοδύναμα είναι αυτά που ρώτησες στο επόμενο ποστ (γιατί δεν τα δοκιμάζεις επιτόπου με κώδικα μόνος σου; )
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, 19:33

Οχι δεν ειναι τοσο δυσκολα... ουτε σημαινει πως επειδη εδωσα αυτο το παραδειγμα πως μου ειναι ακομη δυσκολο απλα για να καταλαβει και καποιος που δεν έχει διαβασει εξαρχης την συζητηση μας και ενδιαφερεται + επειδη το καταλαβα πολυ καλα ηθελα να το πω με πιο δικα μου λογια ;)

Τον κωδικα δεν τον δοκιμαζω επιτοπου γιατι ειπες να το κανουμε με χαρτι και μολυβι και πραγματικα ετσι καταλαβαινω πως ειναι το καλυτερο...
παιδευτεο μεν... καλυτερο δε.
Γνώσεις ⇛ 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 » 02 Σεπ 2011, 19:38

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

Spoiler: show
Κώδικας: Επιλογή όλων
#include <stdio.h>
int raiseToPower(int basen, int n);

int main()
{

int basen, n;
int z,i;

printf("\nPoses dunameis arithmwn thelete na upologisete? \n");
scanf("%d",&z);

for(i=0; i<z; i++)
{
printf("Give the base: ");
scanf("%d",&basen);
printf("Give the exponent: ");
scanf("%d",&n);
if(n<0)
{
printf("\n Invalid value \n");
z++; // An o xristis dwsei 2 fores upologismo kai h 1 einai me arnitiki dunami tote
// Exei invalid value kai oi 2 fores diathrounte se sugrisi me prin pou eixe mono alli 1
// enw kanonika eixe dwsei 2 kai athela tou evale enan arnhtiko arithmo san ektheti
continue;
}
printf("The result is : %d^%d = %d\n", basen, n, raiseToPower(basen, n));
}


return 0;
}


int raiseToPower(int basen, int n )
{

if(n==0)
return 1;

return( basen * raiseToPower(basen, n-1) );
}


Λοιπον αυτος ο κωδικας... καταρχην ειναι παρμενος ετοιμος αλλα του εχω βαλει οταν ο χρηστης ζηταει υπολογισμο 2 φορες σε μια δυναμη
ακομη και αν εχει δωσει invalid τιμη (αρνητικο εκθετη - υποθετουμε πως δεν ειναι σκοπος του προγραμματος να υπολογιζει αρνητικους εκθετες ) τοτε παραμενει ο αριθμος του υπολογισμου της συναρτησης σε 2 και οχι σε 1 (1 ακυρη + 1 εγκυρη) :D

συνεχιζουμε..... μετα απο αυτο το "break" :lol: :lol:
Γνώσεις ⇛ 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 » 02 Σεπ 2011, 20:02

λοιπον συνεχίζω με τα test cases (ομολογω πως μπερδευτηκα λιγο σε καποια σημεια) θα τα γραψω τελειως αναλυτικα... καταρχην εχω κανει τα 3 test cases που προτεινει ο migf1 στην viewtopic.php?f=6&t=18969&start=1060

δηλαδη τα

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


s1[]="a" , s2[]="a"

s1[]="a" , s2[]="b"

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



Το 1ο το έφτιαξα πριν και ηταν σωστο τα αλλα 2 παμε να δουμε τωρα....

Καταρχην στο 2ο case τα a & b δεν ειναι ομοια επομενως επομενο loop δεν θα υπάρξει απο το while. Στη συνεχεια το *s2 αυξανει και δείχνει στον κενό χαρακτήρα? ΑΝ υποθέσουμε οτι

Κώδικας: Επιλογή όλων
s2->b\0

(αρχικα) τοτε μετα την αύξηση θα ειναι b\0 <-b2 (τα έβαλα ετσι επειδη αν τα κανω οπως τα κανε ο migf απο πανω να δειχνουν δηλαδη μου πανε στον γαμο του καραγκιοζη... τα βελακια

εκτος και αν εξαρχης δεν δειχνουν κάπου και τους βάζουμε μετα την αύξηση να δειχνουν σε κατι (a & b αντιστοιχα) αλλα κατι τετοιο αποκλειεται να το εκανε ο migf1 γιατι παλιοτερα μας εχει πει πως δεν ειναι συνετο να χρησιμοποιεις δεικτες αν δεν τους εχεις αρχικοποιησει δηλαδη να δειχνουν καπου...
Μπαινει στο if μετα και επειδη δειχνει ακομη στο a και οχι στο \0 συνεχιζει αυξάνοντας τον s1 να δείχνει στον κενο παλι? και αυτος?

οποτε συμφωνα με την

Κώδικας: Επιλογή όλων
return (int)(*s1- *--s2);

τι κάνει? \0 - b ? :S

στο 3ο case εχω ακριβως το ιδιο προβλημα και τελικα παλι καταληγω και εκει σε αφαιρεση του στυλ

\0 - a

μου θυμισε οταν ημουν φοιτητης που στην Μαθηματικη αναλυση κατεληγα σε πράξεις της μορφης

απειρο - πραγματικος κτλπ :lol: :lol: :lol:

απειρο / απειρο κτλπ.
Γνώσεις ⇛ 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, 20:19

Στο 2ο test-case ( s1[]="a", s2[]="b"; ) ΔΕΝ μπαίνει καν στο if !!!!!!!!!!!!

Έχουμε...
Κώδικας: Επιλογή όλων

...
while ( *s1 == *s2++)
if ( *s1++ == '\0')
return;
return (int) (*s1 - *--s2 );

Ξεκινάμε λοιπόν με *s1: a και *s2: b

α) Η συνθήκη του while-loop είναι απευθείας FALSE διότι: a != b άρα δεν πάει καν στο if, απλά αυξάνει το s2 (οπότε έχουμε *s2: \0) και πάει στη γραμμή της αφαίρεσης.
β) Εκεί λοιπόν έχουμε *s1: a και *s2: \0 και πριν ξεκινήσει η αφαίρεση ο s2 μετακινείται λόγω του -- μια θέση πίσω, άρα *s2: b ... οπότε η αφαίρεση που εκτελείται τελικά κι επιστρέφεται ως αποτέλεσμα είναι η: a - b
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, 20:27

α ναι... Δεν πηρα πρεφα το σωμα της while που ουσιαστικα ειναι το if. Για αυτο την πάτησα.
Γνώσεις ⇛ 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, 20:28

Btw, υπάρχουν και περιπτώσεις που θα γίνει αφαίρεση του στυλ: \0 - a ... ή του στυλ: a - \0 ... το \0 έχει ASCII code 0, οπότε μπορεί και συμμετέχει κανονικότατα ως όρος της αφαίρεσης.

Όπως το 'a' ισούται με 65 στο ASCII table έτσι και το '\0' ισούται με 0 στο ASCII table. Και μάλιστα για αυτόν ακριβώς τον λόγο όταν έχουμε κάτι σαν αυτό:
Κώδικας: Επιλογή όλων
if ( *s == '\0' ) ...

μπορούμε να το συμπτύσσουμε σε:
Κώδικας: Επιλογή όλων
if ( *s == 0 ) ...

Κώδικας: Επιλογή όλων
if ( *s == false ) ...

Κώδικας: Επιλογή όλων
if ( *s == !true) ...

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

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

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