Oppure

Loading
06/01/14 16:24
gcali30
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?


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

void shuffle( int wDeck[][ 13 ] );
void deal( const int wDeck[][ 13 ], const char *wFace[], const char *wSuit[] );

int main( void )
{
   /* Inizializza il vettore dei semi */
   const char *suit[ 4 ] = { "Hearts", "Diamonds", "Clubs", "Spades" };
   
   /* Inizializza il vettore delle facce */
   const char *face[ 13 ] = { "Ace", "Deuce", "Three", "Four", 
                              "Five", "Six", "Sever", "Eight",
                              "Nine", "Ten", "Jack", "Queen", "King" };

   /* Inizializza il vettore del mazzo di carte */
   int deck[ 4 ][ 13 ] = { 0 };

   /* Specifica il seme per il generatore di numeri casuali */
   srand( time(NULL) );

   shuffle( deck );
   deal( deck, face, suit ); 

   return 0;
} /* Fine della funzione main */


/* Mescola le carte nel mazzo */
void shuffle( int wDeck[][ 13 ] )
{
   int row; /* Numero di riga */
   int column; /* Numero di colonna */
   int card; /* Contatore */

   /* Per ognuna delle 52 carte, sceglie a caso una casella del mazzo */
   for( card = 1; card <= 52; card++ ) {

      do {
          row = rand() % 4;
          column = rand() % 13;   
      } while ( wDeck[ row ][ column ] != 0 ); /* Controlla se la casella è libera */

      /* Memorizza il numero della carta nella casella del mazzo scelta */

      wDeck[ row ][ column ] = card;
   }
} /* Fine della funzione shuffle */
   
void deal( const int wDeck[][ 13 ], const char *wFace[], const char *wSuit[] )
{
   int card; /* Contatore delle carte */
   int row; /* Contatore delle righe */
   int column; /* Contatore delle colonne */

   /* Distribuisce ognuna delle 52 carte */
   for( card = 1; card <= 52; card++ ) {

     /* Itera scorrendo le righe di wDeck */
     for( row = 0; row <= 3; row++ ) {

        /* Itera scorrendo le colonne di wDeck*/
        for( column = 0; column <= 12; column++ ) {

           /* Se la casella contiene la carta corrente, la visualizza */
           if ( wDeck[ row ][ column ] == card ) {
              printf( "%s of %s\n", wFace[ column ], wSuit[ row ]);
           } /* Fine del comando if */
        } /* Fine del comando for */
     } /* Fine del comando for */
  } /* Fine del comando for */
} /* 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 06/01/14 16:31
aaa
06/01/14 17:12
Kron_Os
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.
aaa
06/01/14 17:19
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.
EDIT: preceduto.
Ultima modifica effettuata da ZioCrocifisso 06/01/14 17:20
aaa
06/01/14 17:37
gcali30
Grazie mille a tutti e due del chiarimento!
Adesso mi è tutto molto più chiaro. :k:
aaa
07/01/14 18:26
nessuno
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à.
07/01/14 18:47
ZioCrocifisso
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 07/01/14 19:06
aaa
07/01/14 19:01
vbextreme
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.
aaa
07/01/14 19:08
ZioCrocifisso
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 07/01/14 19:28
aaa