baskat Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 int n; int m; cout <<"Dwse tis diastaseis twn pinakwn" << endl; cin >>n; cin>>m; if ((n>0) && (m>0)){ int pinC[n][m]; for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ pinC[i][j]=0; } } } Πως μπορω να δηλωσω δυσδιαστατο πίνακα με τιμες που μου δίνει ο χρήστης???γιατι τ εκανα ετσι και μου βγαινει λαθος.
Jim D. Ace Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 αυτο που κανεις ειναι τελειως λαθος γιατι το προγραμμα δεσμευει μνημη κατα το Compile κι ετσι δε ξερει ποση μνημη να δεσμευση για τον πινακα σου υπαρχουν δυο λυσεις στο προβλημα σου 1) θα ορισεις μονος σου τις διαστασεις πχ int pin[10][10]; και απλα θα πεις στον χρηστη οτι μπορει να δηλωσει μεχρι 10,10 πινακα 2)θα κανεις δυναμικη δεσμευση μνημης με χρηση της new κτλ για το δευτερο θα πρεπει να εχεις κανει για pointer κτλ οποτε αν δε το εχετε πει ακομη κανε το πρωτο
baskat Δημοσ. 13 Μαΐου 2013 Μέλος Δημοσ. 13 Μαΐου 2013 αυτο που κανεις ειναι τελειως λαθος γιατι το προγραμμα δεσμευει μνημη κατα το Compile κι ετσι δε ξερει ποση μνημη να δεσμευση για τον πινακα σου υπαρχουν δυο λυσεις στο προβλημα σου 1) θα ορισεις μονος σου τις διαστασεις πχ int pin[10][10]; και απλα θα πεις στον χρηστη οτι μπορει να δηλωσει μεχρι 10,10 πινακα 2)θα κανεις δυναμικη δεσμευση μνημης με χρηση της new κτλ για το δευτερο θα πρεπει να εχεις κανει για pointer κτλ οποτε αν δε το εχετε πει ακομη κανε το πρωτο πως θα πηγαινει με Pointer?μπορεις ν α μου κανεις ενα παραδειγμα?
migf1 Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 Ή θα τον ορίσεις ως 1Δ πίνακα και θα τον διαχειρίζεσαι ως 2Δ... #include <iostream> #include <cstdlib> using namespace std; /* ----------------------------------- * Enrty point of the program */ int main() { int n = 0, m = 0; int *arr = NULL; cout << "Dwse tis diastaseis twn pinakwn" << endl; cin >> n; cin >> m; if ( n < 1 || m < 1 ) cout << "*** invalid n or m" << endl; arr = (int *) calloc( n * m, sizeof(int) ); if ( NULL == arr ) { cout << "*** possible memory usage, bye..." << endl; return 1; } for (int i = 0; i < n * m; i++) { cout << "arr[" << i / m << "][" << i % m << "]: " << arr[i] << endl; } free( arr ); system( "pause" ); /* Windows only */ return 0; } Έξοδος: Dwse tis diastaseis twn pinakwn 3 3 arr[0][0]: 0 arr[0][1]: 0 arr[0][2]: 0 arr[1][0]: 0 arr[1][1]: 0 arr[1][2]: 0 arr[2][0]: 0 arr[2][1]: 0 arr[2][2]: 0 Press any key to continue . . . ΥΓ. Συγγνώμη, αλλά αν δεν ξέρεις να δεσμεύεις δυναμικά πίνακες μέσω δεικτών, τότε τι κάθισα και σου έγραψα κώδικα για τις διασυνδεδεμένες λίστες που ζήταγες βοήθεια στο άλλο νήμα; 1
Jim D. Ace Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 @migf1 αφου ειναι στη C++ γιατι να χρησιμοποιησει malloc/calloc κτλ ειναι πιο ασφαλες και καλυτερο με τη χρηση του new @baskat ο κωδικας θα ειναι ετσι για τη δημιουργια πινακα int **pin= new int*[megethosY]; for (int i=0;i<megethosY; ++i){ pin[i]=new int[megethosX]; } και για να ελευθερωσεις τη μνημη μετα for(int i = 0; i < megethosY; ++i) { delete [] pin[i]; } delete [] pin; υγ για να κανεις χρηση του new θα πρεπι να κανεις #include<new>
migf1 Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 @migf1 αφου ειναι στη C++ γιατι να χρησιμοποιησει malloc/calloc κτλ ειναι πιο ασφαλες και καλυτερο με τη χρηση του new Προφανώς κι έχεις δίκιο (απλά εμένα μου βγαίνει η C από μόνη της λόγω πολύ μεγαλύτερης εξοικείωσης). Επίσης το κολπάκι με τον 1Δ δεν θυμάμαι αν χρειάζεται στην C++ (λογικά δεν πρέπει να διαφέρει) αλλά στην C εγγυάται μονοκόμματη μνήμη. Οπότε... #include <iostream> #include <cstdlib> using namespace std; /* ----------------------------------- * Enrty point of the program */ int main() { int n = 0, m = 0; int *arr = NULL; cout << "Dwse tis diastaseis twn pinakwn: "; cin >> n; cin >> m; if ( n < 1 || m < 1 ) cout << "*** invalid n or m" << endl; arr = new int[n * m](); if ( NULL == arr ) { cout << "*** possible memory usage, bye..." << endl; return 1; } for (int i = 0; i < n * m; i++) { int row = i / m; int col = i % m; cout << "arr[" << row << "][" << col << "]: " << arr[i] << endl; } delete[] arr; system( "pause" ); /* Windows only */ return 0; } Έξοδος: Dwse tis diastaseis twn pinakwn: 3 3 arr[0][0]: 0 arr[0][1]: 0 arr[0][2]: 0 arr[1][0]: 0 arr[1][1]: 0 arr[1][2]: 0 arr[2][0]: 0 arr[2][1]: 0 arr[2][2]: 0 Press any key to continue . . . EDIT: Παρεμπιπτόντως, με () στο τέλος του new στα arrays τα αρχικοποιύμε με μηδενικές τιμές σε όλα τους τα στοιχεία.
Jim D. Ace Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 Προφανώς κι έχεις δίκιο (απλά εμένα μου βγαίνει η C από μόνη της λόγω πολύ μεγαλύτερης εξοικείωσης). Επίσης το κολπάκι με τον 1Δ δεν θυμάμαι αν χρειάζεται στην C++ (λογικά δεν πρέπει να διαφέρει) αλλά στην C εγγυάται μονοκόμματη μνήμη. δικιο εχεις νομιζω απλα εγω το εγραψα ετσι για να το καταλαβει καλυτερα οποτε baskat με τον κωδικα του migf1 εισαι οκ
migf1 Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 Αν πρόκειται για homework, τότε λογικά τον δικό σου τρόπο πρέπει να τους ζητάνε Το 1Δ το παρέθεσα περισσότερο ως ενδιαφέρουσα (και συνηθισμένη κατά περιπτώσεις) εναλλακτική.
defacer Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 (επεξεργασμένο) Εγγυάται μονοκόμματη μνήμη μεν αλλά το να κάνεις access τα στοιχεία μ' αυτό τον τρόπο δισδιάστατου πίνακα σα να ήταν μονοδιάστατος είναι UB. Και στη C: http://stackoverflow.com/questions/2832970/does-c99-guarantee-that-arrays-are-contiguous Και στη C++: http://stackoverflow.com/questions/7269099/may-i-treat-a-2d-array-as-a-contiguous-1d-array#comment8749836_7269121 Edit: Το να κάνεις allocate τον πίνακα σα μονοδιάστατο "μακρύ μαχαίρι" και access επίσης σα μονοδιάστατο (όπως κάνει ο migf1 παραπάνω) είναι μια χαρά. Δικό μου λάθος που νόμισα πως ο πίνακας γίνεται allocated σαν 2d και access σαν 1d, το οποίο όντως είναι UB και σ' αυτό το σενάριο αναφέρονται τα links που δίνω παραπάνω. Επεξ/σία 14 Μαΐου 2013 από defacer
migf1 Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 Εγγυάται μονοκόμματη μνήμη μεν αλλά το να κάνεις access τα στοιχεία μ' αυτό τον τρόπο είναι UB. Και στη C: http://stackoverflow.com/questions/2832970/does-c99-guarantee-that-arrays-are-contiguous Και στη C++: http://stackoverflow.com/questions/7269099/may-i-treat-a-2d-array-as-a-contiguous-1d-array#comment8749836_7269121 Σε ότι αφορά την C, το έχουμε ξανασυζητήσει αυτό το θέμα, κι έχω δώσει και απόσπασμα από το ίδιο το πρότυπο: http://www.insomnia.gr/topic/437533-%CE%B5%CF%81%CF%89%CF%84%CE%AE%CF%83%CE%B5%CE%B9%CF%82-%CE%B3%CE%B9%CE%B1-c/page-66?do=findComment&comment=5065039 (C11) που επιβεβαιώνει την πεποίθηση μου. Επίσης το έχω χρησιμοποιήσει απροβλημάτιστα επί μακρόν, όπως επίσης το έχουν χρησιμοποιήσει και πολλοί άλλοι. Οπότε προσωπικά I'll stick with it μέχρι νεοτέρας. Πέριξ εκείνου του ποστ που δίνω παραπάνω, υπάρχουν διάφορες απόψεις. EDIT: Διόρθωση του link.
defacer Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 Δεν υπάρχει λόγος. Αφού τη χρησιμοποιεί απροβλημάτιστα επί μακρόν νομίζω το εξαντλήσαμε. UB και βλακείες.
imitheos Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 Εγγυάται μονοκόμματη μνήμη μεν αλλά το να κάνεις access τα στοιχεία μ' αυτό τον τρόπο είναι UB. Και στη C: http://stackoverflow.com/questions/2832970/does-c99-guarantee-that-arrays-are-contiguous Και στη C++: http://stackoverflow.com/questions/7269099/may-i-treat-a-2d-array-as-a-contiguous-1d-array#comment8749836_7269121 +1 Σε ότι αφορά την C, το έχουμε ξανασυζητήσει αυτό το θέμα, κι έχω δώσει και απόσπασμα από το ίδιο το πρότυπο: http://www.insomnia.gr/topic/437533-ερωτήσεις-για-c/page-66#entry5065039 (C11) που επιβεβαιώνει την πεποίθηση μου.Όπως είχαμε πει και τότε, το συγκεκριμένο τμήμα του προτύπου που δίνεις μιλάει για άλλο πράγμα. Το συγκεκριμένο θέμα UB ή όχι UB αναλύεται σε άλλες παραγράφους και είναι όντως UB απλά είναι τέτοια περίπτωση που δεν νομίζω κανείς compiler dev ποτέ να το υλοποιήσει διαφορετικά. Δεν θα είχε κανένα νόημα και θα έβαζε και έξτρα φόρτο στους devs. Επίσης το έχω χρησιμοποιήσει απροβλημάτιστα επί μακρόν, όπως επίσης το έχουν χρησιμοποιήσει και πολλοί άλλοι. Οπότε προσωπικά I'll stick with it μέχρι νεοτέρας. Πέριξ εκείνου του ποστ που δίνω παραπάνω, υπάρχουν διάφορες απόψεις. Συμφωνώ απόλυτα ότι θα παίξει παντού, αυτό όμως δεν είναι επιχείρημα για το αν είναι UB. Και INT_MIN-1 δίνει INT_MAX όπου το έχω δοκιμάσει αλλά δεν παύει να είναι UB. Χαλαρά 5-6 σελίδες. +1 Αφενός το έχουμε ξανασυζητήσει σε άλλο νήμα και αφετέρου ο τίτλος λέει C++ οπότε εγώ σταματάω εδώ. Βέβαια δεν έπρεπε να μπω καν στο χορό αλλά με ξέρετε
migf1 Δημοσ. 13 Μαΐου 2013 Δημοσ. 13 Μαΐου 2013 Δεν υπάρχει λόγος. Αφού τη χρησιμοποιεί απροβλημάτιστα επί μακρόν νομίζω το εξαντλήσαμε. UB και βλακείες. Σαφώς και δεν υπάρχει και λόγος, άλλωστε δεν πρόκειται να γράψεις ποτέ κώδικα σε C οπότε τα λόγια του αέρα είναι πάντα τσάμπα. Btw, προφανώς το πρότυπο αυτή τη φορά δεν σε ενδιαφέρει, τις προάλλες μας το έδειχνες δίπλα στο Ευαγγέλιο @imitheos: Ακριβώς αυτό λέει το πρότυπο, το έχω κοκκινήσει κιόλας. Συνεπικουρούμενο λοιπόν και με τη δική μου εμπειρία αλλά και με την κοινή πρακτική δεκαετίες τώρα δεν βρίσκω τον λόγο να το συνεχίζουμε. Ο καθένας έχει τις απόψεις του και τις εμπειρίες του.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα