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

c συνάρτιση και κλήση από main


taslikos

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

Δημοσ. (επεξεργασμένο)
29 λεπτά πριν, Ilias95 είπε

Έτσι μου φάνηκε από το ύφος σου, αν κατάλαβα λάθος ζητώ συγγνώμη.

Κανείς δεν είπε ότι δεν μπορείς να επιστρέψεις έναν pointer σε οποιαδήποτε virtual διεύθυνση μνήμης θες.
Και κανείς δεν είπε ότι τα δεδομένα που βρίσκονται σε αυτή τη διεύθυνση μνήμης δεν μπορείς να τα κάνεις interpret σαν array ή σαν struct ή σαν οτιδήποτε άλλο θες!

Αυτό που γράφτηκε παραπάνω είναι ότι δεν μπορείς να επιστρέψεις array από function.
Και έτσι είναι, τι να κάνουμε; Να αλλάξουμε το specification και τους compilers;


int [] foo(void); // ILLEGAL
struct bar foo(void); // LEGAL

Στην C μπορείς να επιστρέψεις από μια συνάρτηση ints, chars, pointers, structs και άλλα πράγματα.
Arrays ΔΕΝ μπορείς να επιστρέψεις.
Στην C τα arrays δεν είναι first class types!

Στην Java που είναι first class types μπορείς να γράψεις:


int [] foo(); // LEGAL

Τώρα αυτό είναι διαφορετική ερώτηση.
Αν πραγματικά δεν ξέρεις τότε googlαρε.

Το λάθος που κάνεις είναι ακριβώς στην τελευταία ερώτηση που αρνήθηκες να άπαντήσεις. 

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

Εν ολίγης, αυτό το ευφάνταστο ότι δεν μπορείς να επιστρέψεις πίνακα από function στην C, δεν είναι σωστό. 

Άρα, ούτε «προφανώς» ούτε και σωστό ήταν (τελικά) αυτό που γράφτηκε. 

Επίσης, υπάρχει array ως basic data type στην C; Εάν ναι, μπορείς να μου φέρεις μία παράθεση που να το λέει αυτό;

Γιατί εάν δεν υπάρχει ως basic data type ο array, τότε τα περί “first class” και τα  «έτσι είναι πι compilers” είναι απλά μπαρούφες ολκής. 

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

  • Απαντ. 38
  • Δημ.
  • Τελ. απάντηση

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

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

Εντάξει, είναι προφανές ότι απλά θέλεις να έχεις δίκιο.

31 λεπτά πριν, Fortistis είπε

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

Όχι. Ο μόνος λόγος που δεν μπορείς να επιστρέψεις array από function στη C είναι γιατί έτσι αποφάσισαν οι language designers. Θα μπορούσαν κάλλιστα να είχαν αποφασίσει να γίνεται. Όπως αποφάσισαν για τα structs. Γιατί structs μπορείς να επιστρέψεις. Arrays όμως όχι.
 

32 λεπτά πριν, Fortistis είπε

Εν ολίγης, αυτό το ευφάνταστο ότι δεν μπορείς να επιστρέψεις πίνακα από function στην C, δεν είναι σωστό. 

Άρα, ούτε «προφανώς» ούτε και σωστό ήταν (τελικά) αυτό που γράφτηκε. 

Δεν είναι σωστό επειδή ... το λες εσύ. Οκ...
Από περιέργεια googlαρε "C can I return array from function?" και διάβασε τις απαντήσεις για να μη νομίσεις ότι τα βγάζουμε από το μυαλό μας.

Δεν ξέρω αν το κατάλαβες αλλά αυτό που ήρθες και έγραψες σε αυτό το thread ουσιαστικά ήταν "στην C μπορείς να επιστρέψεις pointer από μια συνάρτηση".
Ευχαριστούμε δεν το ξέραμε...

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

Δημοσ. (επεξεργασμένο)
1 hour ago, Fortistis said:

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

Sorry αλλά κάποια πράγματα που λες όπως αυτό δε βγάζουν κανένα νόημα. Δεν είμαι καν σίγουρος τι προσπαθείς να πεις, αλλά αν διαφωνείς με τον Ηλία δεν έχεις δίκιο.

1 hour ago, Fortistis said:

Επίσης, υπάρχει array ως basic data type στην C; Εάν ναι, μπορείς να μου φέρεις μία παράθεση που να το λέει αυτό;

Καταρχήν δεν υπάρχει ο όρος basic data type στο πρότυπο, οπότε πρέπει να εξηγήσεις τι εννοείς γιατί διαφορετικά παίζουμε ένα παιχνίδι όπου εσύ βάζεις τους κανόνες.

Επιπλέον, νομίζω δεν υπάρχει αφιβολία ότι οι πίνακες είναι types:

Any number of derived types can be constructed from the object and function types, as follows:
— An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. The element type shall be complete whenever the array type is specified. Array types are characterized by their element type and by the number of elements in the array. An array type is said to be derived from its element type, and if its element type is T, the array type is sometimes called ‘‘array of T’’. The construction of an array type from an element type is called ‘‘array type derivation’’.

Υπενθυμίζω επίσης πως αν έχεις αντίρρηση επειδή είναι "derived" type, θα πρέπει να λάβεις υπόψη ότι εξίσου derived types είναι και οι pointers και οι structs, με τους οποίους δεν υπάρχει κανένας τέτοιος περιορισμός όσον αφορά την επιστροφή τους από συνάρτηση.

Τέλος, είναι προφανές ότι ο περιορισμός αυτός κατά το σχεδιασμό της γλώσσας προκύπτει από τη συνειδητή επιλογή του να μην είναι μέρος της ταυτότητας ενός array type το μέγεθός του. Αυτό σημαίνει πως ο compiler δε μπορεί να επιτρέψει το "assignment" (ή γενικότερα, την αντικατάσταση του memory representation από κάποια άλλη τιμή) καθώς το μέγεθος είναι απαραίτητο για να ξέρουμε ποιο είναι το memory representation, αλλά για τον compiler αυτή η πληροφορία είναι γενικά άγνωστη εφόσον δεν είναι μέρος του type system -- πρόσεξε ότι το πρότυπο παραπάνω δεν κάνει πάρα μόνο περαστική αναφορά στο μέγεθος και καθόλου στην πρώτη πρόταση που δίνει τον ορισμό.

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

 

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

23 ώρες πριν, Fortistis είπε

Εάν επιστρέψεις δείκτη σε κάτι, πώς αυτό είναι διαφορετικό από το να επιστρέφεις πίνακα, εφόσον και το array notation (στην ουσία) pointers είναι; 

Πώς λοιπόν είναι αδύνατο να επιστρέψεις array στην C;

Θέλεις να μου πείς δηλαδή ότι array και δείκτης σε array είναι το ίδιο πράγμα;

Array στην C δεν μπορεί να επιστραφεί, γιατί το array υφισταται by reference και όχι by value. Η C μπορέι να επιστρέψει μόνο by value.

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

@Ilias95

@defacer

Στην C έχεις α) `int [ ]` και β) `int * `. Το α) δεν μπορείς να το επιστρέψεις από συνάρτηση, το β) μπορείς. Μέχρι εδώ, νομίζω, συμφωνούμε όλοι. 

Λέγοντας/υποστηρίζοντας ότι "στην C δεν μπορείς να επιστρέψεις array από συνάρτηση", αυτομάτως λέτε ότι το α) και β) είναι εντελώς διαφορετικά μεταξύ τους (orthogonal). Άρα, εάν δεν ισχύει το ότι είναι orthogonal, τότε δεν ισχύει το "στην C δεν μπορείς να επιστρέψεις array από συνάρτηση". 

Εφόσον ο compiler κάνει evaluate το [ ] σε pointer (δηλαδή, ο compiler χρησιμοποιεί pointers και δεν ξεχωρίζει μεταξύ pointer και array), πώς είναι διαφορετικά το [ ] και το * ;

12 λεπτά πριν, sundance_kid είπε

Θέλεις να μου πείς δηλαδή ότι array και δείκτης σε array είναι το ίδιο πράγμα;

Array στην C δεν μπορεί να επιστραφεί, γιατί το array υφισταται by reference και όχι by value. Η C μπορέι να επιστρέψει μόνο by value.

C 101.

By reference και by value δεν υπάρχει. Είναι λεκτικό παιχνίδι. Πάντα by value είναι. Δηλαδή, ο pointer που θα χρησιμοποιήσεις ως όρισμα, θα χρησιμοποιηθεί ως by value. Δηλαδή, θα γίνει ένα copy της value του αλλά εσένα δεν σε πειράζει γιατί δεν θες να αλλάξεις αυτό το value. 

Επίσης, θα θεωρήσω ότι έκανες λάθος και δεν προσπάθησες σκόπιμα να παραποιήσεις όσα λέω. Γιατί, δεν είπα array και pointer σε array αλλά array και pointer σε κάτι από αυτά που έχει ο array, π.χ. `int [ ]` και `int * `. Αυτό, ναι, είναι το ίδιο. 

Y.Γ. Basic data types != aggregated και user specified. Νομίζω ως "primitive" θα ήταν πιο γνωστό. Δεν ξέρω εάν αναφέρεται στο πρότυπο ως basic data type. 

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

@Fortistis
Ναι, το α και το β είναι διαφορετικά μεταξύ τους.

Ο compiler "δεν κάνει evaluate το [] σε pointer" όπως λες. Αυτό που γίνεται όταν χρειάζεται σε κάποια context είναι το όνομα του array να γίνεται decayed σε έναν pointer που δείχνει στο πρώτο στοιχείο.

Γενικά επειδή αφήνεις να εννοηθεί συνέχεια ότι arrays και pointers είναι το ίδιο πράγμα, εδώ είναι μερικά παραδείγματα που μπορώ να σκεφτώ πρόχειρα:

int arr[] = {1, 2, 3}; // LEGAL
int *p = {1, 2, 3}; // ILLEGAL
int *p = arr;
p = 0xabcd;  // reassignment is LEGAL

int arr[] = {1, 2, 3};
arr = 0xabcd; // reassignment is ILLEGAL
sizeof(arr) != sizeof(p)

Bonus: το arr and το &arr ΔΕΝ είναι το ίδιο πράγμα.
Ξέρεις γιατί; Γιατί έχουν άλλο τύπο.

C 101: ARRAYS ARE NOT POINTERS

 

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

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

Καλημέρα, παιδιά !

Μια απλοϊκή λύση που πιστεύω ότι μπορεί να δοθεί στο πρόβλημα και την έγραψα τώρα λίγο βιαστικά θα μπορούσε να έχει ως εξής :

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
float max(float a[10][10]){
    int i,j;
    float m;
    m=a[0][0];
    for (i=0; i<=9; i++)
        for (j=0; j<=9; j++)
            if (a[j]>m){
                m=a[j];
    }
    
    return m; }

void main() {
float pinakas[10][10];
float megistos=0;
int evros_timwn=100;
srand(time(NULL));
int i,j=0;
for(i=0;i<=9;i++)
for(j=0;j<=9;j++) { pinakas[j]=rand() % evros_timwn+1;
                    printf("Sti thesi %d,%d vrisketai i timi %.2f\n",i,j,pinakas[j]);
                    }
megistos=max(pinakas);
printf("\n\nO pinakas gemise \n\n");
printf("\nMegistos einai o arithmos %.2f",megistos);
for(i=0;i<=9;i++)
for(j=0;j<=9;j++)
                  if(pinakas[j]==megistos) { printf("\n\nH megisth timh emfanizetai sti thesi %d,%d\n",i,j); }
                   

}

Εδώ πιστεύω ότι φαίνεται αρκετά ξεκάθαρα πώς καλείται η max μέσα απ' το κυρίως πρόγραμμα, ώστε να βρούμε τη μέγιστη τιμή μέσα σε πίνακα δύο διαστάσεων.
Κατ'  αρχήν πρέπει να θυμόμαστε ότι όταν ξεκινάμε να ορίσουμε μια συνάρτηση στη C, το πρώτο πράγμα που θα πρέπει να σκεφτούμε είναι τι είδους δεδομένα πρέπει να παρέχει αυτή η συνάρτηση στο κυρίως πρόγραμμα. Αυτό λέγεται τύπος επιστροφής και πρέπει να τον γράφουμε πάντα πριν το όνομα της ίδιας της συνάρτησης.
Ο φίλος που έθεσε το ερώτημα έχει δηλώσει λανθασμένα ως τύπο επιστροφής τη λέξη void, πράγμα που θα πει ότι η συγκεκριμένη συνάρτηση απλά θα κάνει κάποιες ενέργειες, χωρίς να επιστρέφει τίποτα στο κυρίως πρόγραμμα.
Ακόμα και στα καθημερινά Αγγλικά, άμα πει κάποιος «my life is void of interest» σημαίνει ότι η ζωή του είναι κενή ενδιαφέροντος.
Έτσι λοιπόν διόρθωσα κατά πρώτον το void σε float αφού ο πίνακας που θα εξετάσει η max είναι τέτοιου τύπου.
Μέσα στη main όρισα έναν νέο πίνακα 2 διαστάσεων και επίσης πρόσθεσα δύο ακόμα οδηγίες #include προς το μεταγλωττιστή, ώστε να μπορώ να χρησιμοποιήσω την ενσωματωμένη συνάρτηση rand της C για να παραχθούν τυχαίοι αριθμοί στο διάστημα [1,100].
Γεμίζω τον πίνακα με τους αριθμούς αυτούς κι ύστερα καλώ τη max για να τον διατρέξει και να βρει τη μέγιστη τιμή. Η τιμή που επιστρέφει η max (πάντα τύπου float) αποθηκεύεται σε εντελώς ξεχωριστή μεταβλητή (float megistos) και ύστερα τυπώνεται στην οθόνη. Επίσης βρίσκει και τις ακριβείς συντεταγμένες μέσα στον πίνακα, όπου τυχαίνει να βρίσκεται η μέγιστη τιμή.
Επειδή οι αριθμοί με τους οποίους γεμίζει ο πίνακας είναι τυχαίοι, κάθε φορά που θα τρέχει το πρόγραμμα θα βγάζει εντελώς διαφορετικά αποτελέσματα.

Ελπίζω να βοήθησα λίγο,

Σας ευχαριστώ,

Ο Άσπρος Γάτος

Συγνώμη παιδιά, δεν καταλαβαίνω τι τον έπιασε τον editor και το έβγαλε έτσι, πάντως εκεί που λέει pinakas[j] εγώ έχω γράψει pinakas σε αγκύλη του i και χωρίς κενό σε αγκύλη του j. Το ίδιο και μέσα στη max.  Ο πίνακας είναι πάντοτε δύο διαστάσεων και οι μεταβλητές βρόγχου είναι το διατεταγμένο ζεύγος i,j. Δεν καταλαβαίνω γιατί μέσα στο web interface δεν το βγάζει σωστά ενώ στο δικό μου υπολογιστή φαίνεται στην οθόνη μια χαρά και τρέχει και χωρίς πρόβλημα.

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

 

 

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

Δημοσ. (επεξεργασμένο)
4 hours ago, Fortistis said:

Λέγοντας/υποστηρίζοντας ότι "στην C δεν μπορείς να επιστρέψεις array από συνάρτηση", αυτομάτως λέτε ότι το α) και β) είναι εντελώς διαφορετικά μεταξύ τους (orthogonal). Άρα, εάν δεν ισχύει το ότι είναι orthogonal, τότε δεν ισχύει το "στην C δεν μπορείς να επιστρέψεις array από συνάρτηση". 

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

4 hours ago, Fortistis said:

Εφόσον ο compiler κάνει evaluate το [ ] σε pointer (δηλαδή, ο compiler χρησιμοποιεί pointers και δεν ξεχωρίζει μεταξύ pointer και array), πώς είναι διαφορετικά το [ ] και το * ;

Ο compiler σε καμία περίπτωση δεν κάνει αυτό που λες, και αυτό που λες είναι πολύ συνηθισμένο λάθος intermediate επιπέδου γνώσης (και εγώ κάποτε έτσι το είχα στο μυαλό μου). Arrays decay into pointers, αλλά όσον αφορά τον compiler είναι τελείως διαφορετικά μεταξύ τους πράγματα. Μπορείς να γκουγκλάρεις, πληθώρα παραδειγμάτων (πχ δε μπορείς να κάνεις assign array σε pointer, αλλά αν βάλεις ένα address-of operator στον πίνακα μπορείς -- φανερά δε θα υπήρχε κανένα πρόβλημα αν όπως λες ο compiler δεν ξεχωρίζει μεταξύ τους). Είμαι βέβαιος ότι υπάρχουν και απαντήσεις στο stackoverflow που το αναλύουν πολύ πιο όμορφα από ότι θα μπορούσα να κάνω εγώ τώρα.

4 hours ago, Fortistis said:

Basic data types != aggregated και user specified. Νομίζω ως "primitive" θα ήταν πιο γνωστό. Δεν ξέρω εάν αναφέρεται στο πρότυπο ως basic data type. 

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

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

Τι γράφει ο D. Rithcie

 

1 ώρα πριν, Ilias95 είπε

@Fortistis
Ναι, το α και το β είναι διαφορετικά μεταξύ τους.

Ο compiler "δεν κάνει evaluate το [] σε pointer" όπως λες. Αυτό που γίνεται όταν χρειάζεται σε κάποια context είναι το όνομα του array να γίνεται decayed σε έναν pointer που δείχνει στο πρώτο στοιχείο.

Γενικά επειδή αφήνεις να εννοηθεί συνέχεια ότι arrays και pointers είναι το ίδιο πράγμα, εδώ είναι μερικά παραδείγματα που μπορώ να σκεφτώ πρόχειρα:


int arr[] = {1, 2, 3}; // LEGAL
int *p = {1, 2, 3}; // ILLEGAL

int *p = arr;
p = 0xabcd;  // reassignment is LEGAL

int arr[] = {1, 2, 3};
arr = 0xabcd; // reassignment is ILLEGAL

sizeof(arr) != sizeof(p)

Bonus: το arr and το &arr ΔΕΝ είναι το ίδιο πράγμα.
Ξέρεις γιατί; Γιατί έχουν άλλο τύπο.

C 101: ARRAYS ARE NOT POINTERS

Σωστά είναι τα παραπάνω παραδείγματα. θα έφτανε μόνο το πρώτο. Το α) και το β) είναι διαφορετικά

Όντως: arrays are not pointers. Αλλά... 2 παραδείγματα ακόμη

Επειδή μπορείς να γράψεις (λόγω του γεγονότος αυτού που αναφέρεις παραπάνω και ο D. Ritchie γράφει:  The rule, which survives in today’s C, is that values of array type are converted, when they appear in expressions, into pointers to the first of the objects making up the array)

1.

είτε test(int x[]) είτε test(int* x)

 

2.

#include <stdio.h>

int* test()
{
  static int array[] = {0,1,2};  
  return array;
}

int main()
{
   int* p = test();  // ναι...., δεν μπορούμε να γράψουμε int* p = {0,1,2} ούτε  int p[] = test() ….είπαμε γιατί.
   printf("array[1] = %d ", p[1]);
   return 0;
}

Από τα παραπάνω 2 παραδείγματα θα μπορούσε άνετα να ισχυριστεί κάποιος ότι arrays & pointers στη C δε διαφέρουν, λόγω της μετατροπής που γίνεται. 

Οπότε τεχνικώς -κατά τη γνώμη μου- δεν έχει άδικο και ο @fortistis.

 

 

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

Δημοσ. (επεξεργασμένο)
43 λεπτά πριν, defacer είπε

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

Ο compiler σε καμία περίπτωση δεν κάνει αυτό που λες, και αυτό που λες είναι πολύ συνηθισμένο λάθος intermediate επιπέδου γνώσης (και εγώ κάποτε έτσι το είχα στο μυαλό μου). Arrays decay into pointers, αλλά όσον αφορά τον compiler είναι τελείως διαφορετικά μεταξύ τους πράγματα. Μπορείς να γκουγκλάρεις, πληθώρα παραδειγμάτων (πχ δε μπορείς να κάνεις assign array σε pointer, αλλά αν βάλεις ένα address-of operator στον πίνακα μπορείς -- φανερά δε θα υπήρχε κανένα πρόβλημα αν όπως λες ο compiler δεν ξεχωρίζει μεταξύ τους). Είμαι βέβαιος ότι υπάρχουν και απαντήσεις στο stackoverflow που το αναλύουν πολύ πιο όμορφα από ότι θα μπορούσα να κάνω εγώ τώρα.

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

a) Γνωρίζω τι είναι orthogonal, για αυτό το χρησιμοποίησα. Δεν βλέπω τον λόγο να προσπαθείς να μεταφράζεις έννοιες αντί να προσπαθείς να καταλάβεις τι γράφω (δεδομένου ότι θέλεις να το κάνεις μιας και απαντάς). Το δικό μου claim είναι ότι `int *` == `int [ ]`, το δεύτερο όμως είναι διαφορετικό notation (της πιάτσας ορισμός προς το παρόν). Εάν είναι το ίδιο, τότε έχετε άδικο. Εάν δεν είναι, τότε έχω εγώ. Άρα, σύμφωνα με το δικό μου claim (γιατί για αυτό γράφω εγώ), εσείς υποστηρίζεται ότι είναι orthogonal. 

β) Την διαβάθμιση της γνώσης την ορίζεις εσύ φαντάζομαι, οπότε δώσε μας τα κριτήρια για να ξέρουμε και εμείς τι μας γίνεται. Εάν όχι, τότε ένα reference στο "γνωσιόμετρο" δεν θα έβλαπτε. Από εκεί και πέρα, η διαφορά είναι ότι ο πίνακας (i.e. το a στο int[10] a) είναι unassignable/unmodifialble lvalue (δεν θυμάμαι τον όρο, φαντάζομαι ότι καταλαβαίνεις, εάν όχι, θα προσπαθήσω να δώσω τον σωστό αλλά ενημέρωσε ρώτα). Για αυτό χρειάζεται αυτό που λες με το &. 

γ) Ναι, είναι της πιάτσας. Δεν θυμάμαι τους όρους του προτύπου. Εάν τους θυμάσαι, πες μου τον σωστό. 

2 ώρες πριν, Ilias95 είπε

@Fortistis
Ναι, το α και το β είναι διαφορετικά μεταξύ τους.

Ο compiler "δεν κάνει evaluate το [] σε pointer" όπως λες. Αυτό που γίνεται όταν χρειάζεται σε κάποια context είναι το όνομα του array να γίνεται decayed σε έναν pointer που δείχνει στο πρώτο στοιχείο.

Γενικά επειδή αφήνεις να εννοηθεί συνέχεια ότι arrays και pointers είναι το ίδιο πράγμα, εδώ είναι μερικά παραδείγματα που μπορώ να σκεφτώ πρόχειρα:


int arr[] = {1, 2, 3}; // LEGAL
int *p = {1, 2, 3}; // ILLEGAL

int *p = arr;
p = 0xabcd;  // reassignment is LEGAL

int arr[] = {1, 2, 3};
arr = 0xabcd; // reassignment is ILLEGAL

sizeof(arr) != sizeof(p)

Bonus: το arr and το &arr ΔΕΝ είναι το ίδιο πράγμα.
Ξέρεις γιατί; Γιατί έχουν άλλο τύπο.

C 101: ARRAYS ARE NOT POINTERS

Tα παραδείγματα είναι λάθος. Διάβασε τι λέω παραπάνω και αυτά που γράφω στη συνέχεια. 

1) Είναι notation της γλώσσας, δεν δείχνει τίποτα. 

2) Φυσικά και είναι illegal. Εάν ήξερες ότι είναι unmodifiable lvalue ο πίνακας, δεν θα έβαζες καν αυτό το παράδειγμα. 

3) Φυσικά και έχουν διαφορετικό sizeof. Διαφορετικό notation οι συγκεκριμένες μεταβλητές. Δεν είδα όμως να κάνεις το sizeof(&arr) != sizeof(p). Είτε δεν το ήξερες, είτε δεν σου έκοψε, είτε προσπάθησες να κλέψεις. 

C101 όλα παραπάνω, μιας που αρέσει να χρησιμοποιείς ό,τι λένε οι άλλοι. 

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

Δημοσ. (επεξεργασμένο)
18 minutes ago, Fortistis said:

Το δικό μου claim είναι ότι `int *` == `int [ ]`

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

44 minutes ago, marios28 said:

The rule, which survives in today’s C, is that values of array type are converted, when they appear in expressions, into pointers to the first of the objects making up the array

Πρώτον, αυτό είναι μια απλοποίηση του κανόνα και όχι ο ίδιος ο κανόνας. Δεν συμβαίνει σε όλες τις περιπτώσεις, και ακριβώς από τις περιπτώσεις που δε συμβαίνει προκύπτουν διαφορές.

Δεύτερον, "values of array type". Όμως τα types, και το type system στο οποίο υπακούει ο compiler, νοούνται και χωρίς να υπάρξει κανένα value (πχ μπορείς να γράψεις sizeof πράγματος που δεν είναι value, και μπορείς να γράψεις compile time error μόνο λόγω types). Επομένως πέρα από την απλούστευση εδώ αφήνεις απέξω και όλο το τμήμα όπου μιλάμε για types και όχι για values. Λάβε υπόψη ότι και τα ίδια τα λόγια του fortistis που κάνω quote παραπάνω μιλάνε για ισοδυναμία types και όχι values.

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

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

Δημοσ. (επεξεργασμένο)
44 λεπτά πριν, Fortistis είπε

3) Φυσικά και έχουν διαφορετικό sizeof. Διαφορετικό notation οι συγκεκριμένες μεταβλητές. Δεν είδα όμως να κάνεις το sizeof(&arr) != sizeof(p). Είτε δεν το ήξερες, είτε δεν σου έκοψε, είτε προσπάθησες να κλέψεις. 

Έγραψες και μετά το έσβησες ότι "πάντα γίνεται decayed σε pointer". Προφανώς και δεν ισχύει αυτό. Αυτό που σου έδειξα με το sizeof είναι ακριβώς ένα παράδειγμα του πότε δεν γίνεται. Αν γινόταν τότε το sizeof(array) θα ήταν πάντα == sizeof(void *).

Το sizeof(&arr) δεν ξέρω που κολλάει πραγματικά. Εδώ ζητάς explicitly έναν pointer και τον συγκρίνεις με έναν άλλον pointer. Προφανώς και θα έχουν το ίδιο size αλλά τι σχέση έχει αυτό;

Αναφορά σε κείμενο

2) Φυσικά και είναι illegal. Εάν ήξερες ότι είναι unmodifiable lvalue ο πίνακας, δεν θα έβαζες καν αυτό το παράδειγμα. 

Όχι δεν το ήξερα. Καλά που ήρθες και μου το είπες. Επίσης μάντεψε τι. Μπορείς να γράψεις int *p = 0xabcd; αλλά δεν μπορείς να γράψεις int arr[] = 0xabcd; Γιατί το arr δεν είναι pointer. ;)

Γενικά μπορείς να ισχυρίζεσαι και να υποστηρίζεις ότι θες.

Αυτό που ισχύει όμως είναι ότι arrays != pointers και ότι array μέσα από function δεν μπορείς να επιστρέψεις.

@marios28
Το 1) σου είναι σωστό αλλά και τα δύο είναι pointers. Όχι arrays. Τα formal parameters ενός function είναι το μόνο σημείο στο οποίο ισχύει ότι  int * == int [ ].

Στο 2) επιστρέφεις έναν pointer σε int. Δεν επιστρέφεις array. Τα δεδομένα στα οποία δείχνει ο pointer αποφασίζεις μετά να τα κάνεις interpret σαν array of ints (για το οποίο "array" δεν ξέρεις καν το size για να το κάνεις iterate). Cool.

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

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

Ρε συ fortistis σου δώσανε 15 επιχειρήματα και ακόμη επιμένεις.

Αν το "είναι το ίδιο" έχει διαφορετική έννοια στο μυαλό σου από ό,τι στα λεξικά και στο μυαλό όλων των άλλων και σημαίνει "σε πολλές περιπτώσεις συμπεριφέρονται το ίδιο" τότε πάω πάσο αλλά σε διαφορετική περίπτωση πρέπει να σταματήσεις να επιμένεις γιατί ΔΕΝ είναι το ίδιο.

Όπως σου γράψανε ήδη ο ilias και ο defacer, ΔΕΝ είναι το ίδιο απλά σε ορισμένα σενάρια οι πίνακες γίνονται decay σε "δείκτη στο τύπο του πρώτου στοιχείου". Επίσης, για ευκολία ο compiler σου επιτρέπει να χρησιμοποιείς οποιοδήποτε από τους δύο τρόπους addressing και σε πίνακες και σε δείκτες οπότε μπορείς να έχεις εκφράσεις του στυλ p [ i ] = foo αντί για *(p+i) = foo ή αντί για *p++ = foo.

Αυτά όμως δεν σημαίνουν ότι είναι το ίδιο όπως φαίνεται στα παραδείγματα που σου έδωσαν και όπως έχουν διαπιστώσει όσοι έχουν προσπαθήσει να χρησιμοποιήσουν πίνακες > 1 διάστασης :)

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

@defacer, @ilias95

Έγραψα πουθενά ότι είναι arrays; Μα πώς θα είναι στο [1] array αφού ο πίνακας περνιέται ως δείκτης στη μέθοδο(άσχετα αν χρησιμοποιούμε brackets) ή στο [2] επιστρέφεται δείκτης.

Ήμουν σαφής. Μη βιάζεστε και ξαναδιαβάστε τα παραπάνω. Τα παραδείγματα τα έφερα για να δείξω ότι η χρήση είναι ίδια (είτε ως πίνακας, είτε ως pointer). Δε μας ενδιαφέρει. Οπότε θα μπορούσαμε να ισχυριστούμε ότι μοιάζουν (δε διαφέρουν). Όχι όμως ότι οι πίνακες είναι pointers. Εξ' αρχής συμφώνησα. Είναι προφανές.

 @ilias95 και για το [2] ισχύει ό,τι και για το 1. Ένα απλό παράδειγμα είναι. 

Το κουράσαμε.

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

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

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

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

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

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

Σύνδεση

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

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

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