Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Passare per riferimento un array multidimensionale a una funzione
Forum - C/C++ - Passare per riferimento un array multidimensionale a una funzione

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
gcali30 (Normal User)
Newbie


Messaggi: 2
Iscritto: 21/12/2013

Segnala al moderatore
Postato alle 17:24
Lunedì, 06/01/2014
Salve a tutti!
Studio da poco il C sul manuale della Deitel, e non credo di aver trovato nessun riferimento al passaggio per riferimento (scusate la cacofonia) di un array multidimensionale a una funzione.

Anzi, il sorgente d'esempio passa un array bidimensionale  a una funzione per valore e lo modifica internamente alla funzione... ma così l'array nella funzione chiamante rimane immutato, no?

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4.  
  5. void shuffle( int wDeck[][ 13 ] );
  6. void deal( const int wDeck[][ 13 ], const char *wFace[], const char *wSuit[] );
  7.  
  8. int main( void )
  9. {
  10.    /* Inizializza il vettore dei semi */
  11.    const char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" };
  12.    
  13.    /* Inizializza il vettore delle facce */
  14.    const char *face[ 13 ] = { "Ace", "Deuce", "Three", "Four",
  15.                               "Five", "Six", "Sever", "Eight",
  16.                               "Nine", "Ten", "Jack", "Queen", "King" };
  17.  
  18.    /* Inizializza il vettore del mazzo di carte */
  19.    int deck[ 4 ][ 13 ] = { 0 };
  20.  
  21.    /* Specifica il seme per il generatore di numeri casuali */
  22.    srand( time(NULL) );
  23.  
  24.    shuffle( deck );
  25.    deal( deck, face, suit );
  26.  
  27.    return 0;
  28. } /* Fine della funzione main */
  29.  
  30.  
  31. /* Mescola le carte nel mazzo */
  32. void shuffle( int wDeck[][ 13 ] )
  33. {
  34.    int row; /* Numero di riga */
  35.    int column; /* Numero di colonna */
  36.    int card; /* Contatore */
  37.  
  38.    /* Per ognuna delle 52 carte, sceglie a caso una casella del mazzo */
  39.    for( card = 1; card <= 52; card++ ) {
  40.  
  41.       do {
  42.           row = rand() % 4;
  43.           column = rand() % 13;  
  44.       } while ( wDeck[ row ][ column ] != 0 ); /* Controlla se la casella è libera */
  45.  
  46.       /* Memorizza il numero della carta nella casella del mazzo scelta */
  47.  
  48.       wDeck[ row ][ column ] = card;
  49.    }
  50. } /* Fine della funzione shuffle */
  51.    
  52. void deal( const int wDeck[][ 13 ], const char *wFace[], const char *wSuit[] )
  53. {
  54.    int card; /* Contatore delle carte */
  55.    int row; /* Contatore delle righe */
  56.    int column; /* Contatore delle colonne */
  57.  
  58.    /* Distribuisce ognuna delle 52 carte */
  59.    for( card = 1; card <= 52; card++ ) {
  60.  
  61.      /* Itera scorrendo le righe di wDeck */
  62.      for( row = 0; row <= 3; row++ ) {
  63.  
  64.         /* Itera scorrendo le colonne di wDeck*/
  65.         for( column = 0; column <= 12; column++ ) {
  66.  
  67.            /* Se la casella contiene la carta corrente, la visualizza */
  68.            if ( wDeck[ row ][ column ] == card ) {
  69.               printf( "%s of %s\n", wFace[ column ], wSuit[ row ]);
  70.            } /* Fine del comando if */
  71.         } /* Fine del comando for */
  72.      } /* Fine del comando for */
  73.   } /* Fine del comando for */
  74. } /* Fine della funzione deal */



Mi è sfuggita qualcosa o effettivamente la funzione shuffle non cambia nulla? Ma soprattutto, qualcuno di voi può spiegarmi come puntare un array multidimensionale e il relativo passaggio a funzione? :yup:

Ultima modifica effettuata da gcali30 il 06/01/2014 alle 17:31
PM Quote
Avatar
Kron_Os (Normal User)
Newbie


Messaggi: 8
Iscritto: 17/12/2013

Segnala al moderatore
Postato alle 18:12
Lunedì, 06/01/2014
Teoricamente, ma mi si corregga se sbaglio, quando si passa un'array, si passa l'indirizzo del primo elemento dell'array che teoricamente sono assimilabili a puntatori, quindi quando lavori in una funzione a cui hai passato un'array, modifichi l'array.

PM Quote
Avatar
ZioCrocifisso (Member)
Pro


Messaggi: 135
Iscritto: 06/03/2013

Segnala al moderatore
Postato alle 18:19
Lunedì, 06/01/2014
Essendo gli array multidimensionali già di per sé puntatori a puntatori, vengono passati per riferimento in quel modo (oppure con int**), e la funzione shuffle modifica l'array del chiamante.
EDIT: preceduto.

Ultima modifica effettuata da ZioCrocifisso il 06/01/2014 alle 18:20
PM Quote
Avatar
gcali30 (Normal User)
Newbie


Messaggi: 2
Iscritto: 21/12/2013

Segnala al moderatore
Postato alle 18:37
Lunedì, 06/01/2014
Grazie mille a tutti e due del chiarimento!
Adesso mi è tutto molto più chiaro. :k:

PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6402
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 19:26
Martedì, 07/01/2014
Testo quotato

Postato originariamente da ZioCrocifisso:
Essendo gli array multidimensionali già di per sé puntatori a puntatori, vengono passati per riferimento in quel modo (oppure con int**), e la funzione shuffle modifica l'array del chiamante.
  



Non è proprio così.

In questo caso passi alla shuffle il puntatore all'inizio dell'array ma in memoria questo è rappresentato in maniera "piatta" e solamente la specifica [][13] permette al compilatore di trattare correttamente i valori.

Non è la stessa cosa di usare un doppio puntatore (int **) per cui l'array si sarebbe dovuto allocare diversamente (e infatti non puoi semplicemente sostituire a int wDeck[][ 13 ] un int ** perché sarebbe un grave errore e il compilatore te lo segnalerebbe).


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
ZioCrocifisso (Member)
Pro


Messaggi: 135
Iscritto: 06/03/2013

Segnala al moderatore
Postato alle 19:47
Martedì, 07/01/2014
Non intendevo dire che in questo caso è possibile sostituirlo tranquillamente con int**, ma che int** è un altro modo di passare array multidimensionali.

Ultima modifica effettuata da ZioCrocifisso il 07/01/2014 alle 20:06
PM Quote
Avatar
vbextreme (Normal User)
Newbie


Messaggi: 4
Iscritto: 16/12/2013

Segnala al moderatore
Postato alle 20:01
Martedì, 07/01/2014
Testo quotato

Non intendevo dire che in questo caso è possibile sostituirlo tranquillamente con int**, ma che int** è un altro modo di passare array multidimensionali.



No un array multidimensionale(matrice) si passa solo ed esclusivamente con matrice[][].
Un puntatore a puntatore si passa con matrice** anche se sono simili non sono equivalenti.
Discorso ben diverso dal vettore(array) classico che può corrispondere ad un puntatore.

PM Quote
Avatar
ZioCrocifisso (Member)
Pro


Messaggi: 135
Iscritto: 06/03/2013

Segnala al moderatore
Postato alle 20:08
Martedì, 07/01/2014
L'implementazione è irrilevante, un int** può comunque essere un array multidimensionale. Anche se tra int[][] e int** c'è differenza nella struttura, su di essi è comunque possibile usare la forma a[x][y] per accedere agli elementi, a dimostrazione del fatto che il C considera array multidimensionali sia quelli del primo tipo che del secondo.

Ultima modifica effettuata da ZioCrocifisso il 07/01/2014 alle 20:28
PM Quote
Avatar
vbextreme (Normal User)
Newbie


Messaggi: 4
Iscritto: 16/12/2013

Segnala al moderatore
Postato alle 21:23
Martedì, 07/01/2014
ma non è vero l'opposto:
Codice sorgente - presumibilmente C/C++

  1. int a[1][1];
  2. int **i = a


è errore perchè non sono equivalenti.

Per non indurre nessuno in errore è quindi sempre conveniente dire che non sono uguali,anche se si assomigliano.

PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo