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

migf1 έγραψε:Το ότι θες μεταβλητή για να χρησιμοποιήσεις μια δομή είναι θέμα γλώσσας. Το να μπορείς να αρχικοποιείς μεταβλητές τύπου struct μπήκε στη γλώσσα με την αναθεώρηση του 1999.



struct_function(p) &(*p).age int x;
&x => (& = ΔΙΕΥΘΥΝΣΗ) + x = στοιχειο) οποτε ολο μαζι διευθυνση στοιχειου (*p).age 
Star_Light έγραψε:εφτασα και στο τελευταιο step πλεον πριν αρχισω να κοιταω τον κωδικα σου....
Δομες και δείκτες (μεσα σε συναρτηση)Spoiler: show
#include <stdio.h>
#include <stdlib.h> // για atoi()
// Macros
#define MAXSLEN (254 + 1) // MAXimum String LENgth
// Πρόσθετοι Τύποι Δεδομένων
typedef struct person // ορισμός δομής person ως πρόσθετο τύπο
{ // με το όνομα Person (λόγω του typedef)
char name[ MAXSLEN ]; // ... 1ο πεδίο της δομής
char surname[ MAXSLEN ]; // ... 2ο πεδίο της δομής
int age; // ... 3ο πεδίο της δομής
} Person; // το όνομα του πρόσθετου τύπου
// Πρότυπα Συναρτήσεων
char *s_getflushed(char *s, size_t len); // αντί fgets, για να μην κρατάει το '\n'
void read_person( Person *someone ); // για διάβασμα των πεδίων της someone
void print_person( Person someone ); // για τύπωμα των πεδίων της someone
// -------------------------------------------------------------------------------
int main( void )
{
Person someone; // η someone είναι μεταβλητή τύπου Person
read_person( &someone ); // πέρασμα της someone by reference
print_person( someone ); // πέρασμα της someone by value
return 0;
}
// -------------------------------------------------------------------------------
char *s_getflushed(char *s, size_t len)
{
char *cp;
for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ )
;
if ( *cp != '\n') { // len reached withoutn '\n'
*cp = '\0'; // null terminate s and
while (getchar() != '\n') // flush remaining chars
;
}
else // '\n' found
*cp = '\0'; // null-terminate
return s;
}
// -------------------------------------------------------------------------------
void read_person( Person *someone ) // by reference πέρασμα της someone
{ // άρα χρήση του -> για τα πεδία της
char inbuf[ 254+1 ] = {'\0'};
printf("Dwse to onoma sou: ");
s_getflushed( someone->name, MAXSLEN );
printf("Dwse to epwnumo sou: ");
s_getflushed( someone->surname, MAXSLEN );
printf("Dwse tin ilikia sou: ");
s_getflushed( inbuf, MAXSLEN );
someone->age = atoi( inbuf );
return;
}
// -------------------------------------------------------------------------------
void print_person( Person someone ) // by value πέρασμα της someone
{ // άρα χρήση τελείας για τα πεδία της
puts("========================================");
printf("To onoma pou edwses einai: %s\n", someone.name);
printf("To epwnimo pou edwses einai: %s\n", someone.surname);
printf("H ilikia pou edwses einai: %d\n", someone.age);
putchar('\n');
return;
}
struct person {
char name[ MAXSLEN ];
char surname[ MAXSLEN ];
int age;
};
typedef struct person Person;
typedef struct person {
char name[ MAXSLEN ];
char surname[ MAXSLEN ];
int age;
} Person;

(*p).age 
Star_Light έγραψε:
...
το μονο που ηταν λιγο αμφιλεγομενο ηταν το
struct_function(p) αλλα και παλι δεν δεχεται καποια τροποποιηση. Απλα ουσιαστικα λες στην συναρτηση να κληθει με βαση αυτη την διευθυνση που ειναι η διευθυνση της δομης απο την οποια θα εκτυπωσει στοιχεια...
ειμαι καπου λαθος?
έγραψε:
Το
- Κώδικας: Επιλογή όλων
(*p).age
ΟΚ το γραφουμε οπως το λες... αλλα το ιδιο πραγμα λεμε...
Eχεις καποιο λογο που προτιμας πιο πολυ αυτη τη γραφη???? (με τον τελεστη εμμεσης σχεσης)

migf1 έγραψε:Καλημέρα,Star_Light έγραψε:εφτασα και στο τελευταιο step πλεον πριν αρχισω να κοιταω τον κωδικα σου....
Δομες και δείκτες (μεσα σε συναρτηση)Spoiler: show
Έτσι όπως έχεις γράψει τον κώδικα μπερδεύονται τα πράγματα, ενώ είναι πολύ πιο απλά! Ο κώδικάς σου για να αντιστοιχεί και στην ανθρώπινη σκέψη και άρα να είναι μακράν πιο κατανοητός πρέπει να γραφτεί κάπως έτσι...
- Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h> // για atoi()
// Macros
#define MAXSLEN (254 + 1) // MAXimum String LENgth
// Πρόσθετοι Τύποι Δεδομένων
typedef struct person // ορισμός δομής person ως πρόσθετο τύπο
{ // με το όνομα Person (λόγω του typedef)
char name[ MAXSLEN ]; // ... 1ο πεδίο της δομής
char surname[ MAXSLEN ]; // ... 2ο πεδίο της δομής
int age; // ... 3ο πεδίο της δομής
} Person; // το όνομα του πρόσθετου τύπου
// Πρότυπα Συναρτήσεων
char *s_getflushed(char *s, size_t len); // αντί fgets, για να μην κρατάει το '\n'
void read_person( Person *someone ); // για διάβασμα των πεδίων της someone
void print_person( Person someone ); // για τύπωμα των πεδίων της someone
// -------------------------------------------------------------------------------
int main( void )
{
Person someone; // η someone είναι μεταβλητή τύπου Person
read_person( &someone ); // πέρασμα της someone by reference
print_person( someone ); // πέρασμα της someone by value
return 0;
}
// -------------------------------------------------------------------------------
char *s_getflushed(char *s, size_t len)
{
char *cp;
for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ )
;
if ( *cp != '\n') { // len reached withoutn '\n'
*cp = '\0'; // null terminate s and
while (getchar() != '\n') // flush remaining chars
;
}
else // '\n' found
*cp = '\0'; // null-terminate
return s;
}
// -------------------------------------------------------------------------------
void read_person( Person *someone ) // by reference πέρασμα της someone
{ // άρα χρήση του -> για τα πεδία της
char inbuf[ 254+1 ] = {'\0'};
printf("Dwse to onoma sou: ");
s_getflushed( someone->name, MAXSLEN );
printf("Dwse to epwnumo sou: ");
s_getflushed( someone->surname, MAXSLEN );
printf("Dwse tin ilikia sou: ");
s_getflushed( inbuf, MAXSLEN );
someone->age = atoi( inbuf );
return;
}
// -------------------------------------------------------------------------------
void print_person( Person someone ) // by value πέρασμα της someone
{ // άρα χρήση τελείας για τα πεδία της
puts("========================================");
printf("To onoma pou edwses einai: %s\n", someone.name);
printf("To epwnimo pou edwses einai: %s\n", someone.surname);
printf("H ilikia pou edwses einai: %d\n", someone.age);
putchar('\n');
return;
}
Τον γέμισα με Ελληνικά σχόλια ελπίζοντας πως ξεκαθαρίζει τα πράγματα και μπορεί να χρησιμοποιηθεί και ως γρήγορος οδηγός για φρεσκάρισμα μνήμης. Εδώ και με syntax-highlighting: http://ideone.com/tw7BS
Ορίζουμε μια δομή struct person, την μετατρέπουμε σε πρόσθετο τύπο Person με το typedef και ορίζουμε μια μεταβλητή someone να είναι τύπου Person. Κατόπιν περνάμε την someone by reference στη συνάρτηση read_person() επειδή θέλουμε να διατηρηθούν οι αλλαγές που θα γίνουν στα πεδία της (διαβάζουμε νέες τιμές για τα πεδία). By reference σημαίνει πως μέσα στη συνάρτηση έχει οριστεί ως δείκτης, άρα εκεί μέσα όταν θέλουμε να αναφερθούμε σε κάποιο πεδίο της το κάνουμε με το σύμβολο ->
Τέλος περνάμε την someone by value στη συνάρτηση print_person() επειδή δεν θα αλλάξουμε τιμές στα πεδία της μέσα στη συνάρτηση. By value σημαίνει πως μέσα στη συνάρτηση ΔΕΝ έχει οριστεί ως δείκτης, άρα εκεί μέσα όταν θέλουμε να αναφερθούμε σε κάποιο πεδίο της το κάνουμε με το σύμβολο της τελείας .
Με άλλα λόγια, σε επίπεδο main() η someone συμπεριφέρεται όπως οποιαδήποτε άλλη μεταβλητή και η μόνη διαφορά με τις κανονικές μεταβλητές είναι πως δεν έχει μια ενιαία τιμή, έχει επιμέρους τιμές στο καθένα από τα πεδία της.
Και μερικές συμβουλές για ευανάγνωστο κώδικα:
α) τους πρόσθετους τύπους που ορίζουμε με typedef τους γράφουμε με κεφαλαίο το πρώτο τους γράμμα.
β) αν ο πρόσθετος τύπος είναι δομή, τότε στον ορισμό της δομής, δίπλα στο struct γράφουμε το ίδιο όνομα αλλά με πεζά γράμματα.
Π.χ...
- Κώδικας: Επιλογή όλων
struct person {
char name[ MAXSLEN ];
char surname[ MAXSLEN ];
int age;
};
typedef struct person Person;
ή σε ένα μόνο βήμα...
- Κώδικας: Επιλογή όλων
typedef struct person {
char name[ MAXSLEN ];
char surname[ MAXSLEN ];
int age;
} Person;
ΥΓ. Το (*p).age το γράφουμε: p->age και η διεύθυνσή του είναι: &p->age
migf1 έγραψε: Είναι δηλαδή σαν να με ρωτάς για ποιο λόγο προτιμάς γενικώς στους δείκτες τη γραφή: p αντί της: &(*p)
&(*p) struct_function(p) 
int main(void)
{
kostas someone , *p;
p=&someone;
struct_function(p) ;
===> printf("%s",p->surname); <==========
return 0;
}
