imitheos Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 Γιατί μπορείς μόνο με char; ΥΓ. Δεν είναι εριστική η ερώτησή μου, απορία είναι. Γιατί βγαίνεις από τα όρια του τύπου της μεταβλητής. Είναι ο ίδιος λόγος που όταν έχεις ένα πίνακα int a[3][3], η δήλωση a[1][0] είναι σωστή ενώ η δήλωση a[0][3] είναι λάθος άσχετα αν δείχνουν στην ίδια ακριβώς διεύθυνση στη μνήμη. Είναι εγγυημένο ότι τα στοιχεία του πίνακα θα υφίστανται συνεχόμενα και πως μπορείς να προσπελάσεις τις θέσεις με char * (αλλιώς δεν θα μπορούσε να παίξει η memcpy) αλλά όχι τίποτα άλλο. Είναι καθαρά τυπικό θέμα και το ανέφερα εγκυκλοπαιδικά. Πρακτικά δεν έχω δει καμμία πλατφόρμα που να μην παίζει αυτό που έγραψες. Για να είμαι 100% σωστός, ούτε αυτό που έδωσα είναι εγγυημένο ότι θα παίξει σωστά γιατί έχω το "p = (int *)c;". Μόνο το οτιδήποτε->char* είναι εγγυημένο και όχι το ανάποδο. Παιδια αν μπορει καποιος να μου πει κατι σχετικο σε αυτο που ρωτησα, θα με βοηθουσε παρα πολυ...Ευχαριστω Δεν έχω χρησιμοποιήσει eclipse σε windows αλλά σε *nix τα errors εμφανίζονται στο παράθυρο console. Λογικά δεν σε βοηθάει αλλά το αναφέρω μήπως και.
migf1 Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 Γιατί βγαίνεις από τα όρια του τύπου της μεταβλητής. Είναι ο ίδιος λόγος που όταν έχεις ένα πίνακα int a[3][3], η δήλωση a[1][0] είναι σωστή ενώ η δήλωση a[0][3] είναι λάθος άσχετα αν δείχνουν στην ίδια ακριβώς διεύθυνση στη μνήμη. Είναι εγγυημένο ότι τα στοιχεία του πίνακα θα υφίστανται συνεχόμενα και πως μπορείς να προσπελάσεις τις θέσεις με char * (αλλιώς δεν θα μπορούσε να παίξει η memcpy) αλλά όχι τίποτα άλλο. Είναι καθαρά τυπικό θέμα και το ανέφερα εγκυκλοπαιδικά. Πρακτικά δεν έχω δει καμμία πλατφόρμα που να μην παίζει αυτό που έγραψες. Βασικά δεν θυμάμαι αν αναφέρεται στο πρότυπο επίσημα, γνωρίζω όμως πως είναι θεμιτό απλά να εξετάζεις τη μνήμη που έπεται αμέσως μετά το όριο ενός πίνακα, χωρίς να κάνεις access τα περιεχόμενό της. Χρησιμοποιείται και συχνά (ή μάλλον χρησιμοποιούταν παλαιότερα, για τώρα δεν ξέρω) Αυτό εννοούσες; @nik234: Ούτε εγώ χρησιμοποιώ Eclipse.
imitheos Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 Βασικά δεν θυμάμαι αν αναφέρεται στο πρότυπο επίσημα, γνωρίζω όμως πως είναι θεμιτό απλά να εξετάζεις τη μνήμη που έπεται αμέσως μετά το όριο ενός πίνακα, χωρίς να κάνεις access τα περιεχόμενό της. Χρησιμοποιείται και συχνά (ή μάλλον χρησιμοποιούταν παλαιότερα, για τώρα δεν ξέρω) Ναι αναφέρεται αυτό και ισχύει. Δεν έχει σχέση με αυτό που λέμε όμως. Δες αυτό που είπα πριν. Έχεις ένα πίνακα int a[3][3]. Η έκφραση a[1][0] ισοδυναμεί με a + 1*3 + 0 και η έκφραση a[0][3] ισοδυναμεί με a + 0*3 + 3 δηλαδή δείχνουν στην ίδια διεύθυνση. Παρόλα αυτά η έκφραση a[0][3] δεν είναι σωστή σύμφωνα με το πρότυπο. Αν όμως ελέγχαμε το &a[1][0] και το &a[0][3] τότε αυτό θα ήταν σωστό για το λόγο που ανέφερες και οι δύο δείκτες θα ήταν ίσοι. Το ίδιο ισχύει και με την άσκηση που λέμε. Έχουμε ένα δισδιάστατο πίνακα με 2 στήλες και 3 γραμμές οπότε στη μνήμη θα έχουμε 6 συνεχόμενους int οπότε πρακτικά είναι το ίδιο με ένα μονοδιάστατο πίνακα με 6 int αλλά για το πρότυπο δεν είναι το ίδιο. > for (int *walk = (int *)arr2d; walk < ((int *)arr2d + nrows * NCOLS); walk++) Εδώ μεταχειρίζεσαι τον arr2d σαν να ήταν μονοδιάστατος πίνακας με 6 στοιχεία που δεν είναι σωστό. Για να προσπελάσεις τον πίνακα πρέπει να το κάνεις είτε με το σωστό δισδιάστατο τύπο ή με char (ή με union σε c99 και πέρα). Όλα αυτά εγκυκλοπαιδικά - ακαδημαϊκά πάντα. Πρακτικά παίζει παντού.
Star_Light Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 ΗΜιθεε αρα ο δικος μου τρόπος με τον δισδιάστατο πίνακα και παιζει παντου και ειναι σωστος συμφωνα με τα ακαδημαικα - εγκυκλοπαιδικα προτυπα!!!!!! Ρε συ migf1 για ποιο λογο κάνεις cast σε δεικτη τον arr2d ? Δηλαδη σε τι χρησιμευει αυτο ακριβως... αφου και παλι δεν μπορεις να δωσεις arr2d++ ; υ.γ Δεν ηξερα οτι υπάρχει a[0][3] ... ειχα στο μυαλο μου πως αμεσως μετα παει το a[1][0] που οντως παει δηλαδη αλλα εσυ μαλλον αναφερεσαι πως εφοσον η μνημη ειναι συνεχομενη μπορεις να παιξεις οπως θελεις με τους δεικτες της διαταξης αν και δεν καταλαβαινω αφου 4η στηλη δεν υπάρχει. Προφανως και ΔΕΝ ειναι σωστο. υ.γ2 Παντως ο King έχει παράδειγμα κανονικοτατο στο οποιο περνάει τον δισδιάστατο σαν μονοδιάστατο σε μια συναρτηση που έχει δηλωθει να περιμενει μονοδιαστατο και κανει στο ετσι την εργασια. Τέλος Σελ. 268 - 269 Δεν ξερω αμα εχω καταλαβει και σωστα τι εννοεις.....
migf1 Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 ... Το ίδιο ισχύει και με την άσκηση που λέμε. Έχουμε ένα δισδιάστατο πίνακα με 2 στήλες και 3 γραμμές οπότε στη μνήμη θα έχουμε 6 συνεχόμενους int οπότε πρακτικά είναι το ίδιο με ένα μονοδιάστατο πίνακα με 6 int αλλά για το πρότυπο δεν είναι το ίδιο. > for (int *walk = (int *)arr2d; walk < ((int *)arr2d + nrows * NCOLS); walk++) Εδώ μεταχειρίζεσαι τον arr2d σαν να ήταν μονοδιάστατος πίνακας με 6 στοιχεία που δεν είναι σωστό. Για να προσπελάσεις τον πίνακα πρέπει να το κάνεις είτε με το σωστό δισδιάστατο τύπο ή με char (ή με union σε c99 και πέρα). ... Με μπέρδεψες! Θα το κοιτάξω με ησυχία αργότερα, μήπως εννοείς κάτι άλλο που δεν το 'πιασα, αλλά στον κώδικά μου η συνθήκη συγκρίνει διευθύνσεις στοιχείων του πίνακα, οπότε αποκλείεται να μπερδέψει το 1 με το τελευταίο+1 στοιχείο. ... Ρε συ migf1 για ποιο λογο κάνεις cast σε δεικτη τον arr2d ? Δηλαδη σε τι χρησιμευει αυτο ακριβως... αφου και παλι δεν μπορεις να δωσεις arr2d++; ... Ο walk είναι διεύθυνση ενός στοιχείου του πίνακα (τα πιάνει με τη σειρά, ένα-ένα). Εξού και το cast, εξού και το μετέπειτα walk++. Ξεκινάει με την διεύθυνση του 1ου στοιχείου του πίνακα arr2d[][] και "περπατάει" μέχρι και τη διεύθυνση του τελευταίου στοιχείου. Μόλις γίνει ίδιος με την διεύθυνση του 7ου στοιχείου (που είναι out of bounds) διακόπτεται το loop. (πολυ-ταξιδευμένο)EDIT: Έχει το χαρακτηριστικό πως δεν ασχολείται ούτε με counters ούτε με sizeof() στους υπολογισμούς του. Θέλω όμως να κοιτάξω (πιο μετά όμως) αυτό που γράφει ο imitheos, μπορεί να μην έχω καταλάβει τι ακριβώς εννοεί και να έχει δίκιο.
imitheos Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 ΗΜιθεε αρα ο δικος μου τρόπος με τον δισδιάστατο πίνακα και παιζει παντου και ειναι σωστος συμφωνα με τα ακαδημαικα - εγκυκλοπαιδικα προτυπα!!!!!! Όχι > for( p = &arr2d[0][0] ; p <= &arr2d[1][2]; p++) sum+= *p; Αυτό δεν έγραψες ? Εδώ διατρέχεις τον πίνακα σαν μονοδιάστατο όπως ο migf1 απλά εκείνος το κάνει πιο όμορφα και πιο γενικά με NCOLS αντί για κατευθείαν τα νούμερα. υ.γ2 Παντως ο King έχει παράδειγμα κανονικοτατο στο οποιο περνάει τον δισδιάστατο σαν μονοδιάστατο σε μια συναρτηση που έχει δηλωθει να περιμενει μονοδιαστατο και κανει στο ετσι την εργασια. Τέλος Σελ. 268 - 269 Το ξαναείπαμε σε προηγούμενο μήνυμα ότι ο King ορίζει την μεταβλητή ως "δείκτη σε πίνακα".
migf1 Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 που πήγε η εντολή διαγραφής ενός ποστ μας; το πήγα στη θέση του το edit
Star_Light Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 Ημιθεε δωσε μια δικια σου εκδοχη που διατρέχει τον πινακα σαν δισδιαστατο . Μηπως εννοεις οτι θα γινει με ενθετο loop?
imitheos Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 Μάλλον δεν το εξηγώ καλά για να έχουν χρειαστεί τόσα μηνύματα. Για θεωρητικό θέμα δεν περίμενα τόσα μηνύματα αλλά αφού δεν έχει κίνηση το νήμα δεν πειράζει Ξεκινάει με την διεύθυνση του 1ου στοιχείου του πίνακα arr2d[][] και "περπατάει" μέχρι και τη διεύθυνση του τελευταίου στοιχείου. Μόλις γίνει ίδιος με την διεύθυνση του 7ου στοιχείου (που είναι out of bounds) διακόπτεται το loop. Θέλω όμως να κοιτάξω (πιο μετά όμως) αυτό που γράφει ο imitheos, μπορεί να μην έχω καταλάβει τι ακριβώς εννοεί και να έχει δίκιο. Ημιθεε δωσε μια δικια σου εκδοχη που διατρέχει τον πινακα σαν δισδιαστατο . Μηπως εννοεις οτι θα γινει με ενθετο loop? > for (i = 0; i < NUM_ROWS; i++) for (j = 0; j < NUM_COLS; j++) a[i][j] = 5; Το κλασικό διπλό loop. Αν τρέξουμε με το μυαλό μας τον κώδικα βλέπουμε ότι θα προσπελάσει τα στοιχεία a[0][0], a[0][1], a[0][2], a[1][0], κτλ δηλαδή όπως είναι δηλωμένος ο πίνακας. Οι κώδικες που γράψαμε πραγματοποιούν κάτι άλλο το οποίο περιέγραψε ο migf1 στο σημείο που έκανα bold. Διατρέχουν σειριακά μια σειρά από στοιχεία σαν να ήταν ο πίνακας μονοδιάστατος. Αν δεν το εξηγώ καλά, ας δούμε το cast "(int *)arr2d" που έχει ο migf1 το οποίο δείχνει ξεκάθαρα αυτό που λέω. **** Όποιος διαβάζει το νήμα, ο nik234 ρώτησε κάτι για το eclipse ****
Star_Light Δημοσ. 7 Νοεμβρίου 2012 Δημοσ. 7 Νοεμβρίου 2012 @Ημιθεε αυτο φανταστηκα και σου ειπα και εγω... το κλασσικο διπλο loop. Αλλα το θεμα ειναι αν μπορουμε αντι για δεικτες στοιχειων των διατάξεων να παιξουμε με αριθμητικη δεικτων σε αυτο το εμφωλιασμενο loop που δινεις. Μιας και θελουμε να ειμαστε 100% σωστοι αν και εφοσον δουλευει με ολες τις πλατφορμες γιατι να κατσεις να παιδευεις το μυαλο σου τοσο πολυ..... χειριζεσαι τον δισδιαστατο σαν μονοδιαστατο και τελειωνει εκει ή ακομη καλυτερα παιζεις χωρις δεικτες και επισης τελειωνει εκει μιας και δεν ειναι σιγουρο οτι κερδιζεις κατι σε ταχυτητα ή και σε κατι αλλο.
migf1 Δημοσ. 8 Νοεμβρίου 2012 Δημοσ. 8 Νοεμβρίου 2012 (επεξεργασμένο) Καλημέρα, κοίταξα πριν λίγο αυτό που συζητούσαμε χτες (και είχα υποσχεθεί να το κοιτάξω πιο προσεκτικά). Δηλαδή αυτό που έχω σε παράθεση ... ... Δεν έχει σχέση με αυτό που λέμε όμως. Δες αυτό που είπα πριν. Έχεις ένα πίνακα int a[3][3]. Η έκφραση a[1][0] ισοδυναμεί με a + 1*3 + 0 και η έκφραση a[0][3] ισοδυναμεί με a + 0*3 + 3 δηλαδή δείχνουν στην ίδια διεύθυνση. Παρόλα αυτά η έκφραση a[0][3] δεν είναι σωστή σύμφωνα με το πρότυπο. Αν όμως ελέγχαμε το &a[1][0] και το &a[0][3] τότε αυτό θα ήταν σωστό για το λόγο που ανέφερες και οι δύο δείκτες θα ήταν ίσοι. Το ίδιο ισχύει και με την άσκηση που λέμε. Έχουμε ένα δισδιάστατο πίνακα με 2 στήλες και 3 γραμμές οπότε στη μνήμη θα έχουμε 6 συνεχόμενους int οπότε πρακτικά είναι το ίδιο με ένα μονοδιάστατο πίνακα με 6 int αλλά για το πρότυπο δεν είναι το ίδιο. > for (int *walk = (int *)arr2d; walk < ((int *)arr2d + nrows * NCOLS); walk++) Εδώ μεταχειρίζεσαι τον arr2d σαν να ήταν μονοδιάστατος πίνακας με 6 στοιχεία που δεν είναι σωστό. Για να προσπελάσεις τον πίνακα πρέπει να το κάνεις είτε με το σωστό δισδιάστατο τύπο ή με char (ή με union σε c99 και πέρα). Όλα αυτά εγκυκλοπαιδικά - ακαδημαϊκά πάντα. Πρακτικά παίζει παντού. Όσο και να το "παίδεψα" δεν βρήκα να υπάρχει κάποιο πρόβλημα με το να περπατάς με (non-char *) pointer-arithmetic τις διευθύνσεις ενός 2Δ πίνακα σαν να ήταν 1Δ. Η γλώσσα εγγυάται πως τα στοιχεία των πολυδιάστατων στατικών πινάκων διατάσσονται μονοδιάστατα ΚΑΙ συνεχόμενα στη μνήμη. Οπότε γιατί να υπάρχει πρόβλημα; Η παρατήρηση ότι: &arr2d[1][0] == &arr2d[0][NCOLS] προφανώς ισχύει, αλλά δεν βλέπω πως μπορεί να αφορά τους κώδικες που συζητάμε. Και οι 2 παραπάνω εκφράσεις απεικονίζουν το 1ο στοιχείο της 1ης γραμμής του 2Δ πίνακα. Έγραψα τον παρακάτω πρόχειρο κώδικα, προσπαθώντας να καλύψω όσο το δυνατόν περισσότερους εναλλακτικούς τρόπους με τους οποίους μπορούμε να διατρέξουμε έναν 2Δ πίνακα, συγκριτικά με το (char *) που έχεις ήδη δώσει με κώδικα σε προηγούμενο ποστ, αλλά εξακολουθώ να μην βλέπω κάποιο μειονέκτημα έναντι του (char *). Παρακαλώ διορθώστε/συμπληρώστε αν βλέπετε κάτι που μου διαφεύγει. > #include <stdio.h> #include <stdlib.h> #define NROWS 2 #define NCOLS 3 int main( void ) { int arr2d[NROWS][NCOLS] = { {10, 20, 30}, {40, 50, 60} }; int *walk = (int *)arr2d; // address of 1st int element int *last_plus_1 = ((int *)arr2d + NROWS * NCOLS); // address of (last+1) int element printf( "arr2d[NROWS][NCOLS] == arr2d[%d][%d]\n\n", NROWS, NCOLS ); // print arr2d elems along with their memory-address, using an (int *) walking pointer to their addresses puts( "*** walking as 1D (manually calculated 2D indices) ***" ); for (; walk < last_plus_1; walk++ ) { printf( "%2d @%p ([%d][%d])\n", *walk, walk, (walk - (int *)arr2d) / NCOLS, (walk - (int *)arr2d) % NCOLS ); } // print the address of the last+1 element printf( "-- @%p ([%d][%d])\n", walk, (walk - (int *)arr2d) / NCOLS, (walk - (int *)arr2d) % NCOLS ); puts("\n"); // print arr2d elements along with their memory-address, using [][] notation puts( "*** walking as 2D (manually calculated address) ***" ); for (int i=0; i < NROWS; i++ ) { for (int j=0; j < NCOLS; j++) { printf( "[%d][%d]: %2d @%p (@%08x)\n", i, j, arr2d[i][j], &arr2d[i][j], (size_t)arr2d + (i*NCOLS + j) * sizeof(int) ); } } // print the address of the last+1 element printf( "[%d][%d]: -- @%p (@%08x) ", NROWS-1, NCOLS, &arr2d[NROWS-1][NCOLS], (size_t)arr2d + ((NROWS-1)*NCOLS + NCOLS) * sizeof(int) ); printf( "%s", "OR " ); printf( "[%d][0]: -- @%p (@%08x)\n", NROWS, &arr2d[NROWS][0], (size_t)arr2d + ((NROWS)*NCOLS + 0) * sizeof(int) ); puts("\n"); system( "pause" ); exit(0); } Έξοδος: > arr2d[NROWS][NCOLS] == arr2d[2][3] *** walking as 1D (manually calculated 2D indices) *** 10 @0028fee4 ([0][0]) 20 @0028fee8 ([0][1]) 30 @0028feec ([0][2]) 40 @0028fef0 ([1][0]) 50 @0028fef4 ([1][1]) 60 @0028fef8 ([1][2]) -- @0028fefc ([2][0]) *** walking as 2D (manually calculated address) *** [0][0]: 10 @0028fee4 (@0028fee4) [0][1]: 20 @0028fee8 (@0028fee8) [0][2]: 30 @0028feec (@0028feec) [1][0]: 40 @0028fef0 (@0028fef0) [1][1]: 50 @0028fef4 (@0028fef4) [1][2]: 60 @0028fef8 (@0028fef8) [1][3]: -- @0028fefc (@0028fefc) OR [2][0]: -- @0028fefc (@0028fefc) Πιέστε ένα πλήκτρο για συνέχεια. . . EDIT: Αλλαγή ονόματος του walking-pointer από first σε walk. Επεξ/σία 8 Νοεμβρίου 2012 από migf1
imitheos Δημοσ. 8 Νοεμβρίου 2012 Δημοσ. 8 Νοεμβρίου 2012 Όσο και να το "παίδεψα" δεν βρήκα να υπάρχει κάποιο πρόβλημα με το να περπατάς με (non-char *) pointer-arithmetic τις διευθύνσεις ενός 2Δ πίνακα σαν να ήταν 1Δ. Η γλώσσα εγγυάται πως τα στοιχεία των πολυδιάστατων στατικών πινάκων διατάσσονται μονοδιάστατα ΚΑΙ συνεχόμενα στη μνήμη. Οπότε γιατί να υπάρχει πρόβλημα; Η παρατήρηση ότι: &arr2d[1][0] == &arr2d[0][NCOLS] προφανώς ισχύει, αλλά δεν βλέπω πως μπορεί να αφορά τους κώδικες που συζητάμε. Και οι 2 παραπάνω εκφράσεις απεικονίζουν το 1ο στοιχείο της 1ης γραμμής του 2Δ πίνακα. Εσύ ανέφερες το να εξετάζεις ένα στοιχείο πέρα από το όριο του πίνακα για αυτό το είπα. Πρόσεξε όμως ότι αυτό μπορεί να γίνει _μόνο_ για τη διεύθυνση του ένα-πέρα-από-το-όριο στοιχείου. _Δεν_ μπορείς να προσπελάσεις την τιμή του. Το arr2d[0][NCOLS]=5 είναι λάθος. Συμφωνείς σε αυτό ? Έγραψα τον παρακάτω πρόχειρο κώδικα, προσπαθώντας να καλύψω όσο το δυνατόν περισσότερους εναλλακτικούς τρόπους με τους οποίους μπορούμε να διατρέξουμε έναν 2Δ πίνακα, συγκριτικά με το (char *) που έχεις ήδη δώσει με κώδικα σε προηγούμενο ποστ, αλλά εξακολουθώ να μην βλέπω κάποιο μειονέκτημα έναντι του (char *). Ο κώδικας δεν λέει κάτι γιατί έχουμε πει πως σε όλους τους compilers θα παίξει σωστά. Αυτοί που γράφουν τον compiler δεν είναι βλαμμένοι οπότε εννοείται πως θα το κάνουν να παίζει σωστά. Θεωρητικά όμως _δεν_ είναι σωστό άσχετα που τα στοιχεία όντως διατάσσονται συνεχόμενα στη μνήμη. 7 An object shall have its stored value accessed only by an lvalue exp<b></b>ression that has one of the following types:76) — a type compatible with the effective type of the object, blah blah — an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or — a character type. Οι τύποι int* (μονοδιάστατος) και int (*)[] (δισδιάστατος) δεν είναι συμβατοί οπότε θεωρητικά δεν είναι σωστό. Το ότι είναι ισοδύναμοι δεν παίζει κανένα ρόλο. > struct a { int k; }; struct b { int k; }; Δες το παραπάνω παράδειγμα. Οι δύο δομές _δεν_ έχουν συμβατό τύπο σύμφωνα με το πρότυπο άσχετα αν είναι ολόιδιες. Να πω για 6η-7η φορά γιατί μάλλον δεν γίνομαι κατανοητός ότι πρακτικά θα παίξει παντού αλλά μιλάμε θεωρητικά.
migf1 Δημοσ. 8 Νοεμβρίου 2012 Δημοσ. 8 Νοεμβρίου 2012 Ναι βρε συ, προφανώς μιλάμε θεωρητικά. Επίσης, προφανώς συμφωνούμε πως μονάχα μπορούμε να εξετάσουμε το &arr[last+1] ως διεύθυνση και όχι ως περιεχόμενο διεύθυνσης. Την ακαταλληλότητα των (non-char *) pointers έχω δυσκολία να κατανοήσω. Το απόσπασμα του προτύπου που παραθέτεις (thanks) δεν το βρίσκω αντιφατικό με την πρακτική των (non-char *). Διότι αν είναι αντιφατικό, τότε θα σήμαινε πως καταργεί την έννοια του casting από τη γλώσσα. Έτσι δεν είναι; Δηλαδή, με άλλα λόγια, οι δομές... > struct_a struct_b δεν έχουν συμβατό τύπο, αλλά οι δομές... > struct_a (struct_a) struct_b έχουν. Έχω παρερμηνεύσει κάτι;
nik324 Δημοσ. 8 Νοεμβρίου 2012 Δημοσ. 8 Νοεμβρίου 2012 Eρωτηση Εχουμε μια συναρτηση Delete(NODE **list, NODE *del) Και κανοντας προσπελαση στη λιστα list, αν βρουμε καποιες μη εγκυρες τιμες να κανουμε διαγραφη του κομβου και να συνεχισουμε την προσπελαση Kανω λοιπον το εξης > struct list{ list *next; list *prev; int data; }list; //η λιστα εχει μεσα στοιχεια..οποτε ξεκιναμε την προσπελαση dummy =list; while(dummy){ if(list->data = 0){ Delete( &list , dummy ) } dummy=dummy->next;; } Kατι δν παει καλα ομως με το παραπανω
migf1 Δημοσ. 8 Νοεμβρίου 2012 Δημοσ. 8 Νοεμβρίου 2012 Έχεις = αντί για == μήπως; Αν ναι, τότε αν το είχες εξαρχής γραμμένο ως... > if (0 = list->data) { ... θα στο είχε πιάσει ο compiler.
Προτεινόμενες αναρτήσεις