Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Οχι δεν θελω να μου κανετε την ασκηση το θεμα ειναι να τα καταλαβω εγω απλως με τα structs δεν το εχω πολυ και τωρα με ολα αυτα που γραφει ο καθηγητης εχω χασει την μπαλα...αυτο που κανετε ειναι παραπολυκαλο και μπραβο σας που ασχολειστε :) και σας ευχαριστω παραπολυ για την σημασια και την βοηθεια που μ εχετε δωσει μεχρι στιγμης!

 

Αυτος ο καθηγητης που εχουμε οντως ειναι μ***(συγνωμη για την εκφραση) :P  πραγματικα εγω πιστευω οτι ειναι απ τους λιγους καθηγητες που ξερω που δεν του αξιζει το μαθημα που κανει!! εχει και ενα αλλο μαθημα οποτε μαλλον αυτο το κανει μονο για τα λεφτα...αλλα σε αυτο δεν φταιει μονο το κρατος φταιμε και εμεις σαν ανθρωποι γιατι αν αυτον δεν τον νοιαζανε μονο τα λεφτα δεν θα εκανε το μαθημα γιατι δεν του αρεσει (τωρα θα μ πειτε χαζος ειναι να μην τα παρει αλλα εγω πιστευω οτι κανονικα ετσι θα επρεπε να γινει) τελος παντων παω παλι στον κωδικα: αυτο ειναι στην main

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


int main(void){
//diko mou

typos_komboy *tree;
Tree_dimiourgia(&tree);
char s[256];
int i=0,error;
FILE *file1,*file2;
if ((file1=fopen("file.txt","r"))==NULL)
{
printf("Unable to open file1.txt\n");
getche(); return 1;
}
while (fscanf(file1,"%255s",s)!=EOF)
{
Tree_eisagogi(&tree,s,&error);
i++;
}

//mexri edw
return 0;
}

αυτο ειναι στο αρχειο BST_pointer-Recursive.c

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "BST_pointer-Recursive.h"

typedef struct typos_komboy
{   TStoixeioyTree dedomena;
	typos_deikti apaidi;
	typos_deikti dpaidi;
} typos_komboy;

void Tree_dimiourgia(typos_deikti *tree)
{     
	*tree=NULL;
}

int Tree_keno(typos_deikti tree)
{    
 	return (tree==NULL);
}

void Tree_eisagogi(typos_deikti *tree, TStoixeioyTree stoixeio, int *error)
{
	if(Tree_keno(*tree))
	{ *tree=malloc(sizeof(typos_komboy));
		if(*tree==NULL)
		{   *error=1;
			return;
		}
		TStree_setValue(&((*tree)->dedomena), stoixeio);
		(*tree)->apaidi=NULL;
		(*tree)->dpaidi=NULL;
	}
	else if(TStree_mikrotero(stoixeio, (*tree)->dedomena))
		Tree_eisagogi(&((*tree)->apaidi), stoixeio, error); 
	else if(TStree_megalytero(stoixeio, (*tree)->dedomena)) 
		Tree_eisagogi(&((*tree)->dpaidi), stoixeio, error); 
	else
		*error=1; 
}

 

 

 

 

auto sto BST_pointer-Recursive.h


#ifndef __BST_POINTER__RECURSIVE_ 
#define __BST_POINTER__RECURSIVE__

#include "typos_stoixeiouDDA.h"

/*diloseis tipon*/
typedef struct typos_komboy * typos_deikti;

void Tree_dimiourgia(typos_deikti *tree);
int Tree_keno(typos_deikti tree);
void Tree_eisagogi(typos_deikti *tree, TStoixeioyTree stoixeio, int *error);

#endif /*#ifndef __BST_POINTER__RECURSIVE__ */

αυτο στο typos_StoixeiouDDA.c (οτι εχω γραψει μεσα ειναι δικα μου)

#include "typos_StoixeiouDDA.h"

int TStree_mikrotero(TStoixeiouTree s1 , TStoixeiouTree s2){
if(strcmp(s1.word,s2.word)>0)
return 1;
else return 0;
}

int TStree_megalytero(TStoixeiouTree s1,TStoixeiouTree s2){

if( strcmp(s1.word,s2.word) <0 )
   return 1;
   else
   return 0;
}

void TStree_setValue (TStoixeiouTree *target, TStoixeiouTree source)
{    
     strcpy(target->word,source.word);
}

και αυτα στο typos_StoixeiouDDA.h

#ifndef __TStoixeioyTree__ 
#define __TStoixeioyTree__
#include <stdio.h>

typedef struct dedomena {
        char word[20]; /* a word */        
} TStoixeioyTree;


int TStree_iso(TStoixeioyTree Elem1, TStoixeioyTree Elem2);
int TStree_mikrotero(TStoixeioyTree Elem1, TStoixeioyTree Elem2);
int TStree_megalytero(TStoixeioyTree Elem1, TStoixeioyTree Elem2);
void TStree_setValue (TStoixeioyTree *target, TStoixeioyTree source);

#endif

αυτα εχει τωρα δεν ξερω αν καλει σωστα τις συναρτησεις παντως το προγραμμα οπως το δινει μεταγλωτιζεται..σορρυ που τα εχω κανει ετσι αλλα δεν ξερω πως γινετε το spoiler

Επεξ/σία από Αννουλα17
  • Απαντ. 40
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Δημοσ.

Αυτό είναι όπως το έδωσε αυτός ή μετά τις αλλαγές σου ? Τέλος πάντων. Ας το δούμε.

 

[rant]

Δεν μπορώ να καταλάβω γιατί αφού σε κάθε σχολή διδάσκεται κάποιο γραφικό IDE που έχει ένα σωρό δυνατότητες όπως το Visual Studio (ή έστω το Dev-C), γιατί δεν διδάσκεται η χρήση του beautifier του IDE ώστε να μην έχει τέτοια εμετική σύνταξη ο κώδικας.

[/rant]

 

Αυτος ο καθηγητης που εχουμε οντως ειναι μ***(συγνωμη για την εκφραση) :P

Ποια σχολή / πόλη ?

 

 

Είπες σε προηγούμενο μήνυμα ότι έχεις πολλά αρχεία και παίρνεις πολλά errors. Ας δούμε γιατί. Καταρχάς να πούμε ότι ο parser παίρνει σβάρνα το αρχείο και το διαβάζει σειρά σειρά. Έτσι για να χρησιμοποιήσεις κάτι στην γραμμή Ν πρέπει το πολύ μέχρι την γραμμή Ν-1 να το έχεις δηλώσει για να μπορεί να καταλάβει τι είναι. Αν η δήλωση υπάρχει μετά την γραμμή Ν, τότε θα πάρεις μήνυμα λάθους.

 

 

#ifndef __TStoixeioyTree__ 
#define __TStoixeioyTree__
#include <stdio.h>

typedef struct dedomena {
        char word[20]; /* a word */        
} TStoixeioyTree;


int TStree_iso(TStoixeioyTree Elem1, TStoixeioyTree Elem2);
int TStree_mikrotero(TStoixeioyTree Elem1, TStoixeioyTree Elem2);
int TStree_megalytero(TStoixeioyTree Elem1, TStoixeioyTree Elem2);

#endif
Εδώ έχεις ένα header file με δηλώσεις. Αυτό το αρχείο το κάνεις include στην αρχή άλλων αρχείων ώστε να φαίνονται οι δηλώσεις όπως είπαμε πριν. Ως εδώ καλά.

 

#include "typos_stoixeiouDDA.h"

int main(void){
typos_komboy *tree;
Tree_dimiourgia(&tree);
Tree_eisagogi(&tree,s,&error);
}
Πάμε στο αρχείο της main (ας πούμε main.c). Έχεις κάνει εισαγωγή το παραπάνω header file το οποίο όμως ενώ έχει κάποιες δηλώσεις, τις τρεις αυτές που χρησιμοποιείς δεν τις έχει οπότε πρέπει να κάνεις include το αρχείο που έχει αυτές τις δηλώσεις.

 

#include "BST_pointer-Recursive.h"

void Tree_eisagogi(typos_deikti *tree, TStoixeioyTree stoixeio, int *error)
{
		TStree_setValue(&((*tree)->dedomena), stoixeio);
}
Πάμε στο BST_pointer-Recursive.c. Εδώ ενώ εισάγεις όλα τα header files, πάλι έχεις πρόβλημα γιατί καλείς την setValue η οποία όμως δεν υπάρχει σε κανένα header file.

 

Μέχρι εδώ είχα κουράγιο να κοιτάξω :) Όμοια θα είναι και για τα άλλα αρχεία. Με λίγα λόγια πρέπει να οργανώσεις καλύτερα τα αρχεία ώστε να υπάρχουν οι δηλώσεις που χρειάζονται.

 

 

http://publications.gbdirect.co.uk/c_book/

http://beej.us/guide/bgc/

http://www2.its.strath.ac.uk/courses/c/

http://www.pottsoft.com/home/c_course/course.html

http://www.lysator.liu.se/c/bwk-tutor.html

http://www.eskimo.com/~scs/cclass/notes/top.html

http://en.wikibooks.org/wiki/C_Programming

http://www.macs.hw.ac.uk/~rjp/Coursewww/Cwww/

 

Κάποιοι οδηγοί για C. Είναι βέβαια αρχαίοι οι περισσότεροι αλλά στο επίπεδο που είσαι δεν πειράζει.

Δημοσ.

συγνωμη το set_value υπαρχει το ξεχασα να το γραψω αλλα το διωρθωσα τωρα.

σε ευχαριστω πολυ για το #include "BST_pointer-Recursive.h" 

το εκανα και ολα οκ! απλως τωρα μ παρουσιαστηκε αλλο προβλημα οταν καλω την συναρτηση tree_eisagogi ενω νομιζω οτι βαζω μεσα στο δεντρο χαρακτηρες στην ουσια δεν μ μπανει τιποτα το δεντρο παραμενει NULL εβαλα μια printf και ειδα οτι το δεντρο ειναι NULL συνεχεια..

 

Ολα δικα του ειναι εκτος απ την main οτι εχω μεσα στο  //diko mou //mexri edw και τις συναρτησεισ mikrotero megalitero set_value..

 

στο καποδιστριακο ειμαι πληροφορικη 

Δημοσ.

αχχαχαχαχαχαχαχαχα ειναι γενικα μην πεσεις στην περιπτωση....π.χ στο προηγουμενο εξαμηνο ειχαμε εναν καθηγητη πολυ καλο ο οποιος και μας ελυνε τις αποριες απο e-mail και οι εκφωνισεις του για τις ασκησεις ηταν πολυ καλες,φανταστειτε ειχε ολοκληρο site με δικους του οι οποιοι ελυναν καθετι απορια μας σε σχεση με την C.(οι δικοι του ηταν φοιτητες οι οποιοι ειχαν περασει τον μαθημα του με 10 και απλως αμα θελανε τους επερνε σαν βοηθους και εγραφε στο βιογραφικο τους οτι ηταν βοηθοι στο μαθημα νομιζω..) αλλα παρολαυτα εγω νομιζω οτι ητανε πολυ καλο αυτο π ειχε κανει..

 

αυτος που εχουμε τωρα ειναι αθλιος..οι εκφωνισεις του ειναι χαλια δεν καταλαβαινεις τπτ..φανταστειτε αυτη π σας εχω δειξει ειναι η τριτη ασκηση και παιζει να ειναι η καλυτερη εκφωνηση π εχει δωσει!! :P μπορει να κανει λαθος μεσα στον κωδικα και μετα απο 10 μερες να το θυμαται (οπως την τελευταια φορα π πηγε ενας φοιτητης και του εκανε παραπονα για τον κωδικα π μασ ειχε δωσει και μας τον εστειλε πισω διωρθομενο χωρις να μας δωσει παραταση δηλαδη αυτος εκανε το λαθος και εμεις να παμε να πνηγουμε)

γενικα αυτος δινει εναν δικο του κωδικα και σου λεει αλλαξε το... ενας φοιτητης του εκανε μια ερωτηση και του λεει θα σ απαντησω μετα τις διακοπες του πασχα...!!!! χαααχαχχα και εχει και αλλα πολλα θα γραφω μεχρι το πρωι αν ειναι να τα πω ολα :P

Δημοσ.

αυτος που εχουμε τωρα ειναι αθλιος..οι εκφωνισεις του ειναι χαλια δεν καταλαβαινεις τπτ..φανταστειτε αυτη π σας εχω δειξει ειναι η τριτη ασκηση και παιζει να ειναι η καλυτερη εκφωνηση π εχει δωσει!! :P μπορει να κανει λαθος μεσα στον κωδικα και μετα απο 10 μερες να το θυμαται (οπως την τελευταια φορα π πηγε ενας φοιτητης και του εκανε παραπονα για τον κωδικα π μασ ειχε δωσει και μας τον εστειλε πισω διωρθομενο χωρις να μας δωσει παραταση δηλαδη αυτος εκανε το λαθος και εμεις να παμε να πνηγουμε)

γενικα αυτος δινει εναν δικο του κωδικα και σου λεει αλλαξε το... ενας φοιτητης του εκανε μια ερωτηση και του λεει θα σ απαντησω μετα τις διακοπες του πασχα...!!!! χαααχαχχα και εχει και αλλα πολλα θα γραφω μεχρι το πρωι αν ειναι να τα πω ολα :P

 

 

Εγώ απο το πρωτο σου μήνυμα σου κατάλαβα ότι πρόκειται για κάποιο δεντρο που του εισάγεις δεδομένα (ίσως με κάποια ταξινόμηση)  από ένα αρχείο. Το θέμα είναι πολύ συγκεκριμένο και δεν δέχεται πολλές ερμηνείες ούτε χρειάζονται διευκρινισεις . 

 

Δλδ πόσο χάλια είναι η εκφώνηση για αυτή την άσκηση.

 

Αν δεν ξέρεις πως να εισάγεις έναν κόμβο σε ένα δεντρο ξανα διαβασε το κεφάλαιο με τα δεντρα και θα δεις ότι δεν θα βγάλει λάθη ο compiler  :-)

 

π.χ. Tree_eisagogi(&tree,s,&error);

 

Βγάλε το "&" απο το tree διότι η Tree_eisagogi  δεχεται δείκτη και όχι διεύθυνση δεικτη.

Δημοσ.

Οχι δεν θελω να μου κανετε την ασκηση το θεμα ειναι να τα καταλαβω εγω απλως με τα structs δεν το εχω πολυ και τωρα με ολα αυτα που γραφει ο καθηγητης εχω χασει την μπαλα...

 

Εγώ θα το πιάσω από εδώ, και θα σε ρωτήσω τι είναι αυτό που δεν έχεις καταλάβει στα struct (δομές) κι αμέσως μετά αν υπάρχει κάτι που δεν έχεις καταλάβει σχετικά με το τι κάνει ένα typedef.

 

Πρέπει πρώτα να εμπεδώσεις τα 2 παραπάνω,  μετά να εμπεδώσεις τα βασικά για pointers (δείκτες) ... για παράδειγμα αν έχεις ορίσει έναν δείκτη: int *p = NULL; να σου είναι απολύτως ξεκάθαρο τι διαφορά έχει το σκέτο p από το *p, καθώς επίσης και το αν, που και πότε μπορείς να τα χρησιμοποιήσεις με ασφάλεια.

 

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

 

Αν έχεις απορίες σε κάποια από τα παραπάνω, και θέλεις να τις ξεκαθαρίσεις ώστε να μπορέσεις να πας παρακάτω, ρώτα ;)

 

Εγώ απο το πρωτο σου μήνυμα σου κατάλαβα ότι πρόκειται για κάποιο δεντρο που του εισάγεις δεδομένα (ίσως με κάποια ταξινόμηση)  από ένα αρχείο. Το θέμα είναι πολύ συγκεκριμένο και δεν δέχεται πολλές ερμηνείες ούτε χρειάζονται διευκρινισεις . 

 

Δλδ πόσο χάλια είναι η εκφώνηση για αυτή την άσκηση.

...

 

Για μένα δεν είναι άθλια η εκφώνηση, αλλά ο κώδικας που την συνοδεύει. Ειδικά το κρύψιμο δεικτών μέσα σε προσαρμοσμένους τύπους, που κι αυτοί έχουν μη συνεπείς ονομασίες (αλλού αρχίζουν με κεφαλαία αλλού με πεζά, αλλού είναι με CamelCase αλλού με _ ανάμεσα στις λέξεις, κλπ, κλπ).

 

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

Δημοσ.

Εγώ απο το πρωτο σου μήνυμα σου κατάλαβα ότι πρόκειται για κάποιο δεντρο που του εισάγεις δεδομένα (ίσως με κάποια ταξινόμηση)  από ένα αρχείο. Το θέμα είναι πολύ συγκεκριμένο και δεν δέχεται πολλές ερμηνείες ούτε χρειάζονται διευκρινισεις . 

 

Δλδ πόσο χάλια είναι η εκφώνηση για αυτή την άσκηση.

 

Αν δεν ξέρεις πως να εισάγεις έναν κόμβο σε ένα δεντρο ξανα διαβασε το κεφάλαιο με τα δεντρα και θα δεις ότι δεν θα βγάλει λάθη ο compiler  :-)

 

π.χ. Tree_eisagogi(&tree,s,&error);

 

Βγάλε το "&" απο το tree διότι η Tree_eisagogi  δεχεται δείκτη και όχι διεύθυνση δεικτη.

δεν θελει να κανει μονο αυτο η ασκηση αλλα και αλλα πολλα αυτο ειμαι μονο το 1/10 απλως ειναι βασικο για να ξεκινησεις...για αυτο σ λεω οτι η εκφωνηση π εχει βγαλει τωρα ειναι η πιο καλη...αμα εβλεπες τισ αλλες θα καταλαβενες..αμα το κανω αυτο π λες μ βγαζει  παλι error τεσπα πιθανοτατα θα την δωσω οποτε δεν πειραζει..

 

Εγώ θα το πιάσω από εδώ, και θα σε ρωτήσω τι είναι αυτό που δεν έχεις καταλάβει στα struct (δομές) κι αμέσως μετά αν υπάρχει κάτι που δεν έχεις καταλάβει σχετικά με το τι κάνει ένα typedef.

 

Πρέπει πρώτα να εμπεδώσεις τα 2 παραπάνω,  μετά να εμπεδώσεις τα βασικά για pointers (δείκτες) ... για παράδειγμα αν έχεις ορίσει έναν δείκτη: int *p = NULL; να σου είναι απολύτως ξεκάθαρο τι διαφορά έχει το σκέτο p από το *p, καθώς επίσης και το αν, που και πότε μπορείς να τα χρησιμοποιήσεις με ασφάλεια.

 

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

 

Αν έχεις απορίες σε κάποια από τα παραπάνω, και θέλεις να τις ξεκαθαρίσεις ώστε να μπορέσεις να πας παρακάτω, ρώτα ;)

 

 

Για μένα δεν είναι άθλια η εκφώνηση, αλλά ο κώδικας που την συνοδεύει. Ειδικά το κρύψιμο δεικτών μέσα σε προσαρμοσμένους τύπους, που κι αυτοί έχουν μη συνεπείς ονομασίες (αλλού αρχίζουν με κεφαλαία αλλού με πεζά, αλλού είναι με CamelCase αλλού με _ ανάμεσα στις λέξεις, κλπ, κλπ).

 

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

οχι δεν θελω μονο την βαθμολογια ετσι και αλλιως δεν δινει και πολλα η ασκηση...απλως θελω να μαθω για να γραψω και τπτ στο τελος...

τα typedef  τα εχω καταλαβει.. 

στα structs  δεν εχω καταλαβει σχεδον τπτ πολυ βασικα πραγματα...βσκ τωρα π βαζουμε ολα αυτα τα δεδομενα στο tree και στην ουσια τα αποθηκευει στο struct πως πανε εκει? ειναι κατι σαν πινακας? ή επειδη ειναι char word[20] αποθηκευοντε εκει με 20 θεσεις? αλλα εγω βαζω περισσοτερα απο 20.. :P :P(σορρυ αν ειναι εντελως βλακεια η ερωτηση αλλα δεν εχω καταλαβει και πολλα) :)

Δημοσ.

οχι δεν θελω μονο την βαθμολογια ετσι και αλλιως δεν δινει και πολλα η ασκηση...απλως θελω να μαθω για να γραψω και τπτ στο τελος...

τα typedef τα εχω καταλαβει..

στα structs δεν εχω καταλαβει σχεδον τπτ πολυ βασικα πραγματα...βσκ τωρα π βαζουμε ολα αυτα τα δεδομενα στο tree και στην ουσια τα αποθηκευει στο struct πως πανε εκει? ειναι κατι σαν πινακας? ή επειδη ειναι char word[20] αποθηκευοντε εκει με 20 θεσεις? αλλα εγω βαζω περισσοτερα απο 20.. :P :P(σορρυ αν ειναι εντελως βλακεια η ερωτηση αλλα δεν εχω καταλαβει και πολλα) :)

Είδες κανένα από τα link που έδωσα ?

 

Φαίνεται να μην ξέρεις/ετε βασικές έννοιες οπότε όσο καλή θέληση και να έχουμε θα είναι δύσκολο να εξηγήσουμε σε ένα μήνυμα ύλη που σε βιβλίο είναι 2-3 κεφάλαια. Τι βιβλίο σας έχει δώσει ? Διάβασε το βιβλίο ή κάποιο από τα link αν δεν είναι καλό και ρώτα μας απορίες.

Δημοσ.

Είδες κανένα από τα link που έδωσα ?

 

Φαίνεται να μην ξέρεις/ετε βασικές έννοιες οπότε όσο καλή θέληση και να έχουμε θα είναι δύσκολο να εξηγήσουμε σε ένα μήνυμα ύλη που σε βιβλίο είναι 2-3 κεφάλαια. Τι βιβλίο σας έχει δώσει ? Διάβασε το βιβλίο ή κάποιο από τα link αν δεν είναι καλό και ρώτα μας απορίες.

ενταξει δε πειραζει θα κατσω να το ψαξω πιο καλα! ευχαριστω παντωσ για ολα!

Δημοσ. (επεξεργασμένο)

...

τα typedef τα εχω καταλαβει..

στα structs δεν εχω καταλαβει σχεδον τπτ πολυ βασικα πραγματα...βσκ τωρα π βαζουμε ολα αυτα τα δεδομενα στο tree και στην ουσια τα αποθηκευει στο struct πως πανε εκει? ειναι κατι σαν πινακας? ή επειδη ειναι char word[20] αποθηκευοντε εκει με 20 θεσεις? αλλα εγω βαζω περισσοτερα απο 20.. :P :P(σορρυ αν ειναι εντελως βλακεια η ερωτηση αλλα δεν εχω καταλαβει και πολλα) :)

 

struct & typedef

 

Ο κύριος λόγος χρήσης δομών είναι για να ομαδοποιούμε πολλές μεταβλητές σε μια. Μας διευκολύνει πολύ τόσο στην οργάνωση του κώδικά μας, όσο και στο να είναι ευανάγνωστος.

 

Αν υποθέσουμε πως θέλουμε να απεικονίσουμε ένα σημείο με συντεταγμένες x και y, η 1η σκέψη μας είναι να ορίσουμε τις συντεταγμένες ως 2 int...

int main( void )
{
	int x=5, y=0;
	...
Ένα πρόβλημα είναι πως έτσι δεν υπάρχει καμία ένδειξη ότι τα x και y αναφέρονται σε συντεταγμένες ενός σημείου, εκτός ίσως από την προσθήκη σχολίων στον ορισμό τους...

int main( void )
{
	int x=5, y=0;	/* συντεταγμένες σημείου */
	...
Αν τώρα το πρόγραμμά μας χρειάζεται να χειριστεί πολλά σημεία, αρχίζουμε να έχουμε πρόβλημα, διότι για κάθε σημείο θα πρέπει να ορίζουμε αντίστοιχες x και y μεταβλητές...

int main( void )
{
	int x1=5, y1=0;		/* συντεταγμένες 1ου σημείου */
	int x2=2, y2=10;	/* συντεταγμένες 2ου σημείου */
	int x3=15, y3=0;	/* συντεταγμένες 3ου σημείου */
	...
Φαντάσου τώρα ότι θέλουμε να φτιάξουμε μια συνάρτηση η οποία θα δέχεται ως ορίσματα 3 σημεία και θα μας επιστρέφει 1 (true) αν αυτά τα σημεία μπορούν να ορίσουν τρίγωνο ή 0 (false) αν δεν μπορούν. Η υπογραφή αυτής της συνάρτησης (prototype ή signature) θα έπρεπε να οριστεί κάπως έτσι...

int is_valid_triangle( int x1, int y1, int x2, int y2, int x3, int y3 );
Αντί λοιπόν να έχουμε χύμα όλες αυτές τις μεταβλητές για να περιγράφουμε σημεία, μπορούμε φτιάξουμε μια δομή Point (struct) η οποία θα ορίζει ένα σημείο από τις συντεταγμένες του...

struct Point {
	int x, y;
};
Αμέσως-αμέσως έχουμε απλοποιήσει οργανωτικά τον κώδικά μας στο εξής:

struct Point {
	int x, y;
};

/* prototypes of functions to be used */
int is_valid_triangle( struct Point pt1, struct Point pt2, struct Point pt3 );

int main( void )
{
	struct Point pt1 = {5, 0};     /* ή σε C99+: struct Point pt1 = {.x=5, .y=0} */
	struct Point pt2 = {2, 10};    /* ή σε C99+: struct Point pt1 = {.x=2, .y=10} */
	struct Point pt3 = {15, 0};    /* ή σε C99+: struct Point pt1 = {.x=15, .y=0} */
	...
Σχεδόν δεν χρειάζονται καν σχόλια πλέον, μιας και ο κώδικας είναι αρκούντως περιγραφικός από μόνος του, ειδικά αν τον γράψουμε με σύνταξη C99 ή μεταγενέστερης.

 

Χρησιμοποιώντας και typedef μπορούμε να απλοποιήσουμε ακόμα περισσότερο τον κώδικά μας...

typedef struct Point {
	int x, y;
}Point;

/* prototypes of functions to be used */
int is_valid_triangle( Point pt1, Point pt2, Point pt3 );

int main( void )
{
	Point pt1 = {5, 0};     /* ή σε C99+: Point pt1 = {.x=5, .y=0} */
	Point pt2 = {2, 10};    /* ή σε C99+: Point pt1 = {.x=2, .y=10} */
	Point pt3 = {15, 0};    /* ή σε C99+: Point pt1 = {.x=15, .y=0} */
	...
Μια πιο συνηθισμένη χρήση του typedef όταν φτιάχνουμε βιβλιοθήκες και θέλουμε να κρύψουμε την υλοποίηση μιας δομής από τους χρήστες της βιβλιοθήκες, είναι με forward declaration, ως εξής...

/*
εκ των προτέρων δήλωση προσαρμοσμένου τύπου (forward declaration)
στο public header file της βιβλιοθήκης, χωρίς δηλαδή να φαίνεται
η υλοποίηση της δομής
*/
typedef struct Point Point;

/*
η υλοποίηση της δομής σε κάποιο ιδιωτικό header file της βιβλιοθήκης
*/
struct Point {
	int x, y;
};
Το forward declaration είναι χρήσιμο κι όταν ορίζουμε δομές κόμβου, για να μην γράφουμε το struct όταν ορίζουμε αναδρομικά πεδία της δομής...

typedef struct Node Node;
struct Node {
	void *data;
	Node *prev;	/* αντί για: struct Node *prev; */
	Node *next;	/* αντί για: struct Node *next; */
};
Με ή χωρίς typedef, όταν θέλουμε να αναφερθούμε στο πεδίο (field) μια δομής μέσω μιας μεταβλητής που την έχουμε ορίσει τύπου δομής, γράφουμε το όνομα της μεταβλητής, μια τελεία και το όνομα του πεδίου...

int main( void )
{
	Point pt;
	...
	pt.x = 5;
	pt.y = 0;
	...
Αν την μεταβλητή μας την έχουμε ορίσει ως δείκτη, τότε αντί για τελεία χρησιμοποιούμε -> ...

int main( void )
{
	Point *pt = malloc( sizeof(Point) );
	if ( NULL == pt )   /* malloc failed */ {
		exit(1);
        }
	...
	pt->x = 5;
	pt->y = 0;
	...
	free( pt );
 

Η εκφώνηση της άσκησής σου

 

Σύμφωνα λοιπόν με όλα τα παραπάνω, ο ορισμός ...

typedef struct dedomena {
	char word[20]; /* a word */        
} TStoixeioyTree;
που δίνει η εκφώνηση της άσκησής σου ορίζει την δομή dedomena να περιέχει έναν πίνακα 20 χαρακτήρων (προφανώς εννοεί cstring, δηλαδή NUL terminated), και κατόπιν ορίζει την δομή ως προσαρμοσμένο τύπο με όνομα TStoixeioyTree.

 

Το συγκεκριμένο coding style που χρησιμοποιεί βέβαια είναι ψιλο-χοντρο άθλιο. Ένα πολύ πιο sane wording θα μπορούσε να ήταν κάπως έτσι...

typedef struct Dedomena {
    char word[20];
}Dedomena;
έτσι ώστε αν θέλαμε να αρχικοποιήσουμε μια μεταβλητή dedomena τύπου Dedomena, και να την τυπώσουμε, θα γράφαμε...

int main( void )
{
	Dedomena dedomena = {.word = "I am a word"};
	puts( dedomena.word );
	...
Στο συγκεκριμένο παράδειγμα δεν φαίνεται να υπάρχει και καμιά τεράστια διοφορά συγκριτικά με το...

int main( void )
{
	TStoixeioyTree dedomena = {.word = "I am a word"};
	puts( dedomena.word );
	...
αλλά αν ήταν συνεπής ως προς ένα πιο sane στυλ γραφής η εκφώνησή σου, θα μπορούσε να γραφεί κάπως έτσι...

typedef struct Dedomena {
    char word[20];
}Dedomena;

typedef struct Kombos Kombos;
struct Kombos
{
	Dedomena dedomena;	/* απλό πεδίο */
	Kombos *apaidi;		/* δείκτης */
	Kombos *dpaidi;		/* δείκτης */
};
το οποίο νομίζω δεν θα υπάρξει άνθρωπος πάνω στον πλανήτη γη που δεν θα συμφωνήσει πως είναι μακράν πιο κατανοητό κι ευανάγνωστο από το (μη) στυλ γραφής που χρησιμοποιεί η εκφώνησή σου. Όχι μόνο στο συγκεκριμένο σημείο, αλλά και κατά την διάρκεια ολόκληρου το πρότζεκτ (που είναι μάλιστα και multi-file project).

 

Βλέποντας το είναι άμεσα κατανοητός όχι μόνο ο τύπος του κάθε πεδίου, αλλά και το αν το πεδίο αυτό είναι απλό πεδίο ή δείκτης (π.χ. τα πεδία apaidi και dpaidi είναι δείκτες σε τύπο Kombos, ενώ το πεδίο dedomena είναι απλό πεδίο τύπου Dedomena).

 

Ένα τέτοιο στυλ γραφής είναι κατά την άποψή μου παραπάνω από ικανοποιητικό για να εξοικειωθεί κανείς με δομές, λίστες, δέντρα, κλπ.

 

Η εκφώνησή σου δυστυχώς προσθέτει ακόμα ένα αχρείαστο μπέρδεμα στα τόσα υπόλοιπα προβλήματά της. Φτιάχνει έναν ακόμα προσαρμοσμένο τύπο (typedef) ο οποίος κρύβει μέσα του δείκτη σε κόμβο, και ονομάζει αυτόν τον τύπο typos_deikth (ούτε καν: typos_deikth_komboy). Κατόπιν ορίζει τα πεδία apaidi και dpaidi ως typos_deikth, αφαιρώντας οπτικάαπό τον ορισμό αυτών των πεδίων τους αστερίσκους (οι οποίοι κάνουν μπαμ πως μιλάμε για δείκτες όταν υπάρχουν).

 

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

 

Πέραν του ότι στην συγκεκριμένη περίπτωση είναι όχι μόνο τελείως άχρηστη αυτή η τεχνική, αλλά περιπλέκει και αχρείαστα τα πάντα, ο τρόπος με τον οποίον επιχειρεί να την χρησιμοποιήσει η εκφώνηση είναι επιεικώς άθλια!

 

Το λιγότερο που πρέπει να κάνουμε όταν αποφασίσουμε να κρύψουμε δείκτη μέσα σε έναν προσαρμοσμένο τύπο, είναι να συμπεριλάβουμε στην ονομασία του και τον τύπο στον οποίον δείχνει. Προφανώς συνδυασμένο με μια σύντμηση που να υποδηλώνει πως μιλάμε για τύπο δείκτη (αυτό το τελευταίο το κάνει η εκφώνηση, τον λέει 'typοs_deikth' δηλαδή, μόνο που δεν μας λέει σε ποιον τύπο δείχνει... ΒΟΗΘΕΙΑ ΜΑΣ!). Η σύντμηση αυτή συνήθως είναι Ptr και μπορεί να χρησιμοποιηθεί είτε ως πρόθεμα, είτε ως επίθεμα.

 

Χρησιμοποιώντας τώρα ένα sane στυλ γραφής, αυτό που κάνει η εκφώνησή σου μπορεί να εκφραστεί ως εξής:

typedef struct Dedomena {
    char word[20];
}Dedomena;

/*
ταυτόχρονος ορισμός 2 προσαρμοσμένων τύπων,
ενός απλού (Kombos) κι ενός με απόκρυψη δείκτη (PtrKombos)
*/
typedef struct Kombos Kombos, *PtrKombos;
struct Kombos
{
	Dedomena dedomena;	/* απλό πεδίο */
	PtrKombos apaidi;	/* δείκτης */
	PtrKombos dpaidi;	/* δείκτης */
};
Επαναλαμβάνω πως είμαι αντίθετος με την απόκρυψη δεικτών μέσα σε τύπους, και για την συγκεκριμένη περίπτωση είμαι μάλιστα κάθετα αντίθετος.

 

Εφόσον όμως το θέλει έτσι, συνέκρινε το παραπάνω με αυτό που σας έχει δώσει...

typedef struct dedomena {
	char word[20]; /* a word */        
} TStoixeioyTree;

typedef struct typos_komboy *typos_deikti;
typedef struct typos_komboy
{
	TStoixeioyTree dedomena;
	typos_deikti apaidi;
	typos_deikti dpaidi;
} typos_komboy;
Από εκεί και πέρα λοιπόν είναι απόλυτα φυσιολογικό να χάνει η μάνα το παιδί και το παιδί τη μάνα στις συναρτήσεις που διαχειρίζονται αυτές τις δομές. Ειδικά για φοιτητές που προσπαθούν να εξοικειωθούν με τις βασικές έννοιες και ορολογίες.

 

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

 

Αν κολλήσεις κάπου αλλού, ρώτα.

 

EDIT: τυπογραφικά

Επεξ/σία από temp_
  • Like 2
Δημοσ.

Τα μέλη μιας δομής (οι τιμές τους) περνάνε  συνεχόμενα στην μνήμη οπως παιζει και με τους πινακες? νομιζω δεν ειναι σιγουρο αυτο ή ειναι?

Δημοσ.

Συνεχόμενα είναι ως πεδία, αλλά ο compiler είναι ελεύθερος να παρεμβάλλει padding μεταξύ τους για να τα στοιχίσει σε εύρη addressable words. Ανάλογα με τον compiler μπορείς να απενεργοποιήσεις το padding (είτε με ειδικά keywords στον κώδικα, είτε με #pragma directives στον προ-επεξεργαστή).

  • Like 2
Δημοσ.

Ο King στο βιβλιο του στην Σελ. 382 λεει πως άν δηλώσεις 2 δομές σε διαφορετικά σημεια του προγραμματος

 

 

 
struct {
    int number;        
    char name[NAME_LEN+1];
    int on_hand;           
} part1 ;

struct {
    int number;        
    char name[NAME_LEN+1];
    int on_hand;           
} part2 ;
 

 

Οτι θα προκυψει θέμα και οτι "bloat" το προγραμμα , το να αλλαξεις το προγραμμα αργοτερα μπορει να ειναι ριψοκινδυνο (θα βγει ένα χέρι απο την οθονη και θα σε αρπαξει και θα σε χωσει στα αδυτα του λειτουργικου συστηματος εκει που κανει κουμαντο η fork και η exec  !!! :P )  και οτι δεν ειναι σιγουρο πως οι δηλωσεις στις δομες θα μεινουν σταθερες.... τεσπα ποιο ειναι το προβλημα? Δεν εχω καταλαβει καλα.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...