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

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

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

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

Δημοσίευσηαπό evolgen » 27 Ιούλ 2011, 16:32

migf1 έγραψε:Ή μπορούμε να πιάνουμε μια ενότητα και να προσπαθούμε να λύσουμε όλες ή τις περισσότερες από τις ασκήσεις που έχουν για αυτή την ενότητα τα links που δώσαμε παραπάνω.

Βασικά, επειδή δεν είμαι στο επίπεδο του migf1, ούτε κατά διάνοια και επειδή οι ασκήσεις που σκέφτηκα συνδυάζουν χρήση πινάκων μαζί με for και while, το οποίο ίσως είναι λίγο too much για τώρα, λέω να παραχωρήσω τις ασκήσεις στο migf1, που μπορεί και να τις οργανώσει καλύτερα.
Το να μειώνεις ένα έργο ελεύθερου λογισμικού, επειδή θεωρείς το δικό σου καλύτερο,
είναι απαράδεκτη συμπεριφορά και δε συμβαδίζει με τις αρχές του ελεύθερου λογισμικού.

Γνώσεις Linux: Μέτριο++ ┃ Προγραμματισμός: Perl, R, Python, SQL, C, Common Lisp, BashΑγγλικά: Άριστα

1. Ubuntu 14.04 trusty
2. Intel Core i7-3520M CPU @ 2.90GHz ‖ RAM 7892 MiB
3. Intel 3rd Gen Core processor Graphics Controller [8086:0166] {i915}
4. eth0: Broadcom NetXtreme BCM57765 Gigabit Ethernet PCIe [14e4:16b4] (rev 10) ⋮ eth1: Broadcom BCM4331 802.11a/b/g/n [14e4:4331] (rev 02)
Άβαταρ μέλους
evolgen
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 1031
Εγγραφή: 28 Ιούλ 2010, 14:22
Τοποθεσία: UK
IRC: bioevolgenec
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 27 Ιούλ 2011, 16:39

Οπότε, να μια ωραία και πολύ χρήσιμη 1η άσκηση:

Χρησιμοποιώντας την s_get() όσες φορές θέλετε για να διαβάζετε γραμμές εισόδου μέσα σε ένα string, διαβάστε από την κύρια είσοδο:
α) έναν χαρακτήρα, και τυπώστε τον
β) δυο int και τυπώστε το γινόμενό τους
γ) 2 long και τυπώστε το άθροισμα τους
δ) 2 float και τυπώστε το αποτέλεσμα της διαίρεσής του

Η συνάρτηση: s_get() (δεν χρειάζεται να καταλάβετε πως δουλεύει ο κώδικάς της, απλά χρησιμοποιήστε την ! )
Κώδικας: Επιλογή όλων

// -----------------------------------------------------------------------------
// Διάβασμα της γραμμής εισόδου στο string s (μέχρι len-1 χαρακτήρες)
//
char *s_get(char *s, size_t len)
{
char *cp;
for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ )
; // for-loop with empty body
*cp = '\0'; // null-terminate last character

return s;
}


EDIT:

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

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

Δημοσίευσηαπό migf1 » 27 Ιούλ 2011, 16:45

Hints:
για τις μετατροπές των strings εισόδου σε int, long και float χρησιμοποιήστε τις στάνταρ συναρτήσεις: atoi, atol και atof (#include <stdlib.h>): http://en.wikipedia.org/wiki/Stdlib.h
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό stamatiou » 27 Ιούλ 2011, 17:37

migf1 έγραψε:
Star_Light έγραψε:BΑΣΙΚΑ εγω εχω ξεκινησει και λυνω τις ασκησεις του βιβλιου του Γκιουρδα μαθετε την C σε 24 ωρες... το ειχα βγαλει σαν θεωρια (και λιγο απο ασκησεις φετος το χειμωνα) και τωρα πιανω οσες δεν ειχα κανει... εχει 24 ενοτητες... συνολικα χθες το επιασα... και εχω φτασει στην 8 :D

εχω μια απορια ομως...

Κώδικας: Επιλογή όλων
#include<stdio.h>
int main()
{
int x=' ';

printf("To programma tha sunexizei tin ektelesi tou mexri na dwsete ton xaraktira K \n\n");



while(x!='K')
{
printf("Dwste enan xaraktira H TO K GIA termatismo: ");
x=getchar();
putchar(x);
}

return 0;
}



ξερω πως αν βγαλω την printf εξω απο την while θα δουλευει καλα... αλλα τωρα δεν μπορω να καταλαβω γιατι ενω την εχω μεσα την βγαζει διπλη... πχ αντι να σου ζηταει μια φορα να εισαγεις εναν χαρακτηρα εμφανιζει το μηνυμα "Dwste enan xaraktira H TO K GIA termatismo: "

2 φορες :/

Υποφέρει από το πρόβλημα με τα απομεινάρια στο input buffer της κύριας εισόδου. Δυστυχώς από τη στιγμή που σε περιβάλλον Posix η fflush(stdin) δεν λειτουργεί, ή θα πρέπει να δοκιμάζετε τις ασκήσεις σε Windows προσθέτοντας ένας fflush(stdin) πριν από κάθε getchar() (ή πριν από κάθε scanf() ή οποιαδήποτε στάνταρ συνάρτηση διαβάσματος) ή θα πρέπει να απενεργοποιήσετε το line-buffering της κύριας εισόδου στο τερματικό σας (αυτό όμως δεν θα δουλεύει σε Windows).

Ένας τρόπος για να δουλεύει παντού είναι να διαβάζουμε την κάθε γραμμή της κύριας εισόδου μονοκόματα σε ένα δικό μας string (είτε με fgets() είτε καλύτερα με την s_get() που έχω δώσει κώδικα πολλές φορές) και κατόπιν να διαχειριζόμαστε μόνοι μας τις όποιες μεταβλητές θέλουμε να ξεχωρίσουμε από τη γραμμή που διαβάσαμε.

Για διάβασμα απλών χαρακτήρων από την κύρια είσοδο, όπως είναι το παράδειγμα που δίνεις, ευτυχώς αυτό δεν είναι και τόσο δύσκολο να το κάνουμε. Αντί να διαβάζουμε το x με getchar() ως char θα τον διαβάζουμε ως μεγάλο string μεγάλου (255 ωφέλιμων χαρακτήρων) και απλά μετά θα χρησιμοποιούμε τον 1ο του χαρακτήρα για τη σύγκριση στο while-loop.

Δηλαδή (άσχετο: έβαλα κι ένα \n μπροστά, στο printf() μέσα στο while, για να αφήνει γραμμή πριν τυπώσει):
Κώδικας: Επιλογή όλων

#include<stdio.h>
int main( void )
{
char x[255+1] = "";

printf("To programma tha sunexizei tin ektelesi tou mexri na dwsete ton xaraktira K \n\n");

while( x[0] != 'K')
{
printf("\nDwste enan xaraktira H TO K GIA termatismo: ");
fgets(x, 256, stdin);
putchar( x[0] );
}

return 0;
}


Ή επειδή σε ένα οποιοδήποτε string αν βάλουμε ένα αστέρι μπροστά από το όνομά του αναφερόμαστε ουσιαστικά στον 1ο του χαρακτήρα, το παραπάνω μπορούμε να το γράψουμε και ως εξής:
Κώδικας: Επιλογή όλων

#include<stdio.h>
int main( void )
{
char x[255+1] = "";

printf("To programma tha sunexizei tin ektelesi tou mexri na dwsete ton xaraktira K \n\n");

while( *x != 'K')
{
printf("\nDwste enan xaraktira H TO K GIA termatismo: ");
fgets(x, 256, stdin);
putchar( *x );
}

return 0;
}


Χρησιμοποιήστε όποιο από τα 2 καταλαβαίνετε καλύτερα!

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

1. τον ορισμό μια σταθεράς για το μέγιστο μήκος της γραμμής εισόδου, συμπεριλαμβανομένου του '\0' στο τέλος (πάντα μεγάλο μήκος, π.χ. 255+1)
2. τη συνάρτηση s_get() (χρησιμοποιήστε την έτοιμη όπως σας την δίνω, απλά την κάνετε copy & paste σε όλα σας τα προγράμματα)
3. χρήση ενός string για το διάβασμα κάθε εισόδου από το χρήστη.
4. γέμισμα των μεταβλητών σας από τα κομμάτια της γραμμής εισόδου που διαβάσετε από τον χρήστη

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

#include<stdio.h>

#define MAXINBUF (255+1) // μέγιστο μήκος γραμμής εισόδου

// -----------------------------------------------------------------------------
// Διάβασμα της γραμμής εισόδου στο string s (μέχρι len-1 χαρακτήρες)
//
char *s_get(char *s, size_t len)
{
char *cp;
for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ )
; // for-loop with empty body
*cp = '\0'; // null-terminate last character

return s;
}

// -----------------------------------------------------------------------------
int main( void )
{
char inbuf[ MAXINBUF ] = ""; // string για μονοκόμματο διάβασμα γραμμής εισόδου
char x = ' ';

printf("To programma tha sunexizei tin ektelesi tou mexri na dwsete ton xaraktira K \n\n");

while( x != 'K')
{
printf("\nDwste enan xaraktira H TO K GIA termatismo: ");
s_get(inbuf, MAXINBUF); // διάβασμα γραμμής εισόδου στο inbuf
x = *inbuf; // κρατάμε στη μεταβλητή μας μόνο ότι χρειαζόμαστε
putchar( x );
}

return 0;
}


Για να μετατρέπετε το string της γραμμή εισόδου σε int χρησιμοποιήστε την: atoi(), για float/double την atof(), για long την atol().

Στην sget σε τι χρησιμεύει το (cp-s) < len-. Επίσης το cp είναι array; Γιατί αν δεν έιναι γιατί έχεις και το cp++;
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 27 Ιούλ 2011, 17:47

Φίλε Σταματίου, μην προσπαθείς να καταλάβεις πως δουλεύει η s_get() θα μπερδευτείς χειρότερα! Απλά χρησιμοποίησέ την όπως τη δίνω για να κάνεις την άσκηση που έχω βάλει σε επόμενο post (κάνε copy & paste την s_get() μέσα στο πρόγραμμά σου πάνω από την main() και απλά χρησιμοποίησέ την... όπως χρησιμοποιείς τις έτοιμες συναρτήσεις της C χωρίς να ξέρεις τον κώδικά τους ;) )

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

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

Δημοσίευσηαπό stamatiou » 27 Ιούλ 2011, 17:57

Και όλα αυτά πρέπει να είναι γραμμένα σε μια γραμμή;(πχ.a 3 2 3.0 2.0 κλπ.)
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 27 Ιούλ 2011, 18:08

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

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

Δημοσίευσηαπό stamatiou » 27 Ιούλ 2011, 18:17

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

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

Δημοσίευσηαπό migf1 » 27 Ιούλ 2011, 18:18

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

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

Δημοσίευσηαπό stamatiou » 27 Ιούλ 2011, 18:22

Δηλαδή το πρόγραμμα θα λέει στο χρήστη να εισάγει 2 int και μετά μόλις πατήσει εντερ να εισαγει τα floa ή να καταλαβαίνει το πρόγραμμα μόνο τι τύπος είναι;
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

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

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