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

δεικτες σε πινακεσ στη c


alexandro_89

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

Δημοσ.

Παιδιά ειναι επειγον!!!εχω απορια πως θα δινω ενα δισδιαστατο πινακα και να αλλαζω πχ 3η γραμμη με 5η γραμμή ή πχ 4η γραμμή με 3η στήλη!!Αν κάποιος γνωρίζει πως το κάνω στη C ας βοηθήσει την κατάσταση:-) Και πρέπει να γίνει με δείκτες η όλη διαδικασία

Δημοσ.
>
   int **A;
   int *temp;

   /* Οι απαραίτητες malloc για να πάρει ο Α τη μορφή δισδιάστατου πίνακα */

   temp = A[2];
   A[2] = A[4];
   A[4] = temp;

Δημοσ.

ννναι καλά τα λεει ο Parsifal, έχω την αίσθηση (σε φάση 95% σίγουρος) πως δεν μπορείς να κάνεις manipulate τον πίνακα λες και είναι Pointer μιας και ενώ συμπεριφερεται σαν Pointer δεν είναι. παω να δώ

 

---------- Προσθήκη στις 20:58 ---------- Προηγούμενο μήνυμα στις 20:52 ----------

 

yeah καλά τα λεεί ο parsifal. θέλει malloc και όχι πίνακα.

Δημοσ.
yeah καλά τα λεεί ο parsifal. θέλει malloc και όχι πίνακα.

 

Το ότι δεσμεύεις μνήμη δυναμικά για έναν πίνακα δε σημαίνει ότι αυτός παύει να είναι πίνακας ! Πάντως όντως οι αντιμεταθέσεις δεν γίνονται σε στατικά δηλωμένο πίνακα παρά μόνο σε δυναμικό όπως υπέδειξε ο Parsifal.

Δημοσ.

επειδή το βλέπεις σαν πίνακα δεν γίνεται αύτοματα πίνακας ;ρ

 

τέσπα ξέρουμε και οι δυο τι λέμε

Δημοσ.
Το ότι δεσμεύεις μνήμη δυναμικά για έναν πίνακα δε σημαίνει ότι αυτός παύει να είναι πίνακας ! Πάντως όντως οι αντιμεταθέσεις δεν γίνονται σε στατικά δηλωμένο πίνακα παρά μόνο σε δυναμικό όπως υπέδειξε ο Parsifal.

 

Deja vu !

Δημοσ.

Μια που μιλάμε για πίνακες με pointers

 

>int fun(int k) {
   static int z;
   if(!k) z=k;
   z++;
   z%=4;
   return z;
}

void main() {
   int i,n;
   char *p;
   for(i=0;i<4;i++) {
      p="ABCDE";
      n=fun(i) ;
      p[n]='X';
      printf("%d %s\n",n,p);
   }
}

Δόθηκε το παραπάνω σε εξετάσεις και ρωτούσε τι θα τυπώνει. Το πρόγραμμα crashάρει και λογικό απ'τη στιγμή που δεν κάνει δυναμική κατανομή. Θα ήθελα να ρωτήσω όμως στην έκφραση p="ABCDE", to "ABCDE" λογικά επιστρέφει μια διεύθυνση μνήμης τύπου char. Αυτή η διεύθυνση κάθε φορά που τρέχει το loop θα είναι η ίδια, διαφορετική ή εξαρτάται απ'τον compiler;

 

Ή έχω εγώ κάποιο λάθος στο σκεπτικό μου;

Δημοσ.
Θα ήθελα να ρωτήσω όμως στην έκφραση p="ABCDE", to "ABCDE" λογικά επιστρέφει μια διεύθυνση μνήμης τύπου char.

 

Επιστρέφει const char*, για την ακρίβεια. Γι' αυτό και το πρόγραμμα «χτυπάει» όταν προσπαθείς να αλλάξεις την τιμή ενός χαρακτήρα του string.

 

 

Αυτή η διεύθυνση κάθε φορά που τρέχει το loop θα είναι η ίδια, διαφορετική ή εξαρτάται απ'τον compiler;

 

Νομίζω δεν καθορίζεται από το standard, οπότε αναγκαστικά πάει implementation-specific. Φαντάζομαι ότι για λόγους efficiency είναι πιθανό κάποιοι compilers, όχι απαραίτητα όλοι, να χειρίζονται ως ειδική περίπτωση τα string constants και να παράγουν κώδικα τέτοιο που σε κάθε rvalue εμφάνιση string constants με κοινό περιεχόμενο (π.χ. εδώ σε κάθε iteration του for loop) να μη δεσμεύεται μνήμη για διαφορετικά "ABCDE" strings αλλά να επιστρέφεται η διεύθυνση του ίδιου κάθε φορά.

 

 

 

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

>
   p[n]='X';

θα παρουσιάζει απροσδιόριστη συμπεριφορά (segmentation fault, συνήθως). Οπότε τί θα έπρεπε να υποθέσει καλή τη πίστει ένας εξεταζόμενος; Ότι το ερώτημα είναι παγίδα και να απαντήσει αναλόγως... ; :rolleyes:

Δημοσ.

κάθε φορά που τρέχει, είναι η ίδια.

Παλιότερες εκδόσεις compiler (16bit) θα επέτρεπαν στο πρόγραμμα να εκτελεστεί, διότι δεν θα υπήρχε προστασία δεδομένων εγγραφής (WRITE ACCESS DENIAL).

 

Δεν είναι θέμα δυναμικής "κατανομής" αλλά ορισμού πίνακα.

Το

>
"hjsdgf" 

είναι ένας δείκτης σε πίνακα read only,

αλλά το

>static char x[] = "sdfgrdfggf";

είναι ένας πίνακας read/write.

 

π.χ.

δοκίμασε την παρακάτω main

>
void main() {
   int i,n;
   char *p;
   for(i=0;i<4;i++) {
static char x[] = "ABCDE";
      p=x;
      n=fun(i) ;
      p[n]='X';
      printf("%d %s\n",n,p);
   }
}

 

και μετά δοκίμασε να αφαιρέσεις το static και δες τι θα συμβεί.

 

---------- Προσθήκη στις 02:38 ---------- Προηγούμενο μήνυμα στις 02:28 ----------

 

...

Νομίζω δεν καθορίζεται από το standard, οπότε αναγκαστικά πάει implementation-specific. Φαντάζομαι ότι για λόγους efficiency είναι πιθανό κάποιοι compilers, όχι απαραίτητα όλοι, να χειρίζονται ως ειδική περίπτωση τα string constants και να παράγουν κώδικα τέτοιο που σε κάθε rvalue εμφάνιση string constants με κοινό περιεχόμενο (π.χ. εδώ σε κάθε iteration του for loop) να μη δεσμεύεται μνήμη για διαφορετικά "ABCDE" strings αλλά να επιστρέφεται η διεύθυνση του ίδιου κάθε φορά.

...

 

το

>char *x = "ABCDE"; 

δεσμεύει μόνο μια φορά το "ABCDE" για την συγκεκριμένη γραμμή κώδικα (άσχετα αν είναι σε loop). Δεν βλέπω λόγο να ασχοληθεί κάποια υλοποίηση με το ανάποδο, ούτε λόγο να περαστεί στο standard. Αν υπάρχει το "ABCDE" σε πάνω απο μια γραμμή κώδικα, τότε έχει σημασία η implementation (optimization?) technique.

 

Το

>char x[] = "ABCDE";

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

Δημοσ.

Μάλιστα, ευχαριστώ για τις διαφωτιστικές σας απαντήσεις. Άρα σίγουρα είναι λάθος του καθηγητή, άσχετα αν σ'αυτόν θα έτρεχε στον borland builder που έχει του 92" version.

Δημοσ.

eh, at the end of the day για να είσαι σίγουρος κοιτάς το assembly που παράγει και βλέπεις, μαθαίνεις και τα perks του κάθε καθηγητή..

Δημοσ.

ΟΚ, ιδού η απάντηση του καθηγητή:

 

Το “ABCDE” καταχωρείται σε συνεχόμενη περιοχή της μνήμης και έχει ως τιμή την διεύθυνση αυτής της περιοχής άρα η καταχώρηση p=“ABCDE” είναι απόλυτα φυσιολογική εφόσον παίρνει τη διεύθυνση μιας δεσμευμένης περιοχής

 

...

Δημοσ.

Η απάντηση του καθηγητή σε ποιο ερώτημα ακριβώς; Σε αυτό;

Δόθηκε το παραπάνω σε εξετάσεις και ρωτούσε τι θα τυπώνει.

 

Σε αυτό;

Θα ήθελα να ρωτήσω όμως στην έκφραση p="ABCDE", to "ABCDE" λογικά επιστρέφει μια διεύθυνση μνήμης τύπου char. Αυτή η διεύθυνση κάθε φορά που τρέχει το loop θα είναι η ίδια, διαφορετική ή εξαρτάται απ'τον compiler;

 

Ή σε διαφορετικά διατυπωμένο ερώτημα; Γιατί η απάντηση φαίνεται να απαντά στο «Είναι η καταχώρηση p=“ABCDE” απόλυτα φυσιολογική ή όχι;», το οποίο δεν είναι κάτι που ρώτησες στο αρχικό μήνυμά σου.

Δημοσ.

Σ'αυτό

 

η έκφραση "ABCDE" επιστρέφει const char*, οπότε το περιεχόμενο της δεν μπορεί να αλλάξει. Οπότε το πρόγραμμα "χτυπάει" στην ανάθεση τιμής p[n] = 'X';

 

Οπότε ποια θα ήταν η σωστή απάντηση στο συγκεκριμένο θέμα;

 

Ευχαριστώ.

 

και τώρα του ξαναέστειλα λέγοντας το ίδιο πράγμα αφού στην ουσία δε μου απάντησε για το const.

Δημοσ.

Το p="ABCDE" εννοείται πως είναι φυσιολογική δήλωση.

 

Το θέμα όμως είναι ότι όπως είπε και ο bxenos η μνήμη που δεσμεύεται για το

string literal είναι σε περιοχή που δεν μπορείς να γράψεις. Τουλάχιστον ο GCC

και ο CLANG/LLVM συμπεριφέρονται σωστά σε αυτό.

 

Το να προσπαθείς να αλλάξεις κάποιο χαρακτήρα ακόμη και να επιτρέπεται

από τον compiler είναι κακή πρακτική και δεν πρέπει να γίνεται.

 

-fwritable-strings

Store string constants in the writable data segment and don't uniquize them. This is for compatibility with old programs which assume they can write into string constants.

 

Writing into string constants is a very bad idea; “constants” should be constant.

 

Δες τι λέει το εγχειρίδιο του gcc (από τον gcc 4 έχει αφαιρεθεί εντελώς

η επιλογή και απαγορεύεται η οποιαδήποτε εγγραφή)

Αρχειοθετημένο

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

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