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

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

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

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

Δημοσίευσηαπό migf1 » 03 Αύγ 2011, 17:10

Εν τω μεταξύ εγώ έφτιαξα ένα calculator που το ονόμασα Dummy Calc :lol: επειδή είναι όντως... ηλίθιο, από την άποψη πως δεν κάνει ελέγχους υπερχείλισης, δεν χρησιμοποιεί προτεραιότητες τελεστών, ούτε παρενθέσεις.

Υποστηρίζει όμως 15 πράξεις και λειτουργεί με τη λογική των κανονικών calculators, ότι δηλαδή παίρνει μόνο έναν τελεστή κι ένα αριθμό στη κάθε γραμμή, και εφαρμόζει τη πράξη στο αποτέλεσμα της προηγούμενης. Μερικοί τελεστές (όπως π.χ της τετραγωνικής ρίζας) είναι μοναδιαίοι (unary) οπότε εφαρμόζονται απευθείας στο προηγούμενο αποτέλεσμα αγνοώντας πλήρως τυχόν νούμερα που υπάρχουν μετά από τον τελεστή, στη γραμμή.

Το prompt δείχνει ανά πάσα στιγμή το αποτέλεσμα της αμέσως προηγούμενης πράξης. Οπότε αν είναι π.χ.
Κώδικας: Επιλογή όλων
10.6:

και του πληκτρολογήσετε +10...
Κώδικας: Επιλογή όλων
10.6: +10

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

10.6: +10
20.6:

Μπορείτε επίσης να δώσετε x για να τερματίσετε το πρόγραμμα, c για να καθαρίσετε το τρέχον αποτέλεσμα και h για να δείτε τη βοηθητική οθόνη με λίστα όλων των υποστηριζόμενων πράξεων και τους τελεστές τους.

Όλο το "παιχνίδι" γίνεται από έναν πίνακα pf που αποτελείται από δείκτες που δείχνουν στις συναρτήσεις των πράξεων...

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

double (*pf[MAX_OPERATORS])(const double, const double) = {
&add, &sub, &mul, &over, &modulus, &pwr, &expo, &sqroot, &cbroot,
&neg, &fact, &loge, &logten, &truncate, &frac
};
(τα ονόματα με τα & μπροστά είναι τα ονόματα των συναρτήσεων).

Οι θέσεις αυτού του πίνακα αντιστοιχούν πλήρως με τον πρόσθετο τύπο απαρίθμησης OpCode:

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

typedef enum { // operator codes
ADD, SUB, MUL, DIV, MOD, POW, EXPO, SQRT, CBRT, NEG,
FACT, LOGE, LOGTEN, TRUNC, FRAC
} OpCode;

Οπότε για παράδειγμα, μια γραμμή σαν αυτήν...

Κώδικας: Επιλογή όλων
res = (*pf[MUL])(3, 100);

καλεί τη συνάρτηση mul(3, 100) που πολλαπλασιάζει το 3 με το 100 και το αποτέλεσμά που επιστρέφει το βάζουμε στη μεταβλητή res.

Τέλος χρησιμοποιώ κι ένα struct που περιέχει το σύμβολο, το OpCode και το αν είναι unary ένας τελεστής, και φτιάχνω έναν πίνακα tabops από τέτοια struct, ένα για κάθε τελεστή, και τα αρχικοποιώ στην αρχή της main (το πεδίο .unary το ορίζω στο struct και το αρχικοποιώ κι αυτό στον πίνακα με FALSE ή TRUE, αλλά βασικά δεν το χρησιμοποιώ καθόλου στο πρόγραμμα... το έβαλα γιατί μπορεί να μου χρειαστεί αργότερα, αν αναβαθμίσω το πρόγραμμα).

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

const OperStruct tabops[MAX_OPERATORS] = { // table of operator structures
{'+', ADD, FALSE}, {'-', SUB, FALSE}, {'*', MUL, FALSE},
{'/', DIV, FALSE}, {'%', MOD, FALSE}, {'^', POW, FALSE},
{'e', EXPO, TRUE}, {'@', SQRT, TRUE}, {'#', CBRT, TRUE},
{'~', NEG, TRUE }, {'!', FACT, TRUE}, {'\'', LOGE, TRUE},
{'\"', LOGTEN, TRUE}, {'_', TRUNC, TRUE}, {'.', FRAC, TRUE}
};
(κι αυτουνού του πίνακα οι θέσεις αντιστοιχούν πλήρως με τον πρόσθετο τύπο απαρίθμησης OpCode... δηλαδή το ADD που ισούται με 0 αντιστοιχεί στην 1η θέση του πίνακα, το SUB που ισούται με 1 αντιστοιχεί στη 2η θέση του πίνακα, κλπ)

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

Οπότε η γενική λογική το προγράμματος είναι, να διαβάζει με την get_input() την κύρια είσοδο και να κρατάει τις μεταβλητές που χρειάζεται (βασικά, τον τελεστή και το νούμερο). Μετατρέπει το σύμβολο του τελεστή από char στο αντίστοιχο opcode (μέσω της sym2opcode()) το οποίο opcode το χρησιμοποιεί μετά στην main για να καλέσει από τον πίνακα των συναρτήσεων την αντίστοιχη συνάρτηση. Για ορίσματα περνάει πάντα το προηγούμενο αποτέλεσμα (res) και το νούμερο που διάβασε (χ).

Οι συναρτήσεις είναι φτιαγμένες έτσι ώστε να αγνοούν το 2ο όρισμά τους αν δεν το χρειάζονται. Απλά για να δουλέψει η φάση με τον πίνακα συναρτήσεων πρέπει όλες οι συναρτήσεις να έχουν το ίδιο πλήθος και τύπο ορισμάτων και να επιστρέφουν όλες τον ίδιο τύπο.

Αυτά! :)

Ο κώδικας είναι ανεβασμένος στο ideone.com: https://ideone.com/f87ub
Τελευταία επεξεργασία από migf1 και 03 Αύγ 2011, 18:49, έχει επεξεργασθεί 1 φορά/ες συνολικά
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό Star_Light » 03 Αύγ 2011, 17:13

@clepto

σου εχω 2 απλές ασκήσεις. :D


1. Γραψε κώδικα στον οποίο θα γίνεται πρόσθεση και πολλαπλασιασμος 2 αριθμών και το αποτέλεσμα των οποιων θα εκτυπωνεται μεσω 2 δεικτών. (οι οποιοι δείκτες θα δείχνουν στις 2 ακέραιες μεταβλητές)

2. Χρησιμοποιησε την switch για να καλείς 3 συναρτήσεις σε καθε case στις οποιες στην μεν μια θα υπολογίζεται η δυναμη ενος αριθμου στην μεν δευτερη θα υπολογιζεται ο μέγιστος μεταξυ των 2 αριθμων (χ,ψ) / χρησιμοποιησε μια βοηθητικη μεταβλητη z για να μην χασεις το αποτελεσμα και στην μεν τριτη ο ελαχιστος εκ των 2 δηλαδη οι συναρτησεις θα ειναι

Κώδικας: Επιλογή όλων
int dunami(int , int)


Κώδικας: Επιλογή όλων
int maximum(int , int , int)


Κώδικας: Επιλογή όλων
int minimum(int , int , int)


;) οποιος θελει ας τις λυσει.

π.σ migf1 εσυ πρεπει να μπεις και σε διαγωνισμο οχι αν θα καταφερεις να λυσεις το οτιδηποτε στην C αλλα και σε λιγοτερο απο μιση ωρα ααχαχαχαχα τι εισαι εσυ ρε φιλε... πωπωωωω xD ουτε μετα απο 10 χρονια εξασκησης δεν παιζει να γινω ετσι... ε ειναι και θεμα ταλεντου. Αλλα και ετσι καααλα ειμαστε :P καλα να σαι να μας μαθαινεις.
Τελευταία επεξεργασία από Star_Light και 03 Αύγ 2011, 17:17, έχει επεξεργασθεί 1 φορά/ες συνολικά
Γνώσεις ⇛ 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 » 03 Αύγ 2011, 17:15

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

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

Δημοσίευσηαπό Star_Light » 03 Αύγ 2011, 17:18

migf1 έγραψε:(εγώ λέω να μην τις λύσω αυτές :lol:)


ε δικαιολογιες απλα δεν μπορεις να λυσεις τις σουπερ ασκησαρες μου αχαχαχαχαχα

Π.Σ Λοιπον παω να ψαξω κατι ακομη για την πτυχιακη και μετα που θα μπω αν δεν τις εχει λυσει κανεις θα τις λυσω εγω
και θα τις ανεβασω . :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 » 03 Αύγ 2011, 18:27

migf1 έγραψε:Οκ, γράψε ένα πρόγραμμα που θα διαβάζει ακέραιους από την κύριο είσοδο και θα σταματάει μόλις διαβάσει αριθμό που θα απέχει περισσότερο από 10 μονάδες από τον προηγούμενό του (είτε προς τα κάτω είτε προς τα πάνω).

Π.χ. 10 12 9 15 29
σταματάει γιατί το 29 απέχει 14 μονάδες από το 15.

Ομοίως: 5 10 19 8
σταματάει γιατί το 8 απέχει 11 μονάδες από το 19

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

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

Δημοσίευσηαπό migf1 » 03 Αύγ 2011, 19:15

migf1 έγραψε:Να δώσω τη λύση, ή όχι ακόμα;

Τη δίνω σε spoiler, για να μη το χω στο μυαλό μου κι αυτο :lol: κι όποιος δεν θέλει δεν το ανοίγει :)

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

#include <stdio.h>
#include <stdlib.h> // for abs()

int main ( void )
{
int num=0, prev = 0;
while ( abs( num-prev ) < 10 )
{
prev = num;
printf("Next num: ");
scanf("%d", &num);
}
return 0;
}
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 03 Αύγ 2011, 19:49

Star_Light έγραψε:;) οποιος θελει ας τις λυσει.

1. Γραψε κώδικα στον οποίο θα γίνεται πρόσθεση και πολλαπλασιασμος 2 αριθμών και το αποτέλεσμα των οποιων θα εκτυπωνεται μεσω 2 δεικτών. (οι οποιοι δείκτες θα δείχνουν στις 2 ακέραιες μεταβλητές)

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

#include <stdio.h>
int main( void )
{
int n1=10, n2=20, sum=n1+n2, prod=n1*n2, *p1=&sum, *p2=&prod;
printf("%d, %d\n", *p1, *p2 );
return 0;
}


έγραψε:2. Χρησιμοποιησε την switch για να καλείς 3 συναρτήσεις σε καθε case στις οποιες στην μεν μια θα υπολογίζεται η δυναμη ενος αριθμου στην μεν δευτερη θα υπολογιζεται ο μέγιστος μεταξυ των 2 αριθμων (χ,ψ) / χρησιμοποιησε μια βοηθητικη μεταβλητη z για να μην χασεις το αποτελεσμα και στην μεν τριτη ο ελαχιστος εκ των 2 δηλαδη οι συναρτησεις θα ειναι...

Δεν κατάλαβα τίποτα :lol:

έγραψε:π.σ migf1 εσυ πρεπει να μπεις και σε διαγωνισμο οχι αν θα καταφερεις να λυσεις το οτιδηποτε στην C αλλα και σε λιγοτερο απο μιση ωρα ααχαχαχαχα τι εισαι εσυ ρε φιλε... πωπωωωω xD ουτε μετα απο 10 χρονια εξασκησης δεν παιζει να γινω ετσι... ε ειναι και θεμα ταλεντου. Αλλα και ετσι καααλα ειμαστε :P καλα να σαι να μας μαθαινεις.

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

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

Δημοσίευσηαπό Star_Light » 03 Αύγ 2011, 20:31

migf1 έγραψε:
Star_Light έγραψε:;) οποιος θελει ας τις λυσει.

1. Γραψε κώδικα στον οποίο θα γίνεται πρόσθεση και πολλαπλασιασμος 2 αριθμών και το αποτέλεσμα των οποιων θα εκτυπωνεται μεσω 2 δεικτών. (οι οποιοι δείκτες θα δείχνουν στις 2 ακέραιες μεταβλητές)

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

#include <stdio.h>
int main( void )
{
int n1=10, n2=20, sum=n1+n2, prod=n1*n2, *p1=&sum, *p2=&prod;
printf("%d, %d\n", *p1, *p2 );
return 0;
}


έγραψε:2. Χρησιμοποιησε την switch για να καλείς 3 συναρτήσεις σε καθε case στις οποιες στην μεν μια θα υπολογίζεται η δυναμη ενος αριθμου στην μεν δευτερη θα υπολογιζεται ο μέγιστος μεταξυ των 2 αριθμων (χ,ψ) / χρησιμοποιησε μια βοηθητικη μεταβλητη z για να μην χασεις το αποτελεσμα και στην μεν τριτη ο ελαχιστος εκ των 2 δηλαδη οι συναρτησεις θα ειναι...

Δεν κατάλαβα τίποτα :lol:

έγραψε:π.σ migf1 εσυ πρεπει να μπεις και σε διαγωνισμο οχι αν θα καταφερεις να λυσεις το οτιδηποτε στην C αλλα και σε λιγοτερο απο μιση ωρα ααχαχαχαχα τι εισαι εσυ ρε φιλε... πωπωωωω xD ουτε μετα απο 10 χρονια εξασκησης δεν παιζει να γινω ετσι... ε ειναι και θεμα ταλεντου. Αλλα και ετσι καααλα ειμαστε :P καλα να σαι να μας μαθαινεις.

Thanks ρε συ, αλλά σου φαίνονται wow επειδή είσαι στην αρχή ακόμα. Δεν είναι τόσο δύσκολα ;)


migf1 οτι θες μπορεις να το πεις και να στο λυσουμε σχετικα με την ασκηση χαχαχαχαχα

λοιπον προχθες μιλησαμε για την sscanf χθες μαλλον...

νομιζω πως καταλαβα

ουσιαστικα το const char *str που εχει στο προτυπο μπορει να έχει δηλωθει ας πουμε ως μονιμη μεταβλητη και να μην μπορει να αλλαξει αλλα ο δεικτης str μπορει να πάρει την διευθυνση μιας διαφορετικης συμβολοσειρας που δηλωνεται με το const chat αυτο σημαινει πως μπορει να ανανεωνει η μνημη καθε φορα που ο χρηστης εισαγει συμβολοσειρες! Ετσι δεν ειναι?
Γνώσεις ⇛ 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 » 03 Αύγ 2011, 21:03

Η λυση της δικιας μου 1. :D

Spoiler: show
Κώδικας: Επιλογή όλων
/*-=====================================-
EMfanisi apotelesmatos pollaplasiasmou kai pros8esis
2 akeraiwn me xrhsh deiktwn

* Arxiko paradeigma me deiktes
*

-=========================================- */

#include <stdio.h>
#define N 20

int main()
{
char array[N];
int x,y;
int *ptrsm , *ptrgn; //Deiktes gia sm => sum kai gn => ginomeno antistoixa.
int sum, gn;


printf("Dwste ta x kai y");
printf("\n\n");
fgets(array,N,stdin);
sscanf(array,"%d%d",&x,&y);

sum=x+y;
ptrsm=&sum; //pleon o deiktis deixnei ekei pou einai apothikeumeno to sum

printf("To apotelesma tis pros8esis einai: %d \n",*ptrsm);

gn=x*y;
ptrgn=&gn; // OMoiws idia logiki me panw

printf("To apotelesma tou ginomenou einai: %d \n", *ptrgn);

printf("\n");
printf("Kalh sunexeia");

return 0;
}


μπορουμε να επεκτείνουμε και την 2η άσκηση να παίζει με δείκτες μέσα στις συναρτήσεις (call by reference) και ουσιαστικα ο τυπος επιστροφής της να ειναι μονο void αλλα η συνάρτηση να πειράζει την μνήμη απο την στιγμη που καλείται οπως ακριβως έχει δειξει και ο migf1.
Γνώσεις ⇛ 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 » 03 Αύγ 2011, 21:31

Star_Light έγραψε:
λοιπον προχθες μιλησαμε για την sscanf χθες μαλλον...

νομιζω πως καταλαβα

ουσιαστικα το const char *str που εχει στο προτυπο μπορει να έχει δηλωθει ας πουμε ως μονιμη μεταβλητη και να μην μπορει να αλλαξει αλλα ο δεικτης str μπορει να πάρει την διευθυνση μιας διαφορετικης συμβολοσειρας που δηλωνεται με το const chat αυτο σημαινει πως μπορει να ανανεωνει η μνημη καθε φορα που ο χρηστης εισαγει συμβολοσειρες! Ετσι δεν ειναι?

Το const σε δείκτες είναι λίγο μπερδεμένο.

Κώδικας: Επιλογή όλων
const char *
σημαίνει πως είναι σταθερό αυτό στο οποίο δείχνει ο δείκτης, αλλά δεν είναι σταθερός ο δείκτης

Κώδικας: Επιλογή όλων
char *const
σημαίνει πως είναι σταθερός ο δείκτης, αλλά δεν είναι σταθερό αυτό στο οποίο δείχνει

Κώδικας: Επιλογή όλων
const char *const
σημαίνει πως είναι σταθερός και ο δείκτης και αυτό στο οποίο δείχνει.

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

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

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