Παραδείγματα & Ασκήσεις στην C

...ασύγχρονα μαθήματα γλώσσας C

Re: Παραδείγματα & Ασκήσεις στην C

Δημοσίευσηαπό migf1 » 13 Ιούλ 2011, 01:14

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

Re: Παραδείγματα & Ασκήσεις στην C

Δημοσίευσηαπό Star_Light » 13 Ιούλ 2011, 03:12

migf1 έγραψε:Αφού γράφω ξεκάθαρα: Microsoft, Google, κλπ (προφανώς για πληροφορικάριους)


Οχι βασικα δεν με καταλαβες. Εννοουσα πως ειναι συγκεκριμενη θεση να δουλεψεις ακριβως σαν προγραμματιστης???
ή γενικα??? ΠΛηροφορικαριους... ? Καλα γενικα ακουγεται πως η C δεν πολυ "πουλαει" αυτο ειναι μπαρουφα πιστευω
οταν θα πας σε καποια σοβαρη εταιρεια για να εργαστεις θα σε ρωτησουν αν γνωριζεις κατι σοβαρο.

EDIT: Α οκ... "They are not in any specific order." το διαβασα καλυτερα ;) ειναι γενικα για πληροφορικαριους. Και ζητανε να δουνε αν ξερεις 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

Δημοσίευσηαπό Star_Light » 13 Ιούλ 2011, 13:40

Οταν λεει πχ οτι για καθε προγραμμα ορίζονται 3 μέρη μεσα στην μνημη εκ των οποιων το ενα ειναι το DATA SECTION το αλλο το CODE SECTION και το αλλο το STACK SECTION εννοει ουσιαστικα οτι το DATA SECTION καταρχην αν εχω φτιαξει εγω ενα προγραμμα το οποιο ζηταει εισοδο απο το πληκτρολογιο απο τον χρηστη ουσιαστικα η εισοδος θα ειναι αυτα τα DATA? Το code section οκ θα ειναι πες οι εντολες του... ενω το STACK SECTION θα ειναι οι διευθυνσεις των επομενων εντολων στην μνημη ??? τα σκεφτομαι καλα?

Π.Σ Παντως τωρα καταλαβαινω την σπουδαιοτητα των λιστων.... στον σκληρο δισκο που διαβαζα χθες και στους κομβους ευρετηριου i-nodes ολα αυτα υλοποιουνται ας πουμε με συνδεδεμενες λιστες.... η δομη της λιστας πχ ειναι τα χαρακτηριστικα ενος αρχειου... και ο δεικτης σε επομενο δειχνει στο επομενο μπλοκ που ειναι το ονομα του επομενου αρχειου κτλπ. Ειλικρινα αν εχεις καταλαβει λιστες και στοιβες εχεις κανει μεγαλα βηματα.
Γνώσεις ⇛ 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

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

Star_Light έγραψε:Οταν λεει πχ οτι για καθε προγραμμα ορίζονται 3 μέρη μεσα στην μνημη εκ των οποιων το ενα ειναι το DATA SECTION το αλλο το CODE SECTION και το αλλο το STACK SECTION εννοει ουσιαστικα οτι το DATA SECTION καταρχην αν εχω φτιαξει εγω ενα προγραμμα το οποιο ζηταει εισοδο απο το πληκτρολογιο απο τον χρηστη ουσιαστικα η εισοδος θα ειναι αυτα τα DATA? Το code section οκ θα ειναι πες οι εντολες του... ενω το STACK SECTION θα ειναι οι διευθυνσεις των επομενων εντολων στην μνημη ??? τα σκεφτομαι καλα?

Όχι, καμία σχέση :)

Δες 3 συνδέσμους που εξηγούν αναλυτικά (διάβασέ τα με τη σειρά που στα δίνω):
1. http://book.chinaunix.net/special/ebook ... 1sec6.html
2. http://discussknowhow.blogspot.com/2008 ... -wise.html
3. http://www.cyberplusindia.com/blog/inde ... -in-linux/

έγραψε:
Π.Σ Παντως τωρα καταλαβαινω την σπουδαιοτητα των λιστων.... στον σκληρο δισκο που διαβαζα χθες και στους κομβους ευρετηριου i-nodes ολα αυτα υλοποιουνται ας πουμε με συνδεδεμενες λιστες.... η δομη της λιστας πχ ειναι τα χαρακτηριστικα ενος αρχειου... και ο δεικτης σε επομενο δειχνει στο επομενο μπλοκ που ειναι το ονομα του επομενου αρχειου κτλπ. Ειλικρινα αν εχεις καταλαβει λιστες και στοιβες εχεις κανει μεγαλα βηματα.

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

Re: Παραδείγματα & Ασκήσεις στην C

Δημοσίευσηαπό migf1 » 13 Ιούλ 2011, 20:59

migf1 έγραψε:
[snip]
Βασικά έχω κάνει 2 υλοποιήσεις, μια στην οποία η αντιστροφή γίνεται απευθείας στην main() και οι λέξεις τυπώνονται απευθείας στην οθόνη, και μια όπου η αντιστροφή γίνεται μέσα σε συνάρτηση που δέχεται ως όρισμα την αρχική πρόταση και την επιστρέφει με αντεστραμμένες τις λέξεις της.

Παραθέτω (σε spoiler) την πρώτη υλοποίηση που είναι πιο εύκολη κι όταν μου δώσετε το οκ θα παραθέσω και την υλοποίηση με τη συνάρτηση.

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

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

/* ------------------------------------------------------------
* Από: migf1 Έκδοση ΧΩΡΙΣ Συνάρτηση
*
* Αντιστροφή λέξεων μιας πρότασης. Π.χ. το "γειά σου κόσμε"
* γίνεται "κόσμε σου γεια"
*
* Αλγόριθμος:
* πρώτα αντιστρέφεται η αρχική πρόταση και κατόπιν διασπάται
* στις λέξεις της, οι οποίες αντιστρέφονται εκ νέου πριν
* τυπωθούν μια προς μια στην οθόνη.
* ------------------------------------------------------------
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ------------------------------------------------------------------------------------
// Αντιστρέφει το string s. Βάζει από έναν δείκτην στην αρχή και το τέλος του s, κι
// εναλλάσει τους χαρακτήρες τους μέχρι να συναντηθούν οι δυο δείκτες στη μέση του s
// ΣΗΜΑΝΤΙΚΟ: το s πρέπει να είναι ήδη δημιουργημένο.
//
char *s_reverse(char *s)
{
if ( !s ) // early exit
return NULL;

char *cp1, *cp2, dummy;

cp2 = s + strlen(s) - 1; // set cp2 at end of s
for (cp1=s; cp1 < cp2; cp1++, cp2--) {
dummy = *cp1;
*cp1 = *cp2;
*cp2 = dummy;
}

return s;
}

// ------------------------------------------------------------------------------------
int main( void )
{
char s[255+1]="", *delims=" \t\n", *cp;

printf("Enter a sentence: ");
fgets(s, 256, stdin);

s_reverse(s);
cp = strtok(s, delims);
while (cp != NULL) {
printf("%s ", s_reverse(cp) );
cp = strtok(NULL, delims);
}
putchar('\n');

fflush(stdin); getchar();
exit( EXIT_SUCCESS );
}


Παραθέτω την (2η) υλοποίηση με αυτόνομη συνάρτηση.

Η βασική της διαφορά από την 1η υλοποίηση είναι πως οι διασπασμένες λέξεις του s δεν τυπώνονται απευθείας στην οθόνη μετά την αντιστροφή τους, αλλά μπαίνουν μέσα σε ένα τοπικά δηλωμένο string t, το οποίο στο τέλος αντιγράφεται στο s, πριν τερματίσει η συνάρτηση.

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

/* ------------------------------------------------------------
* Από: migf1 Έκδοση με Συνάρτηση
*
* Αντιστροφή λέξεων μιας πρότασης. Π.χ. το "γειά σου κόσμε"
* γίνεται "κόσμε σου γεια"
*
* Αλγόριθμος:
* πρώτα αντιστρέφεται η αρχική πρόταση και κατόπιν διασπάται
* στις λέξεις της, οι οποίες αντιστρέφονται εκ νέου πριν
* τυπωθούν μια προς μια στην οθόνη.
* ------------------------------------------------------------
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// ------------------------------------------------------------------------------------
// Αντιγράφει έως n-1 χαρακτήρες του string src στο string dst, το οποίο κι επιστρέφει
// προσθέτοντας τον μηδενικό χαρακτήρα στο τέλος.
// ΣΗΜΑΝΤΙΚΟ: τα dst και src πρέπει να είναι ήδη δημιουργημένα και να έχουν χώρο για
// τουλάχιστον n χαρακτήρες (συμπεριλαμβανομένου του μηδενικού στο τέλος)
//
char *s_ncopy( char *dst, const char *src, int n )
{
char *save = dst;

while ( (dst-save) < n-1 && (*dst=*src) != '\0' )
dst++, src++;

if ( *dst )
*dst = 0;

return save;
}

// ------------------------------------------------------------------------------------
// Αντιστρέφει το string s. Βάζει από έναν δείκτην στην αρχή και το τέλος του s, κι
// εναλλάσει τους χαρακτήρες τους μέχρι να συναντηθούν οι δυο δείκτες στη μέση του s
// ΣΗΜΑΝΤΙΚΟ: το s πρέπει να είναι ήδη δημιουργημένο.
//
char *s_reverse(char *s)
{
if ( !s ) // early exit
return NULL;

char *cp1, *cp2, dummy;

cp2 = s + strlen(s) - 1; // set cp2 at end of s
for (cp1=s; cp1 < cp2; cp1++, cp2--) {
dummy = *cp1;
*cp1 = *cp2;
*cp2 = dummy;
}

return s;
}

// ------------------------------------------------------------------------------------
// Αντιστρέφει τις λέξεις του string s κι επιστρέφει το αλλαγμένο s (δείτε στην αρχή
// του αρχείου τον αλγόριθμο).
// ΣΗΜΑΝΤΙΚΟ: το s πρέπει να είναι ήδη δημιουργημένο πριν περαστεί στη συνάρτηση
//
char *s_revwords(char *s)
{
size_t slen = strlen(s) + 1; // strlen() excludes '\0', so +1
char t[ slen+1 ]; // t will have an extra space at the end
char *delims=" \t\n", *cp = NULL;

*t = '\0'; // must be done, for strcat() below
s_reverse(s);
cp = strtok(s, delims);
while (cp != NULL)
{
strcat(t, s_reverse(cp) );
strcat(t, " ");
cp = strtok(NULL, delims);
}

s_ncopy(s, t, slen ); // exclude final space char ' '
return s;
}
// ------------------------------------------------------------------------------------
int main( void )
{
char s[256];

printf("Enter a sentence: ");
fgets(s, 256, stdin);
printf("%s\n", s_revwords(s));

exit( EXIT_SUCCESS );
}

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

Re: Παραδείγματα & Ασκήσεις στην C

Δημοσίευσηαπό linuxs » 13 Ιούλ 2011, 21:00

Να βάλω και τις δυο υλοποιήσεις στο πρώτο ποστ? :/ Είναι η ίδια άσκηση απλά με συνάρτηση...να δώσω μήπως κάποιο λινκ μόνο? :/ για πε...
Αν το πρόβλημά μας επιλυθεί. Επιλέγουμε το θέμα που βοήθησε στην επίλυση και πατάμε το κουμπάκι Εικόνα.
Γνώσεις ⇛ Linux: Μέτριο┃Προγραμματισμός: C┃Αγγλικά: Καλά
Λειτουργικό ⇛ Linux Ubuntu 10.4 LTS
Προδιαγραφές ⇛ Intel Pentium @T4500 2.3GHz│ 512GB VRAM│ 500 HDD│ ATI RADEON HD545v 512 MB │ Screen: 15.6''
Άβαταρ μέλους
linuxs
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 1060
Εγγραφή: 02 Ιούλ 2010, 13:19
Τοποθεσία: GR
IRC: linuxs
Εκτύπωση

Re: Παραδείγματα & Ασκήσεις στην C

Δημοσίευσηαπό migf1 » 13 Ιούλ 2011, 21:04

migf1 έγραψε:
[snip]
Γράψτε μια συνάρτηση: int myatoi( char *str ) η οποία θα μιμείται τη στάνταρ συνάρτηση: atoi().

Η συνάρτηση δέχεται ως όρισμα ένα string και επιστρέφει τον ακέραιο αριθμό στον οποίον αντιστοιχεί σε αυτό το string. Θα πρέπει να λαμβάνει υπόψη της τα εξής:
  • αρχικά κενά διαστήματα αγνοούνται
  • τα πρόσημα + και - υπολογίζονται κανονικά (αν δεν υπάρχει πρόσημο, ο ακέραιος θεωρείται θετικός)
  • αν ο πρώτος μη κενός χαρακτήρας δεν είναι ούτε πρόσημο ούτε ψηφίο, η συνάρτηση επιστρέφει 0
  • χαρακτήρες που δεν είναι ψηφία και ακολουθούν κανονικό αριθμό (με ή χωρίς πρόσημο) αγνοούνται
  • αν ο υπολογισμένος αριθμός είναι μεγαλύτερος του INT_MAX, η συνάρτηση επιστρέφει INT_MAX
  • αν ο υπολογισμένος αριθμός είναι μικρότερος του -INT_MAX, η συνάρτηση επιστρέφει -INT_MAX *
* η κανονική atoi() ως αρνητικό όριο επιστρέφει το INT_MIN (και όχι το -INT_MAX) αλλά δεν χρειάζεται να το κάνετε έτσι
[snip]

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

/* ---------------------------------------------------------------------------
* Από: migf1
* Υλοποίηση συνάρτησης: int myatoi(char *str) που μιμείται την συνάρτηση
* int int atoi(char *str) της στάνταρ βιβλιοθήκης stdlib
* ---------------------------------------------------------------------------
*/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>

// ------------------------------------------------------------------------------------
int myatoi( const char *s )
{
if ( !s || !*s ) // ανύπαρκτο ή μηδενικό s
return 0; // πρόωρη έξοδος

//αγνοούμε τυχόν κενούς χαρακτήρες στην αρχή
while (*s && isspace(*s) )
s++;
if ( !*s )
return 0;

// απαιτούμε ο 1ος χαρακτήρας να είναι είτε πρόσημο είτε ψηφίο
if ( *s != '+' && *s != '-' && !isdigit( *s ) )
return 0;

int num = 0, sign = 0; // ΣΗΜΑΝΤΙΚΕΣ αρχικοποιήσεις σε 0

// καθορισμός προσήμου (αν υπάρχει)
if ( *s == '+') {
sign = 1;
s++;
}
else if ( *s == '-') {
sign = -1;
s++;
}

// μετατροπή σε ακέραιο
while ( *s ) // όσο υπάρχουν χαρακτήρες
{
if ( isdigit(*s) ) // ψηφίο, επεξεργάσου το
{
int temp = num * 10 + *s - '0'; // υπολογισμός
if ( INT_MAX - temp < 0 ) { // έλεγχος για overflow
puts("integer overflow");
num = INT_MAX;
break;
}

num = temp;
s++;
}
else // μη-ψηφιο, μην συνεχίσεις!
break;
}

// προσθήκη προσήμου
if ( sign != 0 )
num = num * sign;

return num;
}

// -------------------------------------------------------------------------------------
int main( void )
{
char s[255+1] = "";

printf("Enter a number (%d): ", INT_MAX);
fgets(s, 256, stdin);
printf("%d\n", myatoi2(s) );

exit( EXIT_SUCCESS );
}

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

Re: Παραδείγματα & Ασκήσεις στην C

Δημοσίευσηαπό migf1 » 13 Ιούλ 2011, 21:06

linuxs έγραψε:Να βάλω και τις δυο υλοποιήσεις στο πρώτο ποστ? :/ Είναι η ίδια άσκηση απλά με συνάρτηση...να δώσω μήπως κάποιο λινκ μόνο? :/ για πε...

Μπορείς να βάλεις π.χ. κάτι τέτοιο:

Αντιστροφή λέξεων: 1ος τρόπος, 2ος τρόπος

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

Re: Παραδείγματα & Ασκήσεις στην C

Δημοσίευσηαπό migf1 » 13 Ιούλ 2011, 21:28

Υπολογισμός του χώρου που πιάνει στη μνήμη μια μεταβλητή τύπου struct, χωρίς χρήση του τελεστή sizeof...

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

/* ------------------------------------------------------------
* Από: migf1
* υπολογισμός του χώρου που πιάνει στη μνήμη μια μεταβλητή τύπου struct,
* χωρίς χρήση του τελεστή sizeof
*/

#include <stdio.h>
#include <stdlib.h>

// --------------------------------------------------------------------------------------
int main( void )
{
struct test {
int a;
float b;
char c[100];
} test;
struct test *p = &test;

printf("The size of \"struct test\" is: %d bytes\n", (char *)(p+1) - (char *)p );

exit( EXIT_SUCCESS );
}

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

Re: Παραδείγματα & Ασκήσεις στην C

Δημοσίευσηαπό linuxs » 13 Ιούλ 2011, 21:31

migf1 έγραψε:Υπολογισμός του χώρου που πιάνει στη μνήμη μια μεταβλητή τύπου struct, χωρίς χρήση του τελεστή sizeof...

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

/* ------------------------------------------------------------
* Από: migf1
* υπολογισμός του χώρου που πιάνει στη μνήμη μια μεταβλητή τύπου struct,
* χωρίς χρήση του τελεστή sizeof
*/

#include <stdio.h>
#include <stdlib.h>

// --------------------------------------------------------------------------------------
int main( void )
{
struct test {
int a;
float b;
char c[100];
} test;
struct test *p = &test;

printf("The size of \"struct test\" is: %d bytes\n", (char *)(p+1) - (char *)p );

exit( EXIT_SUCCESS );
}



:S Το printf δεν το καταλαβαίνω... :(
Αν το πρόβλημά μας επιλυθεί. Επιλέγουμε το θέμα που βοήθησε στην επίλυση και πατάμε το κουμπάκι Εικόνα.
Γνώσεις ⇛ Linux: Μέτριο┃Προγραμματισμός: C┃Αγγλικά: Καλά
Λειτουργικό ⇛ Linux Ubuntu 10.4 LTS
Προδιαγραφές ⇛ Intel Pentium @T4500 2.3GHz│ 512GB VRAM│ 500 HDD│ ATI RADEON HD545v 512 MB │ Screen: 15.6''
Άβαταρ μέλους
linuxs
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 1060
Εγγραφή: 02 Ιούλ 2010, 13:19
Τοποθεσία: GR
IRC: linuxs
Εκτύπωση

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

  • ΣΧΕΤΙΚΑ ΘΕΜΑΤΑ
    ΑΠΑΝΤΗΣΕΙΣ
    ΠΡΟΒΟΛΕΣ
    ΣΥΓΓΡΑΦΕΑΣ

Επιστροφή στο Μαθήματα C

cron