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

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

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

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

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

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

#include <stdio.h>
#define N 254 + 1
typedef struct person
{
int age;
char name[N];
char surname[N];
} kostas ;

void struct_function(kostas *someone);


int main(void)
{

kostas someone;

//p=&someone;

struct_function(&someone) ;

printf("%d", someone.age);

return 0;
}

void struct_function(kostas *someone)
{


printf("Dwse to onoma sou: ");
fgets(someone->name,254,stdin);

printf("Dwse to epwnumo sou: ");
fgets(someone->surname,254,stdin);

printf("Dwse tin ilikia sou: ");
scanf("%d",&(*someone).age);


printf("========================================");

printf("\nTo onoma pou edwses einai: %s",someone->name);
printf("H ilikia pou edwses einai: %d",someone->age);
printf("\nTo epwnimo pou edwses einai: %s",someone->surname);

}



Η διορθωμενη εκδοση της αρχικα μπερδεμενης μου σκεψης :lol: :lol:

Τα λεμε μετα της 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++

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


Είσαι ωραίος Γιώργο :)

Έχουμε 2 προβλήματα όμως!

Το ένα είναι πως εφόσον την τιμή επιστροφή της συνάρτησης την ορίσαμε να είναι Bool, οι τιμές που επιστρέφουμε θα πρέπει να είναι είτε TRUE είτε FALSE, σύμφωνα με το σχετικό typedef στην αρχή του αρχείου. Βέβαια καταλαβαίνω τη λογική σου να επιστρέφεις διαφορετικές ακέραιες τιμές ανάλογα με την περίπτωση (για να μπορείς π.χ εξετάζοντας την τιμή επιστροφής της συνάρτησης να καταλαβαίνεις και τι λάθος προέκυψε, απλά έχω προτιμήσει να το κρατήσω πιο απλό) αλλά ακόμα κι έτσι το έχεις λάθος. Η συνάρτηση πρέπει να επιστρέφει ΣΦΑΛΜΑ (δηλαδή FALSE, δηλαδή 0) όταν κάτι πήγε στραβά, κι ΕΠΙΤΥΧΙΑ (δηλαδή TRUE, δηλαδή 1) όταν όλα πήγαν καλά.

Εσύ λοιπόν όταν κάτι δεν πήγε καλά επιστρέφεις 1 (πρόβλημα ασφαλείας) ή 2 (γεμάτος πίνακας). Και το 1 και το 2 είναι ΜΗ-ΜΗΔΕΝ που στην ουσία μεταφράζεται σε TRUE. Εκεί και στις δυο περιπτώσεις πρέπει να επιστρέψεις FALSE (που σύμφωνα με το typedef enum στην αρχή του αρχείου ισούται με 0) κι ας μην μπορούμε να διαχωρίσουμε ποιο από τα 2 σφάλματα προέκυψε. Αυτό που προέχει είναι να σηματοδοτήσουμε ότι προέκυψε σφάλμα!

Ομοίως πρέπει να αλλάξεις την τιμή του τελευταίου return από 0 σε TRUE (που σύμφωνα με το typedef enum στην αρχή του αρχείου ισούται με 1) για να σηματοδοτήσεις πως το γέμισμα ολοκληρώθηκε επιτυχώς.

Έτσι όπως τα έχει τώρα, το ! στο...

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

if ( !table_fill_randomly( &table, 234 ) )
puts("*** σφάλμα τυχαίου γέμισματος του πίνακα ( ήταν ήδη γεμάτος; )\n");

της main() δουλεύει ανάποδα από ότι πρέπει.

Π.χ. αν ο πίνακας είναι γεμάτος, η συνάρτησή σου επιστρέφει τώρα 2... για τον compiler οτιδήποτε δεν είναι 0 θεωρείται TRUE, οπότε η συνθήκη αξιολογείται ως !TRUE, δηλαδή ως FALSE. Άρα δεν θα μπει μέσα στο if, παρόλο που κανονικά εκεί ακριβώς έπρεπε να μπει :)

Το επόμενο σφάλμα είναι πως δεν ενημερώνεις το table->buflen μετά το επιτυχές γέμισμα του buffer ;)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

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

Star_Light έγραψε: scanf("%d",&(*someone).age);
Star_Light έγραψε:
Spoiler: show
Κώδικας: Επιλογή όλων

#include <stdio.h>
#define N 254 + 1
typedef struct person
{
int age;
char name[N];
char surname[N];
} kostas ;

void struct_function(kostas *someone);


int main(void)
{

kostas someone;

//p=&someone;

struct_function(&someone) ;

printf("%d", someone.age);

return 0;
}

void struct_function(kostas *someone)
{


printf("Dwse to onoma sou: ");
fgets(someone->name,254,stdin);

printf("Dwse to epwnumo sou: ");
fgets(someone->surname,254,stdin);

printf("Dwse tin ilikia sou: ");
scanf("%d",&(*someone).age);


printf("========================================");

printf("\nTo onoma pou edwses einai: %s",someone->name);
printf("H ilikia pou edwses einai: %d",someone->age);
printf("\nTo epwnimo pou edwses einai: %s",someone->surname);

}



Η διορθωμενη εκδοση της αρχικα μπερδεμενης μου σκεψης :lol: :lol:

Τα λεμε μετα της 10. Παω για μαθημα ΑΓγλικα.

Πολύ καλύτερα :)

Όμως αυτό: scanf("%d",&(*someone).age);
κάνε το : scanf("%d",&someone->age);
ή έστω : scanf("%d",&(someone->age) );

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

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

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

migf1 έγραψε:

Είσαι ωραίος Γιώργο :)

Έχουμε 2 προβλήματα όμως! ...

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

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

Δημοσίευσηαπό stamatiou » 12 Σεπ 2011, 19:36

Άρα πρέπει να γίνει έτσι:
Spoiler: show
Κώδικας: Επιλογή όλων

Bool table_fill_randomly( Table *table, const int maxval ) {
int i;
if(!table || !table->buffer) {
printf("ΠΑΡΟΥΣΙΑΣΤΗΚΕ ΣΦΑΛΜΑ!");
return FALSE;
}else if(table->buflen == table->bufmaxlen) {
printf("Ο ΠΙΝΑΚΑΣ ΕΙΝΑΙ ΓΕΜΑΤΟΣ!");
return FALSE;
}

for(i = table->buflen;i < table->bufmaxlen;i++) {
table->buffer[i] = rand() % maxval+1;
}
return TRUE;
}
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

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

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

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

Δημοσίευσηαπό stamatiou » 12 Σεπ 2011, 19:47

migf1 έγραψε:Ναι, αλλά πάλι δεν ενημερώνεις το table->buflen (κι επίσης πάλι έχεις εκείνο το περιττό else μετά από return).

:oops: Ας κάνω άλλη μια προσπάθεια να δω τι ξέχασα πάλι :D
Spoiler: show
Κώδικας: Επιλογή όλων
Bool table_fill_randomly( Table *table, const int maxval ) {
int i;
if(!table || !table->buffer) {
printf("ΠΑΡΟΥΣΙΑΣΤΗΚΕ ΣΦΑΛΜΑ!");
return FALSE;
}

if(table->buflen == table->bufmaxlen) {
printf("Ο ΠΙΝΑΚΑΣ ΕΙΝΑΙ ΓΕΜΑΤΟΣ!");
return FALSE;
}

for(i = table->buflen;i < table->bufmaxlen;i++) {
table->buffer[i] = rand() % maxval+1;
}
table->buflen = table->bufmaxlen;
return TRUE;
}
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

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

Αυτό ήταν ! :clap: :clap: :clap:

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

Bool table_fill_randomly( Table *table, const int maxval )
{
register int i = 0; /* μετρητής για το buffer */

if ( !table ) /* έλεγχος ασφαλείας */
return FALSE; /* ... πρόωρη έξοδος */

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

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

for (i=table->buflen; i < table->bufmaxlen; i++)/* γέμισμα buffer με τυχαίους */
table->buffer[i] = rand() % (maxval + 1);

table->buflen = table->bufmaxlen; /* ενημέρωση τρέχοντος μήκους */

return TRUE;
}

Η μόνη διαφορά με τον δικό σου είναι πως δεν γράφω μηνύματα σφάλματος μέσα από την συνάρτηση (για να είναι πιο εύκολο να απομονώσουμε αργότερα το περιβάλλον επικοινωνίας με τον χρήστη -user interface- από τον πυρήνα του προγράμματος ;) )

Λοιπόν, μέχρι να το προσπαθήσει κι ο Star_Light, έχω κάτι αρκετά πιο δύσκολο τώρα... μια βελτιωμένη έκδοση αυτής της συνάρτησης, που τα τυχαία νούμερα που θα παράγει θα είναι μοναδικά!

Κώδικας: Επιλογή όλων
Bool table_fill_unique_randomly( Table *table, int maxval );

Αυτόματα αυτό σημαίνει πως η τιμή του ορίσματος maxval δεν μπορεί να είναι μικρότερη από το πλήθος των κενών στοιχείων του buffer μας. Διότι φανταστείτε π.χ. έναν κενό πίνακα μέγιστης χωρητικότητας 10 στοιχείων, που θέλουμε να τον γεμίσουμε με μοναδικούς τυχαίους αριθμούς από το 8 και κάτω. Μόλις συμπληρωθούν τα 8 πρώτα του στοιχεία, δεν θα υπάρχουν άλλοι τυχαίοι αριθμοί ;)

Άρα η συνάρτησή μας πρέπει να εξετάζει αυτή την περίπτωση και να "αντιδράει" με κάποιον λογικό και λειτουργικό τρόπο. Ένας τέτοιος τρόπος είναι να επιστρέφει σφάλμα (FALSE). Ένας άλλος πολύ πιο έξυπνος τρόπος είναι όταν χρειάζεται, να προσαρμόζει αυτόματα την τιμή του maxval ώστε να ισούται με το πλήθος των κενών κελιών του πίνακα, πριν αρχίσει να τα γεμίζει με τυχαία νούμερα.

Αυτό θέλουμε να κάνει η συνάρτησή μας :)

Τώρα, σε ότι αφορά την μοναδικότητα του κάθε παραγόμενου τυχαίου αριθμού (από 0 έως maxval, συμπεριλαμβανομένων) θα μπορούσα να σας αφήσω να σκεφτείτε μόνοι σας πως θα το καταφέρετε, αλλά νομίζω πως ακόμα δεν έχετε αναπτύξει τέτοια αλγοριθμική σκέψη. Οπότε, θα σας περιγράψω τον αλγόριθμο και σεις θα προσπαθήσετε να τον υλοποιήσετε.

Ένας ΑΡΓΟΣ τρόπος είναι για κάθε παραγόμενο τυχαίο νούμερο που θέλετε να βάλετε σε ένα κενό στοιχείο του πίνακα, να ψάχνετε πρώτα στα γεμάτα στοιχεία του για να δείτε αν υπάρχει ήδη. Αν υπάρχει θα επαναλαμβάνετε τη διαδικασία μέχρι το παραγόμενο τυχαίο νούμερο να μην υπάρχει ήδη, οπότε θα μπορείτε να το αναθέσετε στο κενό στοιχείο που βρίσκεστε, και να πάτε στο επόμενο.

Όπως καταλαβαίνουμε, για κάθε παραγόμενο τυχαίο νούμερο πρέπει να εξετάζουμε όλο τον πίνακα! ΘΑΝΑΤΟΣ :lol:

Υπάρχει πολύ πιο γρήγορος τρόπος! Μέσα στη συνάρτηση θα ορίσετε έναν τοπικό πίνακα με στοιχεία τύπου Bool, που θα τον ονομάσετε usedvals...

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

Bool table_fill_unique_randomly( Table *table, int maxval )
{
Bool *usedvals = NULL;
...

Θα τον βάλετε να έχει μέγιστο πλήθος στοιχείων όσα είναι τα νούμερα μέσα από τα οποία θα επιλέγονται οι τυχαίοι αριθμοί. Για παράδειγμα, αν οι τυχαίοι αριθμοί επιλέγονται από το 0 έως το 100, τότε το μέγιστο πλήθος στοιχείων του usedvals θα πρέπει να είναι 101 στοιχεία (δλδ από το 0 έως το και 100).

Έχουμε λοιπόν έναν πίνακα από Bool στοιχεία, με το καθένα τους να αντιστοιχεί σε έναν από τους τυχαίους μας αριθμούς. Θα αρχικοποιήσετε όλα τα στοιχεία με την τιμή FALSE, που σημαίνει πως κανένα από αυτά τα νούμερα δεν έχει χρησιμοποιηθεί ακόμα!

Τώρα, όταν αρχίσετε να παράγετε τυχαία νούμερα για να τα βάλετε στα κενά κελιά του buffer, για καθένα από αυτά τα νούμερα θα εξετάζετε αν το κελί του στον πίνακα usedvals περιέχει την τιμή FALSE ή την τιμή TRUE. Αν περιέχει την τιμή TRUE σημαίνει πως έχει ήδη χρησιμοποιηθεί, άρα θα παράξετε νέο τυχαίο νούμερο και θα επαναλάβετε τον έλεγχο. Αν όμως περιέχει την τιμή FALSE, τότε σημαίνει πως το συγκεκριμένο νούμερο δεν έχει χρησιμοποιηθεί, άρα θα αλλάξετε την τιμή που του αντιστοιχεί στον usedvals σε TRUE και θα αναθέσετε το τυχαίο σας νούμερο στο κενό κελί του buffer που θα βρίσκεστε εκείνη τη στιγμή! Και θα πάτε στο επόμενο κενό κελί του table->buffer.

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

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

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

Ηello Here! :P

Τι να λυσει ο Star_LIght???? Γιατι χαθηκα μεσα στα συμβολα χθες :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 » 13 Σεπ 2011, 17:57

επισης μια παρατηρηση

Το

Κώδικας: Επιλογή όλων
typedef struct person
{..... members of structure .....
} kostas;


ειναι αχρειαστο ή καλυτερα ειναι πλεονάζον.

οριστε μια διορθωση του

Κώδικας: Επιλογή όλων
typedef struct {
.... members of structure ....
} kostas ;
Γνώσεις ⇛ 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
Εκτύπωση

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

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