migf1 έγραψε:Οκ λοιπόν, ας περάσουμε τώρα στο...
- Κώδικας: Επιλογή όλων
char *s = "this is a test";
Εδώ βασικά ΔΕΝ έχουμε string, έχουμε ένα
string literal ή αλλιώς, μια σταθερά τιμή τύπου string, σαν να την είχαμε ορίσει με #define...
- Κώδικας: Επιλογή όλων
#define STR_LITERAL "this is a test"
int main( void )
{
char *s = STR_LITERAL;
...
}
Ο πιο γρήγορος τρόπος για να καταλάβετε σε αυτό το παράδειγμα πως το s δεν είναι string αλλά απλός δείκτης, είναι να κάνετε ένα: sizeof( s ); και να διαπιστώσετε πως το μέγεθός του δεν είναι το πλήθος των χαρακτήρων του string + 1 για τον μηδενικό χαρακτήρα, αλλά είναι 4 bytes (ή 8 bytes στις 64μπιτες πλατφόρμες) που απεικονίζει το μέγεθος του δείκτη s, που είναι ίδιο για όλους τους δείκτες!
Κατόπιν, μπορείτε να δοκιμάσετε να κάνετε κάτι τέτοιο:
- Κώδικας: Επιλογή όλων
s[1] = 'a;'
ή κάτι τέτοιο:
- Κώδικας: Επιλογή όλων
*s = 'a;'
και να διαπιστώσετε πως ο compiler δεν θα παραπονεθεί, αλλά το πρόγραμμα θα κρασάρει!!! Ο λόγος είναι πως τα string literals ΔΕΝ μπορούμε να τα αλλάξουμε, μόνο να τα διαβάσουμε ή να τα χρησιμοποιήσουμε απείραχτα (read only).
Αν θέλουμε ντε και καλά να φτιάξουμε ένα string ορίζοντάς το ως δείκτη και όχι ως πίνακα, τότε πρέπει εκτός από τον ορισμό του δείκτη να δεσμεύσουμε και μνήμη για το μέγιστο πλήθος των χαρακτήρων που θέλουμε να φιλοξενεί + 1 για τον μηδενικό χαρακτήρα. Θα μπορούμε κατόπιν να το διαχειριστούμε σαν κανονικό string, αλλά πριν τερματίσουμε το πρόγραμμά μας θα πρέπει να απελευθερώσουμε τη μνήμη που δεσμεύσαμε...
- Κώδικας: Επιλογή όλων
int main( void )
{
char *s = NULL;
s = calloc( μέγιστο_πλήθος_χαρακτήρων + 1, sizeof(char) );
...
printf("%lu\n", sizeof( s ) );
...
free( s );
return 0;
Σημειώστε πως στον παραπάνω κώδικα δεσμεύω τη μνήμη με calloc() και όχι με malloc(), διότι η calloc() γεμίζει με μηδενικά τη μνήμη που δεσμεύει, που στην περίπτωσή μας μας έρχεται... ταμάμ, διότι ισοδυναμεί με γέμισμα του string s με μηδενικούς χαρακτήρες σε όλο του το μήκος.
Ανεξάρτητα με την ευεργετική αυτή ιδιότητα σε strings που δημιουργούμε δυναμικά, να προτιμάτε πάντα την calloc() έναντι της malloc() για οποιονδήποτε τύπο δεικτών.
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Και για να κλείσουμε το κομμάτι των ορισμών, στη C τα string literals μπορείτε να τα χρησιμοποιείται και απευθείας, είτε οριζοντάς τα με #define είτε όχι.
Π.χ.
- Κώδικας: Επιλογή όλων
int main( void )
{
if ( "this is a test"[ 1 ] == 'h' )
...
else
...
return 0;
}
ή πιο όμορφα...
- Κώδικας: Επιλογή όλων
#define MESSAGE "this is a test"
int main( void )
{
if ( MESSAGE[ 1 ] == 'h' )
...
else
...
return 0;
}
και προφανώς και με χρήση δείκτη, όπως είπαμε σήμερα...
- Κώδικας: Επιλογή όλων
int main( void )
{
char *s = "this is a test";
if ( s[ 1 ] == 'h' )
...
else
...
return 0;
}
ή με συνδυασμό τους...
- Κώδικας: Επιλογή όλων
#define MESSAGE "this is a test"
int main( void )
{
char *s = MESSAGE;
if ( s[ 1 ] == 'h' )
...
else
...
return 0;
}
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Τα strings literals λοιπόν τα χρησιμοποιούμε σαν READ ONLY σταθερές τιμές τύπου string.
Ακούω (τυχόν) απορίες, για να συνεχίσουμε.