βοηθεια για επιτροφη πινακα απο συναρτηση σε γλωσσα C

Συζητήσεις για την γλώσσα C και C++

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
ianni
Δημοσιεύσεις: 8
Εγγραφή: 12 Απρ 2006 00:38
Τοποθεσία: rodos

βοηθεια για επιτροφη πινακα απο συναρτηση σε γλωσσα C

Δημοσίευση από ianni » 14 Αύγ 2008 03:35

Λοιπον γεια και χαρα σε ολους τους φιλους του freestuff

Ειμαι παλικαρακι ανω των 35 και καλιο αργα παρα ποτε μετα απο πολλα χρονια ενασχολησης μου με τους υπολογιστες αποφασισα να μαθω C για να μπορεσω να ασχοληθω εκτενεστερα με το linux

Το επιπεδο μου αυτην την στιγμη οσο αφορα τον προγραμματισμο ειναι στους pointer kai stis συναρτησεις,αλλα πολυ φρεσκος ακομα.

Και ιδου η απορια μου.Μεχρι στιγμης ηξερα να επιστρεφω μια τιμη απο μια συναρτηση στην main.Τωρα ομως θελω να επιστρεψω εναν ολοκληρο πινακα,δηλαδη παραπανω απο μια τιμη

Μπορω να το κανω στην απλουστερη του μορφη και θα παραθεσω και τον κωδικα μου παρακατω απλα θα θελα να μου επησιμανετε και αλλους τροπους



#include <stdio.h>

void epistrofi_pinaka(int B[])
{
int i;
int C[5];

for(i = 0; i <= 4; i++)
{
C = B++; //apothikevo s enan pinaka tis times tou pinaka A afksanomenes kata 1
}
}



int main()
{
int A[] = {1,2,3,4,5}; // arxikopoio enan pinaka me times 1 2 3 4 5
int i;

epistrofi_pinaka(A); // kalo tin sinartisi


for(i = 0; i <= 4; i++)
{

printf("%i\n",A); //kai emfanizo ta apotelesmata tou pinaka A afksanomena kata 1
}


}


ευχαριστω για οποια βοηθεια.

Άβαταρ μέλους
soteres2002
S. & H. Moderator
Δημοσιεύσεις: 1524
Εγγραφή: 05 Μαρ 2004 22:17
Τοποθεσία: Ιωάννινα

βοηθεια για επιτροφη πινακα απο συναρτηση σε γλωσσα C

Δημοσίευση από soteres2002 » 14 Αύγ 2008 03:50

Μπορείς να επιστέψεις διάνυσμα (δηλ με την έννοια του pointer, άρα έναν δείκτη σε μια φυσική διεύθυνση) από συνάρτηση, δηλαδή η συνάρτησή σου θα έχει πρωτότυπο κάτι σαν int * somefunc(args...), και γενικά void * somefunc(args...). Όμως αυτό απαιτεί να δεσμεύσεις μνήμη από το λειτουργικό δυναμικά, με χρήση {m,k, re}alloc(*), κάτι που είναι μια νορμάλ διαδικασία όταν έχεις να κάνεις με δείκτες - pointers. Επίσης, αν θέλεις να επιστρέψεις ολόκληρο πίνακα σαν δείκτη, μερικές φορές μπορείς να περάσεις κανονικά ένα στατικό πινακα είτε σαν όρισμα είτε σαν όρισμα στο return.

Δηλαδή: αν έχεις δηλώσει κάπου int something[10] = {1, 2, 3, ..., 10}; και έχεις μια συνάρτηση void dosomething(int *ptr); μπορείς να καλέσεις αυτήν με dosomething(something);. Κάνε σαφές στο μυαλό σου ότι αυτά είναι ταυτόσημα κατά μια έννοια, εφόσον αναφέρονται σε διευθύνσεις.

Επίσης πρέπει να μάθεις που να χρησιμοποιείς pointers και που όχι. Το ότι ξέρεις καλά pointers δε σημαίνει ότι πρέπει να τους κοτσάρεις παντού. Υπάρχουν πολλά coding standards, αλλά το επικρατέστερο είναι να περνάς pointer όταν θές πέρασμα δι αναφοράς (by reference) δηλαδή ότι αλλάξει μέσα στη συνάρτηση υπάρχει και μετά την κλήση. Κάτι που δεν συμβαίνει με απλές μεταβλητές καθώς είτε τις αλλάξεις είτε τις αφήσεις άθικτες μέσα στο σώμα της συνάρτησης παραμένουν όπως ήταν πριν την κλήση μόλις χαθεί το scope της συνάρτησης. Το πέρασμα απλών μεταβλητών λέγεται δια τιμής (by value) και συνήθως χρησιμεύει απλά για να περάσεις μια πληροφορία που είναι συνήθως χρήσιμη για το σώμα της συνάρτησης. Επίσης, μια που θα Linux-άρεις σε λίγο, θα δείς σε πολλά έργα κώδικα ένα άλλο πρότυπο: συγκεκριμένα το by value πέρασμα γίνεται με pointer με τη διαφορά ότι βάζεις και ένα const προσδιορισμό πριν τον τύπο του δείκτη. πχ void do(const int *seed);

Θα αλλάξω το παράδειγμά σου ώστε να επιστρέφεις με return ολόκληρο διάνυσμα που το δεσμεύεις δυναμικά, και το επιστρέφεις σαν έναν "αφηρημένο" δείκτη void (όπως πχ int, char κτλ) αντί να αλλάζεις την τιμή από μια void συνάρτηση.

Κώδικας: Επιλογή όλων

#include <stdio.h>
#include <stdlib.h>

#define DIE&#40;x&#41; &#123; printf&#40;"Error&#58; %s\n", x&#41;; exit&#40;1&#41;; &#125;

// epistrefei panta 10 akeraious
void *retVector&#40;const int *param&#41; &#123;
    int *numbers;
    int i;
    
    if&#40;!param&#41; return&#40;&#40;void *&#41;NULL&#41;;

    numbers = &#40;int *&#41;malloc&#40;10 * sizeof&#40;int&#41;&#41;;
    if&#40;!numbers&#41; &#123;
          DIE&#40;"not enough memory"&#41;; 
    &#125;

    for&#40;i = 0; i < 9; i++&#41;
      numbers&#91;i&#93; = i;

    *&#40;numbers + 9&#41; = *param;

    return&#40;&#40;void *&#41;numbers&#41;;
&#125;

int main&#40;&#41; &#123;
   int *l;
   int i, param;
   
   param = 10;
   l = &#40;int *&#41;retVector&#40;&#40;int *&#41;&param&#41;;
   if&#40;!l&#41; &#123;
      DIE&#40;"die die hard!"&#41;;
   &#125;   

   for&#40;i = 0; i < 10; i++&#41;
      printf&#40;"%d&#93; number %d&#58; %d\n", i, i, *&#40;l + i&#41;&#41;;
   
   if&#40;l&#41; free&#40;l&#41;;
    
   return 0;
&#125;
Μια δυνατή εκδοχή του κώδικά σου αλλά με δυναμική δέσμευση και που συνδιάζεις μαζί πολλές άλλες μικρολεπτομέρειες με τους δείκτες.

Με gcc 3.4.6 στον σέρβερ ενός πελάτη έτρεξε κανονικά και έκανα compile με -Ο2 -pedantic -Wall χωρίς κανένα warning.

Θα δεις έξοδο:

Κώδικας: Επιλογή όλων

stressgr@stress.gr &#91;~&#93;# ./test
0&#93; number 0&#58; 0
1&#93; number 1&#58; 1
2&#93; number 2&#58; 2
3&#93; number 3&#58; 3
4&#93; number 4&#58; 4
5&#93; number 5&#58; 5
6&#93; number 6&#58; 6
7&#93; number 7&#58; 7
8&#93; number 8&#58; 8
9&#93; number 9&#58; 10
Τελευταία επεξεργασία από το μέλος soteres2002 την 14 Αύγ 2008 04:19, έχει επεξεργασθεί 2 φορές συνολικά.

ianni
Δημοσιεύσεις: 8
Εγγραφή: 12 Απρ 2006 00:38
Τοποθεσία: rodos

βοηθεια για επιτροφη πινακα απο συναρτηση σε γλωσσα C

Δημοσίευση από ianni » 14 Αύγ 2008 04:11

α φιλε soteres κατ αρχην ευχαριστω για την απαντηση.Απλα απ οτι καταλαβα πρεπει να μαθω να χρισοιμοποιω την malloc e?

πολυ ομορφα,σ ευχαριστω και παλι

Άβαταρ μέλους
soteres2002
S. & H. Moderator
Δημοσιεύσεις: 1524
Εγγραφή: 05 Μαρ 2004 22:17
Τοποθεσία: Ιωάννινα

βοηθεια για επιτροφη πινακα απο συναρτηση σε γλωσσα C

Δημοσίευση από soteres2002 » 14 Αύγ 2008 04:22

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

Επίσης, τσέκαρε και τα structs. Μπορείς να συγκεντρώσεις πληροφορία σε αυτές μέσα σε μια μεταβλητή και να επιστρέφεις απο συναρτήσεις κτλ κτλ.

Φίλε δούλεψε στριφνά παραδείγματα και προσπάθησε να μάθεις και να μιμηθείς το στύλ. Έτσι θα κάνεις καλό kick start σε αυτήν την γλώσσα. Με το να λύνεις απλά προβλήματα δεν θα λύνεις αυθόρμητα τα δικά σου σοβαρότερα προγραμματιστικά προβλήματα τόσο εύκολα. Πάρε κώδικα από μεγάλα projects και προσπάθησε να καταλάβεις παθητικά τι παίζει, αυτό διότι τα εγχειρίδια όσο καλογραμμένα και να είναι έχουν στην πραγματικότητα απλές αναφορές και δεν λένε πώς να χρησιμοποιήσεις τη γλώσσα στην πράξη και σου προσφέρουν μόνο γνώση και 0.1% εμπειρία. Λίγοι είναι αυτοί που φιλοσοφούν όταν γράφουν σε C μεγάλα projects, και είναι δύσκολο να το κάνεις γιατί χτίζεις από μηδενική βάση και πρέπει να χτήσεις κατάλληλα την εφαρμογή. Αν το θες θα γίνεις πολύ καλός C programmer στη συνέχεια, με συνεχόμενη προσπάθεια (όπως οι περισσότεροι κάθε μέρα), αν και σκοπός είναι να έχεις πολύπλευρη γνώση γύρω από τα συστήματα, αρχές σχεδίασης, κτλ και όχι targeted γνώση!

ianni
Δημοσιεύσεις: 8
Εγγραφή: 12 Απρ 2006 00:38
Τοποθεσία: rodos

βοηθεια για επιτροφη πινακα απο συναρτηση σε γλωσσα C

Δημοσίευση από ianni » 14 Αύγ 2008 13:42

να σαι καλα φιλε μου,ησουν κατατοπιστικοτατος,σ ευχαριστω πολυ

Erevis
Δημοσιεύσεις: 56
Εγγραφή: 12 Ιουν 2008 16:31
Τοποθεσία: Χαλάνδρι

βοηθεια για επιτροφη πινακα απο συναρτηση σε γλωσσα C

Δημοσίευση από Erevis » 19 Σεπ 2008 15:25

ianni έγραψε: C = B++; //apothikevo s enan pinaka tis times tou pinaka A afksanomenes kata 1


Άσχετο με το γενικό πνεύμα του post αλλά μικρή διόρθωση γιατί λογικά θα το ξαναχρησιμοποιήσεις μελλοντικά,

έχω την εντύπωση πως λόγω της πρωτεραιότητας των τελεστών πρώτα χαταχωρείται ο Β στο C και μετά αυξάνεται κατά 1, οπότε καλύερα να το γράψεις:

C=++B;

Απάντηση

Επιστροφή στο “C, C++”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 1 επισκέπτης