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

Ερωτήσεις για C


capoelo

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

...

 Το casting αυτό είναι λάθος. Το έχει εξηγήσει το λινκ που έδωσα παραπάνω για ποιό λόγο. Αν δούλεψε, που αμφιβάλλω, ήταν εντελώς συγκυριακό.

 

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

 

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

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • Απαντ. 1,6k
  • Δημ.
  • Τελ. απάντηση

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

Δοκίμασα εδώ http://liveworkspace.org/ χρησιμοποιώντας τον τελευταίο gcc και δε δούλεψε, δεν εμφανίζει τίποτα οπότε μάλλον είναι run-time error. Επειδή είμαι στη δουλειά και δεν έχω πρόσβαση σε μηχάνημα με C compiler θα το δοκιμάσω όταν γυρίσω σπίτι.

 

http://liveworkspace.org/code/3rMmDj$3 ο test κώδικας που έγραψα.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Στο link που δίνεις δουλεύει μια χαρά με gcc 4.6.x και 4.7.x (όχι με g++) ... με c-lang και intel σε εκείνο το link δεν δουλεύει. Όταν τον είχα γράψει τον είχα δοκιμάσει σε gcc 4.7, lcc-win32 (δεν θυμάμαι version), Pelles C 7 & 6.50RC4 και σε μια παλιότερη έκδοση (δεν θυμάμαι ποια) σε Ubuntu 11.10.

 

http://liveworkspace.org/code/3eZjO6$0

 

ΥΓ. Βγάλε και το -O2.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλά τυφλός είμαι? Με gcc δεν εμφανίζει τίποτα ο κώδικας που παράθεσα. :P

 

O κώδικας που παρέθεσες εκ πρώτης όψεως φαίνεται σωστός αλλά δε δουλεύει με δυναμικά δεσμευμένους δυσδιάστατους πίνακες. Κανείς δε σου εγγυάται ότι τα rows που θα δεσμεύσεις βρίσκονται σε συνεχόμενες θέσεις μνήμης.

 

Εν κατακλείδι, έστω το ότι δε δουλεύει σε ορισμένους compilers σημαίνει undefined behaviour.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Το είχαμε ξανασυζητήσει το θέμα 2d <-> 1d. Το να ξεκινάς από την αρχή του 2d και να αυξάνεις κατά 1 int σαν να ήταν 1d πίνακας πρακτικά θα παίξει σε όλους τους compilers αλλά θεωρητικά σύμφωνα με το πρότυπο είναι λάθος γιατί προσπελαύνεις ένα τύπο με "μη-συμβατό" τύπο.

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

http://cboard.cprogramming.com/c-programming/153336-pointers-arrays.html

 

δικη μου αποψη ειναι οτι πρεπει εξαρχης αν μαθαινει καποιος να του ξεκαθαρισεις για να μην εχει μετα μπερδεματα οτι οι διπλοι δεικτες δεν έχουν σε τιποτα να κανουν με τους δισδιαστατους πινακες..... δεν εχει να κανει ουτε με θεμα ισοτητας ουτε με θεμα ισοδυναμιας. Η διαφορα εγκειται στους τυπους. Ενας δισδιαστατος ειναι τυπου δεικτης σε πινακα... ενω ενας μονοδιαστατος ειναι δεικτης σε απλο στοιχειο (1ο).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλά τυφλός είμαι? Με gcc δεν εμφανίζει τίποτα ο κώδικας που παράθεσα. :P

 

Sorry, εννοούσα τον δικό μου κώδικα (όχι τον δικό σου). Ο οποίος τελικά παίζει σωστά με όλους τους C compilers που περιέχει το link που παρέθεσες, και με όλους όσους τον έχω δοκιμάσει στο PC (Win32 και Ubuntu).

 

O κώδικας που παρέθεσες εκ πρώτης όψεως φαίνεται σωστός αλλά δε δουλεύει με δυναμικά δεσμευμένους δυσδιάστατους πίνακες. Κανείς δε σου εγγυάται ότι τα rows που θα δεσμεύσεις βρίσκονται σε συνεχόμενες θέσεις μνήμης.

 

Αν τον δεσμεύσεις μονοκόμματα ως Ν*Μ τότε στο εγγυάται το πρότυπο. Κατόπιν τον διαχειρίζεσαι με pointer arithmetic, ακριβώς όπως το κάνει εσωτερικά και ο compiler όταν τον δηλώνεις και τον διαχειρίζεσαι με [] notation (εσύ έμπλεξες στην ίδια συνάρτηση το [ ] notation με το pointer declaration, για αυτό δεν σου τρέχει με 2Δ... με το [ ] notation χάνεις το lvalue capability).

 

Εν κατακλείδι, έστω το ότι δε δουλεύει σε ορισμένους compilers σημαίνει undefined behaviour.

 

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

 

Αυτά καταρρίπτουν και την βεβαιότητα που εκφράζει ο imitheos για το char *, θέμα που είχαμε συζητήσει ξανά πέριξ εκείνου του ποστ, με τα ίδια ακριβώς επιχειρήματα. Μεταξύ άλλων, έχω παραθέσει και άλλα links που χρησιμοποιούν την ίδια ακριβώς τεχνική για να προσπελάσουν 2Δ πίνακα, σε speed critical εφαρμογές... είναι κοινός τόπος σε αυτές τις περιπτώσεις.

 

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

 

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

ΥΓ. Νομίζω είναι πλέον προφανές πως το συγκεκριμένο cast δεν έχει γίνει στην τύχη.

http://cboard.cprogramming.com/c-programming/153336-pointers-arrays.html

 

δικη μου αποψη ειναι οτι πρεπει εξαρχης αν μαθαινει καποιος να του ξεκαθαρισεις για να μην εχει μετα μπερδεματα οτι οι διπλοι δεικτες δεν έχουν σε τιποτα να κανουν με τους δισδιαστατους πινακες..... δεν εχει να κανει ουτε με θεμα ισοτητας ουτε με θεμα ισοδυναμιας. Η διαφορα εγκειται στους τυπους. Ενας δισδιαστατος ειναι τυπου δεικτης σε πινακα... ενω ενας μονοδιαστατος ειναι δεικτης σε απλο στοιχειο (1ο).

 

Οπότε η δυνατότητα που παρέχει για casting η γλώσσα δεν έχει λόγο ύπαρξης κατά την άποψή σου;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

μιγφ1 δεν ξερω δεν εκατσα να το ψαξω περαιτερω ... εμαθα 2-3 πραγματα και προχωρησα το σημαντικοτερο απο εκεινα που εμαθα ομως ηταν οτι ειναι σφαλμα να θεωρουμε εναν διπλο δεικτη ισοδυναμο με εναν δισδιαστατο πινακα. Αν πας να κανεις μαθημα σε κάποιον ή προσληφθεις σε μια εταιρεια δεν θα σου πει κατσε ψιρισε μου τι λεει το προτυπο θα σου δωσει ενα προτζεκτ να το βγαλεις οσο πιο καλα μπορεις.

 

p.s Παρεθεσα και εγω ενα λινκ αν το ειδες πιο πανω....στο οποιο ξεκαθαρα αλλοι προγραμματιστες εξηγουν οτι δεν πρεπει να υπαρχει καμια υπονοια ταυτισης αυτων των δυο.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

μιγφ1 δεν ξερω δεν εκατσα να το ψαξω περαιτερω ... εμαθα 2-3 πραγματα και προχωρησα το σημαντικοτερο απο εκεινα που εμαθα ομως ηταν οτι ειναι σφαλμα να θεωρουμε εναν διπλο δεικτη ισοδυναμο με εναν δισδιαστατο πινακα. Αν πας να κανεις μαθημα σε κάποιον ή προσληφθεις σε μια εταιρεια δεν θα σου πει κατσε ψιρισε μου τι λεει το προτυπο θα σου δωσει ενα προτζεκτ να το βγαλεις οσο πιο καλα μπορεις.

p.s Παρεθεσα και εγω ενα λινκ αν το ειδες πιο πανω....στο οποιο ξεκαθαρα αλλοι προγραμματιστες εξηγουν οτι δεν πρεπει να υπαρχει καμια υπονοια ταυτισης αυτων των δυο.

 

Η ευχέρεια να χρησιμοποιείς σωστά το casting προς όφελός σου είναι σημαντική δεξιότητα στο C programming, και πιο συγκεκριμένα στο advanced C programming. Οπότε εξαρτάται από το σε ποια εταιρεία απευθύνεσαι και για τι είδους C programming job κάνεις apply.

 

Παρεμπιπτόντως, επαναλαμβάνω πως, ο 2Δ πίνακας είναι κατά περιπτώσεις ισοδύναμος με **. Είναι στην διακριτική σου ευχέρεια να μάθεις που, πότε και γιατί ώστε να το εκμεταλλεύεσαι προς όφελός σου αν και όταν χρειάζεται και άρα να αποκτήσεις συγκριτικό πλεονέκτημα έναντι του ανταγωνισμού σου όταν καλείσαι "να βγάλεις το πρότζεκτ που σου ανέθεσε η εταιρεία σου όσο πιο καλά μπορείς".

 

PS. Έδωσα κι εγώ μερικά links, με σημαντικότερο ανάμεσά τους εκείνο του προτύπου. Αμέσως μετά σε προτεραιότητα, εκείνο που κάνει ολοκληρωμένο και εμπεριστατωμένο benchmarking διάφορων τεχνικών με διάφορους compilers.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Να ρωτησω κατι αλλο... έστω οτι έχουμε τον ορισμο  και την κλήση :

 

 

#define MAX(x,y) ( (x) > (y) ? (x) : (y))
 
n = MAX( i , MAX(j,k) )

 

Έκατσα να το υπολογισω στο χαρτι να δω ποσες παρενθεσεις θέλει ... οι κανονες λένε οτι βαζεις παρενθεσεις αν η λιστα αντικαταστασης εχει εναν τελεστη και γυρω απο καθε παραμετρο στην λιστα αντικαταστασης οποτε θα έχουμε :

 

Αρχικά έχουμε 2 παράμετρους τις i και MAX(i , j) που ειναι ταυτοχρονα και αλλη μια εμφωλιασμενη κληση οποτε

 

n = ( (i) > (MAX(j,k)) ? (i) : MAX(j,k) )  η λιστα εχει ηδη απο πριν(κατα τον ορισμο της δηλαδη) ενα ζευγαρι παρενθεσεων και βαζουμε και ενα γυρω απο καθε παραμετρο.

 

στη συνέχεια :

 

n = ( (i) > ( ( (j) > (k) ? (j) : (k) ) ) ? (i) : ( ( (j) > (k) ? (j) : (k) )) )

 

Οπως ηταν πριν + ενα ακομη ζευγαρακι παρενθεσεων οπου συνανταμε τον τριαδικο τελεστη μολις ομως τελειωσα παρολο που το εχω σωστο αναρωτηθηκα ποσους τελεστες θα πρέπει να θεωρουμε στο (x) > (y) ? (x) : (y) 

και αν ειναι παραπανω απο ένας τοτε πως και δεν μπαίνουν παραπανω περισσοτερες παρενθεσεις συμφωνα με τον κανονα?

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Όταν το ύφος σου είναι passive-aggressive, να περιμένεις ανάλογη απάντηση...ιδίως όταν δε ξέρεις για τι πράγμα μιλάς.

 

 Το casting αυτό είναι λάθος. Το έχει εξηγήσει το λινκ που έδωσα παραπάνω για ποιό λόγο. Αν δούλεψε, που αμφιβάλλω, ήταν εντελώς συγκυριακό.

 

Μου αρέσει που συνεχίζεις ενώ εσύ ήσουν ο πρώτος που άρχισε. 

 

Το ποιος ξέρει για τι μιλάει, ποιος καταλαβαίνει τι διαβάζει κτλ... πραγματικά έχω κουραστεί να τα σχολιάζω. 

 

Ούτε ο πρώτος είσαι ούτε και ο τελευταίος που ξαφνικά αποφάσισε να ξεκινήσει καβγάδες για να μεγαλώσει το e penis του. Ειλικρινά με κουράζεις τόσο που πραγματικά αυτό είναι το τελευταίο μήνυμα σε τέτοιου είδους συζήτηση. 

 

Μπορείς να συνεχίσεις όσο θες.

 

Τα 'παμε. 

 

Το είχαμε ξανασυζητήσει το θέμα 2d <-> 1d. Το να ξεκινάς από την αρχή του 2d και να αυξάνεις κατά 1 int σαν να ήταν 1d πίνακας πρακτικά θα παίξει σε όλους τους compilers αλλά θεωρητικά σύμφωνα με το πρότυπο είναι λάθος γιατί προσπελαύνεις ένα τύπο με "μη-συμβατό" τύπο.

 

Ακριβώς!

 

Από την άλλη όμως, σε memory critical και time critical applications, αρκετές φορές συμφέρει να έχεις δυναμικούς 2D arrays με την "ευχέρεια" των 1D και κυρίως αναφέρομαι στην δέσμευση συνεχόμενης περιοχής μνήμης.  Σωστό με τους τυπικούς όρους μπορεί να μην είναι, αλλά "παίζει" και δουλεύει. Οπότε είναι fine by me για εφαρμογές που δεν έχουν απαιτήσεις σε scalability, maintenance και reusability και κυρίως πρόκειται για install and forget applications σε εντελώς συγκεκριμένο H/W. 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

...

Οπότε είναι fine by me για εφαρμογές που δεν έχουν απαιτήσεις σε scalability, maintenance και reusability και κυρίως πρόκειται για install and forget applications σε εντελώς συγκεκριμένο H/W.

 

Βασικά το συγκεκριμένο είναι fine by all. Δεν έχει κανένα πρόβλημα ούτε με scalability ούτε με reusability ούτε με maintenance. Είναι καθαρά θέμα του να ξέρει ο προγραμματιστής που πως και γιατί χρησιμοποιεί casting.

 

Να ρωτησω κατι αλλο... έστω οτι έχουμε τον ορισμο  και την κλήση :

 

 

#define MAX(x,y) ( (x) > (y) ? (x) : (y))
 
n = MAX( i , MAX(j,k) )

 

Έκατσα να το υπολογισω στο χαρτι να δω ποσες παρενθεσεις θέλει ... οι κανονες λένε οτι βαζεις παρενθεσεις αν η λιστα αντικαταστασης εχει εναν τελεστη και γυρω απο καθε παραμετρο στην λιστα αντικαταστασης οποτε θα έχουμε :

 

Αρχικά έχουμε 2 παράμετρους τις i και MAX(i , j) που ειναι ταυτοχρονα και αλλη μια εμφωλιασμενη κληση οποτε

 

n = ( (i) > (MAX(j,k)) ? (i) : MAX(j,k) )  η λιστα εχει ηδη απο πριν(κατα τον ορισμο της δηλαδη) ενα ζευγαρι παρενθεσεων και βαζουμε και ενα γυρω απο καθε παραμετρο.

 

στη συνέχεια :

 

n = ( (i) > ( ( (j) > (k) ? (j) : (k) ) ) ? (i) : ( ( (j) > (k) ? (j) : (k) )) )

 

Οπως ηταν πριν + ενα ακομη ζευγαρακι παρενθεσεων οπου συνανταμε τον τριαδικο τελεστη μολις ομως τελειωσα παρολο που το εχω σωστο αναρωτηθηκα ποσους τελεστες θα πρέπει να θεωρουμε στο (x) > (y) ? (x) : (y) 

και αν ειναι παραπανω απο ένας τοτε πως και δεν μπαίνουν παραπανω περισσοτερες παρενθεσεις συμφωνα με τον κανονα?

 

Δεν είναι καλή ιδέα να περιπλέκεις έτσι την κλήση των macros, γιατί έχουν πολλά pitfalls. Είναι πολύ χρήσιμα όταν τα κρατάς και τα χρησιμοποιείς όσο πιο απλά μπορείς (εκτός αν δεν γίνεται αλλιώς).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δοκίμασα εδώ http://liveworkspace.org/ χρησιμοποιώντας τον τελευταίο gcc και δε δούλεψε, δεν εμφανίζει τίποτα οπότε μάλλον είναι run-time error. Επειδή είμαι στη δουλειά και δεν έχω πρόσβαση σε μηχάνημα με C compiler θα το δοκιμάσω όταν γυρίσω σπίτι.

 

http://liveworkspace.org/code/3rMmDj$3 ο test κώδικας που έγραψα.

 

Για την ιστορία, ούτε σε C++ Builder δουλεύει.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Πουθενά δεν δουλεύει, γιατί ο erevis δηλώνει το όρισμα ως ** και κατόπιν προσπαθεί να το διαχειριστεί με 2D indexing notation.

 

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

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Πουθενά δεν δουλεύει, γιατί ο erevis δηλώνει το όρισμα ως ** και κατόπιν προσπαθεί να το διαχειριστεί με 2D indexing notation.

 

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

Σωστός!

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Επισκέπτης
Αυτό το θέμα είναι πλέον κλειστό για περαιτέρω απαντήσεις.

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