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

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

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

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

Δημοσίευσηαπό stamatiou » 23 Σεπ 2011, 22:17

@migf1
Συμφωνώ με το Star_Light, ως προς το ότι έχουμε βελτιωθεί κάπως :D Όσο για τη βοήθειά σου θα ήθελα να πω πως αν δεν ήσουν εδώ δεν θα κατάφερνα να μάθω C! :D
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

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

Τελικα εμενα γιατι μου δειχνει τον πινακα αδειο;
Edit:
1. Δηλαδή τέρμα οι ασκήσεις;! :(
2. Διάβασα σε ένα βιβλίο ότι αν δεν έχεις δοκιμάσει debugging μέχρι τώρα, είναι σαν να είσαι γιατρός του 17ου αιώνα που δε χρησιμοποιεί μικροσκόπιο, ισχύει;
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

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

stamatiou έγραψε:Τελικα εμενα γιατι μου δειχνει τον πινακα αδειο;
Edit:
1. Δηλαδή τέρμα οι ασκήσεις;! :(
2. Διάβασα σε ένα βιβλίο ότι αν δεν έχεις δοκιμάσει debugging μέχρι τώρα, είναι σαν να είσαι γιατρός του 17ου αιώνα που δε χρησιμοποιεί μικροσκόπιο, ισχύει;


Γιατι τερμα? Στο ρωτησα και πιο πανω αυτο .
Δεν θα μπορουσε να μείνει αιωνια εδω ο migf1 να κάνει μαθήματα.
Έδωσε κατευθυνσεις ο ανθρωπος , ξηγηθηκε αψογα , εκανε πολυ καλη δουλεια ενω δεν ηταν υποχρεωμενος
και τελος . Δεν μπορουμε να έχουμε εναν migf1 συνεχεια απο πανω να κοιταει εμας. Πρεπει να ασχοληθουμε
και να προπονηθουμε ωστε να αποκτησουμε δικη μας προγραμματιστικη αντιληψη... τα βασικα μας τα ειπε
και παραπανω μας ειπε... η συνεχεια ειναι δικη μας επομενως αραξε και μην αγχωνεσαι :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/C++

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

stamatiou έγραψε:Να με και εγώ! Προσπάθησα να κάνω την append και την prepend αλλά και μου βγήκε ο κώδικας: http://ideone.com/zheFD
Γιατί μου λέει ότι είναι άδειος;

Καλημέρα,

σχετικά με την append σου βγάζει άδειο τον πίνακα διότι αντί να εισαγάγεις το value στη θέση [table->buflen], το εισαγάγεις στην αμέσως επόμενη. Οπότε στη θέση [table->buflen] παραμένει ως τιμή η TABLE_EMPTYCELL ;)

Δυο ακόμα επισημάνεις: α) να αποφεύγεις να χρησιμοποιείς τα ++ και -- ως πρόθεμα μεταβλητών, να τα προτιμάς ως επίθεμα και β) το: [++table->buflen] δεν είμαι σίγουρος αν αυξάνει κατά 1 τον δείκτη table ή το πεδίο buflen (νομίζω τον δείκτη αυξάνει)... ακριβώς επειδή δεν είμαι σίγουρος, και για να μη ψάχνω στα εγχειρίδια, προτιμώ τη σιγουριά του: [ ++(table->buflen) ] το οποίο αυξάνει σίγουρα το πεδίο buflen.

Επίσης, η συνάρτησή σου δεν ελέγχει αν το buffer είναι ήδη γεμάτο πριν επιχειρήσει να εισαγάγει το value. Ούτε ελέγχει αν έστω και κατά λάθος, το table->buflen έχει αρνητική τιμή... περίπτωση κατά την οποία θα προκαλέσει segmentation fault ;)

Και τελος, το: table->bufsize = sizeof(table->buffer) και περιττό είναι, και λάθος. Λάθος είναι διότι το buffer δεν έχει οριστεί ως array, αλλά ως δείκτης που έχει γίνει calloc()... οπότε το sizeof() σου δίνει πάντα το ίδιο νούμερο, που ισούται με τον αριθμό των bytes που καταλαμβάνει ο οποιοσδήποτε δείκτης στην πλατφόρμα σου. Για να βρεις το μέγεθος του buffer σε bytes, πρέπει να κάνεις: table->bufmaxlen * sizeof( int ) ... αλλά δεν το χρειάζεσαι στη συνάρτηση αυτή! Το μέγεθος του buffer σε bytes υπολογίζεται έτσι κι αλλιώς μια φορά στην table_init(), αποθηκεύεται στο table->bufsize και τέρμα.

Ίσως ήθελες να βρεις το μέγεθος σε bytes των γεμάτων στοιχείων του buffer, που ισούται με: table->buflen * sizeof( int ) αλλά αυτή την πληροφορία δεν την χρησιμοποιούμε στην άσκηση.

Παραθέτω τον κώδικα της append...
Κώδικας: Επιλογή όλων

/* --------------------------------------------------------------------------------
*
* --------------------------------------------------------------------------------
*/
Bool table_append_element( Table *table, const int element )
{
if ( !table ) /* έλεγχος ασφαλείας */
return FALSE; /* ... πρόωρη έξοδος */

if ( !table->buffer ) /* το buffer δεν υπάρχει */
return FALSE; /* ... πρόωρη έξοδος */

if ( table->buflen < 0 ) /* αποτροπή άκυρης θέσης */
return FALSE; /* ... πρόωρη έξοδος */

if ( table->buflen == table->bufmaxlen ) /* το buffer είναι γεμάτο */
return FALSE; /* ... πρόωρη έξοδος */

table->buffer[ table->buflen ] = element; /* εισαγωγή του element */
table->buflen++; /* ενημέρωση τρέχοντος μήκους */

return TRUE;
}


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

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

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

Για την prepend, το 1ο που βλέπω είναι πως μέσα στο loop ξεκινάς με: table->buffer[i] = tmp; με το tmp να έχει undefined τιμή!

Όσο για το ίδιο το loop, δεν το έκανα trace (μπορείς να το κάνεις εσύ, είτε με χαρτί & μολύβι, είτε προσθέτοντας printf να σου τυπώνουν τις τιμές των στοιχείων σε ενδιάμεσα στάδια, είτε με debugger).

Για αυτές τις δουλειές πάντως (εννοώ τη μαζική μετακίνηση συνεχόμενων στοιχείων) ο ενδεδειγμένος και μακράν ταχύτερος τρόπος είναι με χρήση της έτοιμης συνάρτησης: memmove... δες επίσης κι εδώ: http://www.java-samples.com/showtutoria ... rialid=591.

Παραθέτω και τον κώδικα της table_prepend_element() για την δική μας περίπτωση...

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

/* --------------------------------------------------------------------------------
*
* --------------------------------------------------------------------------------
*/
Bool table_prepend_element( Table *table, const int element )
{
if ( !table ) /* έλεγχος ασφαλείας */
return FALSE; /* ... πρόωρη έξοδος */

if ( !table->buffer ) /* το buffer δεν υπάρχει */
return FALSE; /* ... πρόωρη έξοδος */

if ( table->buflen < 0 ) /* αποτροπή άκυρης θέσης */
return FALSE; /* ... πρόωρη έξοδος */

if ( table->buflen == table->bufmaxlen ) /* το buffer είναι γεμάτο */
return FALSE; /* ... πρόωρη έξοδος */

/* μετακίνηση στοιχείων δεξιά */
memmove( &table->buffer[1], &table->buffer[0], table->buflen * sizeof(int) );

table->buffer[ 0 ] = element; /* εισαγωγή του element */
(table->buflen)++; /* ενημέρωση τρέχοντος μήκους */

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

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

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

Καλησπερα σε όλους. Προσφατα ανακαλυψα πως μπορεις να δουλευεις - να μαθαινεις και να πληρωνεσαι ταυτοχρονα!!!!

https://www.odesk.com/jobs/c/#filter/?q=c&st=0&skip=10

;)

αυτο ειναι ειδικα για την C!
Γνώσεις ⇛ 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++

Δημοσίευσηαπό stamatiou » 01 Οκτ 2011, 17:12

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

https://www.odesk.com/jobs/c/#filter/?q=c&st=0&skip=10

;)

αυτο ειναι ειδικα για την C!

Εντάξει, δεν μαθαίνεις κιόλας με αυτά! Αυτά είναι για επίπεδο migf1 που λέει ο λόγος! Πάντως για C δεν βλέπω τίποτα, μόνο C# :(
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

Δημοσίευσηαπό stamatiou » 01 Οκτ 2011, 17:20

migf1 έγραψε:
stamatiou έγραψε:Να με και εγώ! Προσπάθησα να κάνω την append και την prepend αλλά και μου βγήκε ο κώδικας: http://ideone.com/zheFD
Γιατί μου λέει ότι είναι άδειος;

Καλημέρα,

σχετικά με την append σου βγάζει άδειο τον πίνακα διότι αντί να εισαγάγεις το value στη θέση [table->buflen], το εισαγάγεις στην αμέσως επόμενη. Οπότε στη θέση [table->buflen] παραμένει ως τιμή η TABLE_EMPTYCELL ;)

Δυο ακόμα επισημάνεις: α) να αποφεύγεις να χρησιμοποιείς τα ++ και -- ως πρόθεμα μεταβλητών, να τα προτιμάς ως επίθεμα και β) το: [++table->buflen] δεν είμαι σίγουρος αν αυξάνει κατά 1 τον δείκτη table ή το πεδίο buflen (νομίζω τον δείκτη αυξάνει)... ακριβώς επειδή δεν είμαι σίγουρος, και για να μη ψάχνω στα εγχειρίδια, προτιμώ τη σιγουριά του: [ ++(table->buflen) ] το οποίο αυξάνει σίγουρα το πεδίο buflen.

Επίσης, η συνάρτησή σου δεν ελέγχει αν το buffer είναι ήδη γεμάτο πριν επιχειρήσει να εισαγάγει το value. Ούτε ελέγχει αν έστω και κατά λάθος, το table->buflen έχει αρνητική τιμή... περίπτωση κατά την οποία θα προκαλέσει segmentation fault ;)

Και τελος, το: table->bufsize = sizeof(table->buffer) και περιττό είναι, και λάθος. Λάθος είναι διότι το buffer δεν έχει οριστεί ως array, αλλά ως δείκτης που έχει γίνει calloc()... οπότε το sizeof() σου δίνει πάντα το ίδιο νούμερο, που ισούται με τον αριθμό των bytes που καταλαμβάνει ο οποιοσδήποτε δείκτης στην πλατφόρμα σου. Για να βρεις το μέγεθος του buffer σε bytes, πρέπει να κάνεις: table->bufmaxlen * sizeof( int ) ... αλλά δεν το χρειάζεσαι στη συνάρτηση αυτή! Το μέγεθος του buffer σε bytes υπολογίζεται έτσι κι αλλιώς μια φορά στην table_init(), αποθηκεύεται στο table->bufsize και τέρμα.

Ίσως ήθελες να βρεις το μέγεθος σε bytes των γεμάτων στοιχείων του buffer, που ισούται με: table->buflen * sizeof( int ) αλλά αυτή την πληροφορία δεν την χρησιμοποιούμε στην άσκηση.

Παραθέτω τον κώδικα της append...
Κώδικας: Επιλογή όλων

/* --------------------------------------------------------------------------------
*
* --------------------------------------------------------------------------------
*/
Bool table_append_element( Table *table, const int element )
{
if ( !table ) /* έλεγχος ασφαλείας */
return FALSE; /* ... πρόωρη έξοδος */

if ( !table->buffer ) /* το buffer δεν υπάρχει */
return FALSE; /* ... πρόωρη έξοδος */

if ( table->buflen < 0 ) /* αποτροπή άκυρης θέσης */
return FALSE; /* ... πρόωρη έξοδος */

if ( table->buflen == table->bufmaxlen ) /* το buffer είναι γεμάτο */
return FALSE; /* ... πρόωρη έξοδος */

table->buffer[ table->buflen ] = element; /* εισαγωγή του element */
table->buflen++; /* ενημέρωση τρέχοντος μήκους */

return TRUE;
}


ΥΓ. Για την prepend() θα σου γράψω λίγο πιο μετά, γιατί έχω λίγη δουλίτσα τώρα.
migf1 έγραψε:Για την prepend, το 1ο που βλέπω είναι πως μέσα στο loop ξεκινάς με: table->buffer[i] = tmp; με το tmp να έχει undefined τιμή!

Όσο για το ίδιο το loop, δεν το έκανα trace (μπορείς να το κάνεις εσύ, είτε με χαρτί & μολύβι, είτε προσθέτοντας printf να σου τυπώνουν τις τιμές των στοιχείων σε ενδιάμεσα στάδια, είτε με debugger).

Για αυτές τις δουλειές πάντως (εννοώ τη μαζική μετακίνηση συνεχόμενων στοιχείων) ο ενδεδειγμένος και μακράν ταχύτερος τρόπος είναι με χρήση της έτοιμης συνάρτησης: memmove... δες επίσης κι εδώ: http://www.java-samples.com/showtutoria ... rialid=591.

Παραθέτω και τον κώδικα της table_prepend_element() για την δική μας περίπτωση...

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

/* --------------------------------------------------------------------------------
*
* --------------------------------------------------------------------------------
*/
Bool table_prepend_element( Table *table, const int element )
{
if ( !table ) /* έλεγχος ασφαλείας */
return FALSE; /* ... πρόωρη έξοδος */

if ( !table->buffer ) /* το buffer δεν υπάρχει */
return FALSE; /* ... πρόωρη έξοδος */

if ( table->buflen < 0 ) /* αποτροπή άκυρης θέσης */
return FALSE; /* ... πρόωρη έξοδος */

if ( table->buflen == table->bufmaxlen ) /* το buffer είναι γεμάτο */
return FALSE; /* ... πρόωρη έξοδος */

/* μετακίνηση στοιχείων δεξιά */
memmove( &table->buffer[1], &table->buffer[0], table->buflen * sizeof(int) );

table->buffer[ 0 ] = element; /* εισαγωγή του element */
(table->buflen)++; /* ενημέρωση τρέχοντος μήκους */

return TRUE;
}

Οκ, το ομολογώ, τις είχα σκοτώσει τις συναρτήσεις! :lol:
Τις διόρθωσα αλλά κάπου έχω ένα πρόβλημα (μάλλον στη main) και όταν εισάγω 2 στοιχεία εισάγω μόνο το 2ο.... :problem:
Επίσης, βρήκα ένα tutorial για debugging: http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Debug.html
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

Δημοσίευσηαπό stamatiou » 01 Οκτ 2011, 21:42

Γίνεται με την memmove να μετακινήσω τα στοιχεία ενός πίνακα προς τα αριστερά;
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 02 Οκτ 2011, 07:39

Γίνεται να μετακινήσεις όπου θέλεις με την memmove()... π.χ. το αριστερά θα σου χρειαστεί για την table_delete_element(table, element);

Για debugging, εγώ πάω στα Windows και χρησιμοποιώ τον ενσωματωμένο debugger της Pelles-C... στα Project Options, ενεργοποιείς το debug-info στον compiler, assembler και linker (έχει σχετικές επιλογές για το καθένα από αυτά) και μετά απλά κάνεις compile. Κατόπιν βάζεις με δεξί κλικ breakpoints στα σημεία που θες να σταματάει το πρόγραμμά σου για να εξετάζεις τις τιμές των μεταβλητών, και αντί για Run διαλέγεις Go Debug.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

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