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

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

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

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

Δημοσίευσηαπό migf1 » 03 Μαρ 2012, 16:20

Για δες κι αυτό (κλασσική περίπτωση πιο ευανάγνωστου, modular, reusable κώδικα, με κόστος μειωμένες επιδόσεις... σκανάρει συνεχώς το NORMAL σε κάθε επανάληψη του loop)...

Μορφοποιημένος Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <ctype.h>

#define MAXINPUT (255+1)

#define NORMAL "ABEIOS"
#define BIFFED "483105"

/* ------------------------------------------------------------------- */
char toBiff( const char c )
{
for (int i=0; NORMAL[i]; i++ )
if ( c == NORMAL[i] )
return BIFFED[i];
return c;
}
/* ------------------------------------------------------------------- */
int main( void )
{
char msg[MAXINPUT] = {'\0'};

for (int i=0; '\n' != (msg[i] = getchar()); i++ )
putchar( toBiff( toupper(msg[i]) ) );
puts("!!!!!!!!!!");

return 0;
}

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

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

Δημοσίευσηαπό Ilias95 » 03 Μαρ 2012, 16:32

Βέβαια και στα δύο τελευταία παραδείγματα που παρέθεσες δεν υπάρχει πραγματική ανάγκη να χρησιμοποιηθούν arrays.
Ενώ αν πρέπει να υλοποιηθεί ακριβώς όπως την ζητάει (δηλαδή τυπώνοντας και "In B1FF-speak:") τότε θα πρέπει να γίνουν αλλαγές και στις δύο υλοποιήσεις.
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 03 Μαρ 2012, 16:51

Βασικά αυτά υλοποιούνται με strings, τα οποία είναι ειδικοί πίνακες χαρακτήρων. Ειδικοί επειδή πρέπει υποχρεωτικό ο πρώτος μη ωφέλιμος χαρακτήρας τους νε είναι πάντα μηδενικός ('\0') καθώς επίσης να υπάρχει τουλάχιστον ένας μηδενικός χαρακτήρας μέσα στο string (ο μηδενικός χαρακτήρας σηματοδοτεί το τέλος των ωφέλιμων χαρακτήρων του).

Αυτό βολεύει π.χ. στο να ξεκινάς από την αρχή ενός string και να βρίσκεις το τέλος των ωφέλιμων χαρακτήρων του, χωρίς να χρειάζεται να "ξέρεις" το μέγιστο μήκος με το οποίο έχουν δημιουργηθεί... σταματάς στο 1ο '\0' που θα βρεις. Αυτά στη θεωρία, γιατί στην πράξη δεν είναι καθόλου λίγες οι περιπτώσεις κακογραμμένου κώδικα που είτε ξεχνάει να εξασφαλίσει την ύπαρξη του '\0' μέσα στο string, ή το βάζει σε θέση μεγαλύτερη από την μέγιστη με την οποία έχει ορίσει για το string.

Η συντριπτική μάλιστα πλειοψηφία των στάνταρ συναρτήσεων διαχείρισης strings, στην βιβλιοθήκη string.h θεωρούν δεδομένη την ύπαρξη ενός τουλάχιστον '\0' στα strings που τους περνάμε ως ορίσματα. Αν δεν υπάρχει,, τότε συνήθως προκαλείται seg-fault (επειδή η συνάρτηση κάποια στιγμή θα επιχειρήσει να κάνει access θέση μεγαλύτερη από την μέγιστη που έχει οριστεί το string.

Για αυτό και τα strings από χαρακτήρες που περιέχουν τουλάχιστον έναν μηδενικό χαρακτήρα θα τα συναντήσεις και με την ονομασία c-string.

Μορφοποιημένος Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <ctype.h>

#define MAXINPUT (255+1)
#define NORMAL "ABEIOS"
#define BIFFED "483105"

/* ------------------------------------------------------------------- */
char toBiff( const char c )
{
for (int i=0; NORMAL[i]; i++ )
if ( c == NORMAL[i] )
return BIFFED[i];
return c;
}
/* ------------------------------------------------------------------- */
int main( void )
{
int i;
char msg[MAXINPUT] = {'\0'};

printf( "Message: ");
for (i=0; i < MAXINPUT-1 && '\n' != (msg[i] = getchar()); i++ )
msg[i] = toBiff( toupper(msg[i]) );

if ( msg[i] == '\n' )
msg[i] = '\0';

printf("BIFFED : %s!!!!!!!!!!\n", msg );

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

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

Δημοσίευσηαπό migf1 » 03 Μαρ 2012, 16:56

Βασικά έχουμε ξεχάσει και οι 2 να ελέγχουμε να μην ξεπερνιέται το μέγιστο μήκος του πίνακα κατά την ανάγνωση !!!!

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

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

Δημοσίευσηαπό migf1 » 03 Μαρ 2012, 17:08

Δες το και πλήρες (με χειροκίνητη διαχείριση των πάντων)....

Μορφοποιημένος Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <ctype.h>

#define MAXINPUT (255+1)
#define NORMAL "ABEIOS"
#define BIFFED "483105"

/* ------------------------------------------------------------------- */
char toBiff( const char c )
{
for (int i=0; NORMAL[i]; i++ )
if ( c == NORMAL[i] )
return BIFFED[i];
return c;
}
/* ------------------------------------------------------------------- */
int main( void )
{
int i;
char msg[ MAXINPUT ] = {'\0'};

printf( "Message: ");
for (i=0; i < MAXINPUT-1 && '\n' != (msg[i] = getchar()); i++ )
msg[i] = toBiff( toupper(msg[i]) );

/* remove '\n' from end of msg (if exists) */
if ( msg[i] == '\n' )
msg[i] = '\0';

/* append 10 '!' at the end of msg, or less if there is no room */
for (int j=0; j < 10 && i < MAXINPUT-1; i++, j++)
msg[i] = '!';

printf("BIFFED : %s\n", msg );

return 0;
}

Εκείνα τα MAXINPUT-1 είναι για να εξασφαλίζουν πως η τελευταία θέση είναι για τον χαρακτήρας '\0' ... παρατήρησε επίσης πως αρχικοποιώ το msg[] με όλο το μήκος τους γεμάτο μηδενικούς χαρακτήρες στην αρχή ;)
Τελευταία επεξεργασία από migf1 και 03 Μαρ 2012, 17:22, έχει επεξεργασθεί 1 φορά/ες συνολικά
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό Ilias95 » 03 Μαρ 2012, 17:15

Όμορφα. :)

Το:
Κώδικας: Επιλογή όλων
if ( msg[i] == '\n' )
msg[i--] = '\0';

Νομίζω πρέπει να γίνει:
Κώδικας: Επιλογή όλων
if ( msg[i] == '\n' )
msg[i] = '\0';

Γιατί χάνεται ένας χαρακτήρας στην έξοδο.

migf1 έγραψε:παρατήρησε επίσης πως αρχικοποιώ το msg[] με όλο το μήκος τους γεμάτο μηδενικούς χαρακτήρες στην αρχή

Θα ήταν το ίδιο με;
Κώδικας: Επιλογή όλων
char msg[ MAXINPUT ] = {0};

Γιατί απ' ότι κατάλαβα το '\0' παίζει ρόλο στο να σηματοδοτήσει το "τέλος" του string. Ή υπάρχει λόγος που γίνεται και η αρχικοποίηση έτσι;
Ilias95
saintTUX
saintTUX
 
Δημοσιεύσεις: 1548
Εγγραφή: 29 Απρ 2011, 23:26
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 03 Μαρ 2012, 17:26

Ilias95 έγραψε:Όμορφα. :)

Το:
Κώδικας: Επιλογή όλων
if ( msg[i] == '\n' )
msg[i--] = '\0';

Νομίζω πρέπει να γίνει:
Κώδικας: Επιλογή όλων
if ( msg[i] == '\n' )
msg[i] = '\0';

Γιατί χάνεται ένας χαρακτήρας στην έξοδο.

Σωστός, το διόρθωσα (καταραμένο copy & paste :lol:)

έγραψε:
migf1 έγραψε:παρατήρησε επίσης πως αρχικοποιώ το msg[] με όλο το μήκος τους γεμάτο μηδενικούς χαρακτήρες στην αρχή

Θα ήταν το ίδιο με;
Κώδικας: Επιλογή όλων
char msg[ MAXINPUT ] = {0};

Γιατί απ' ότι κατάλαβα το '\0' παίζει ρόλο στο να σηματοδοτήσει το "τέλος" του string. Ή υπάρχει λόγος που γίνεται και η αρχικοποίηση έτσι;

Είναι ακριβώς το ίδιο, ναι. Το '\0' ισοδυναμεί με ASCII code = 0 ... το βάζουμε έτσι για να είναι πιο ευδιάκριτο πως πρόκειται για πίνακα χαρακτήρων... έτσι κι αλλιώς εμείς είτε ως 0 είτε ως '\0' αρχικοποιούμε μονάχα το 1ο στοιχείο του πίνακα, τα υπόλοιπα τα μηδενίζει αυτόματα η C (είναι στα χαρακτηριστικά της γλώσσας να μην αρχικοποιεί αυτόματα σε 0 τις μη-καθολικές μεταβλητές, αλλά να αρχικοποιεί αυτόματα με μηδενικά bytes οτιδήποτε περισσεύει από δική μας ελλειπή αρχικοποίηση πινάκων).
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό Star_Light » 03 Μαρ 2012, 17:28

migf1 έγραψε:

ΥΓ. Σχετικά με την scanf, η δική μου απορία είναι: γιατί δεν δοκιμάζεις στα πράξη αυτό που ρωτάς για να δεις πως συμπεριφέρεται; Λιγότερο χρόνο θα σε είχε πάρει :P


Παράθεση σου εκανα επειδη εσυ λες πως δεν ειναι δομη δεδομένων ενω η wikipedia ναι και μπερδευτηκα.
Φυσικα εψαξα για την scanf και θα επανέλθω σε λιγο με αναλυτικό παραδειγμα για οποιον θέλει να ασχοληθει
μαζι της! Αν θελει καποιος να καταλαβαινει ΠΟΥ ειναι ακριβως το προβλημα και δεν πρεπει να τη χρησιμοποιει
πιστευω ειναι χρησιμο να μεινει λιγο περισσοτερο εστιαζοντας σε αυτην.
Γνώσεις ⇛ 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 » 03 Μαρ 2012, 17:32

Νταξει ακομη δεν έχω υλοποιησει στοιβα για να ξερω τι ακριβως ειναι κτλπ.... οποτε οκ
απλα τι διαβασα απο την wikipedia παρέθεσα.
Γνώσεις ⇛ 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 » 03 Μαρ 2012, 17:35

Μιας και το αναφέραμε, όταν διατρέχεις ένα c-string μέχρι να βρεις τον μηδενικό χαρακτήρα, θα συναντήσεις πολύ συχνά το παρακάτω ιδίωμα...

Μορφοποιημένος Κώδικας: Επιλογή όλων
for (int i=0; str[i]; i++) ...

ή το ίδιο πράγμα με δείκτη μετρητή...
Μορφοποιημένος Κώδικας: Επιλογή όλων
for (char *cp=str; *cp; cp++) ...

το μεσαίο τμήμα στην επικεφαλίδα του for που βασικά είναι η ελεγκτική σύγκριση ισοδυναμεί με...
Μορφοποιημένος Κώδικας: Επιλογή όλων
for (int i=0; str[i] != 0; i++) ...
for (char *cp=str; *cp != 0; cp++) ...

ή
Μορφοποιημένος Κώδικας: Επιλογή όλων
for (int i=0; str[i] != '\0'; i++) ...
for (char *cp=str; *cp != '\0'; cp++) ...

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

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

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