Come generare una matrice quadrata casuale tramite sottoprogrammi

di il
13 risposte

Come generare una matrice quadrata casuale tramite sottoprogrammi

Salve a tutti, probabilmente già mi conoscete per il thread riguardo la matrice 10x10, ora il problema è simile ma diverso.
Colgo l'occasione per ringraziare @Nippolo e @oregon che nell'altro thread mi hanno letteralmente salvato.

Ma andiamo al dunque: devo creare una matrice quadrata casuale (ma sempre con un numero di righe-colonne incluso tra 2 e 10) tramite sottoprogrammi.
Avevo pensato di risolvere così: assegnare nei prototipi delle funzioni i valori di righe e colonne all'array bidimensionale (matrice) tramite delle variabili globali definite con lo specificatore const, poi definire la matrice all'interno del main con i valori di righe e colonne generati casualmente.
Ma purtroppo non funziona, mi da errore.
Posto qui sotto codice ed errori.
Come di solito, ringrazio in anticipo chiunque sappia aiutarmi.

Codice NON funzionante:

/*
Programma che genera una matrice quadrata numerica casuale e la stampa a schermo
*/
#include <iostream>
#include <stdlib.h>
#include <ctime>

using namespace std;
//variabili globali
const int righe=10;
const int colonne=10; 


//prototipi
void numerorighecolonne (int x, int y);
void generamatrice(int f, int h,int x[righe][colonne]);
void stampa (int f, int h,int x[righe][colonne]); 

//programma principale
int main(){
	
	srand(time(0)); //inizializzazione seme
	
	int r,c; //variabili righe e colonne
	
	////generazione numero di righe e colonne con un valore compreso tra 2 e 10
	
	numerorighecolonne (r,c);
	
	
   int matrice[r][c];
   
   cout<<"Ora uscira' a schermo una matrice casuale.\n\n";
    
   
   
   //generazione matrice
   generamatrice(r, c, matrice);
   
   //stampa a schermo della matrice
   stampa(r, c, matrice);
   
   cout<<"\n\n\n";

   return 0; 
}

//sottoprogrammi

//generazione numero di righe e colonne

void numerorighecolonne (int r, int c){
	r=rand()%10;
	c=r;
	
	if(r==0 || r==1){
		r=2;
		c=2;
		return r,c;
	}else{
		return r,c;
	}
}



//generazione matrice
void generamatrice(int r, int c, int matrice[r][c]){
   int i,j;
   
   for(i=0; i<r; i++){
       for(j=0; j<c; j++){
          matrice[i][j]=rand()%100;
      }
  }
}

//stampa a schermo matrice
void stampa(int r, int c, int matrice[r][c]){
   int i,j;

   for (i=0; i<r; i++){
   cout<<"\n";
   for (j=0; j<c; j++){
      cout<<matrice[i][j]<<" ";
   }
   }
}

Errori:

13 Risposte

  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    NON CI SI INVENTA la sintassi di un linguaggio di programmazione!

    Quello che che hai scritto potrebbe sembrare ragionevole in 'taliano', NON E' ASSOLUTAMENTE VALIDO secondo la sintassi e semantica del C.

    Non e' per non spiegarti gli errori, ma per descriverli tutto dovrei scrivere l'equivalente di un libro sul C.

    Ad esempio:
    
    /*
    Programma che genera una matrice quadrata numerica casuale e la stampa a schermo
    */
    #include <iostream>
    #include <stdlib.h>
    #include <ctime>
    
    using namespace std;
    //variabili globali
    const int righe=10;
    const int colonne=10;
    
    
    //prototipi
    void numerorighecolonne (int x, int y);
    void generamatrice(int f, int h,int x[righe][colonne]);     NO: sintassi sbagliata   
    void stampa (int f, int h,int x[righe][colonne]);                 NO: sintassi sbagliata
    
    NI: inconsistenza tra nomi di parametri nella dichiarazione (x,y, f,h) con x che una volta e' un intero ed una volta una matrice, e nella definizione (r,c,matrice).
    Si puo' fare, MA PUO' ESSERE CONSIDERATO UN ERRORE.
    
    //programma principale
    int main(){
       
       srand(time(0)); //inizializzazione seme
       
       int r,c; //variabili righe e colonne
       
       ////generazione numero di righe e colonne con un valore compreso tra 2 e 10
       
       numerorighecolonne (r,c);    NO: non fa quello che pensi
       
       
       int matrice[r][c];       NO: sintassi sbagliata
       
       cout<<"Ora uscira' a schermo una matrice casuale.\n\n";
       
       
       
       //generazione matrice
       generamatrice(r, c, matrice);    NO: non fa quello che pensi
       
       //stampa a schermo della matrice
       stampa(r, c, matrice);    NI: l'idea e' buona ma non funziona
       
       cout<<"\n\n\n";
    
       return 0;
    }
    
    //sottoprogrammi
    
    //generazione numero di righe e colonne
    
    void numerorighecolonne (int r, int c){
       r=rand()%10;
       c=r;
       
       if(r==0 || r==1){
          r=2;
          c=2;
          return r,c;      NO: sintassi sbagliata, la funz e' di tipo void
       }else{
          return r,c;      NO: come sopra
       }
    }
    
    
    
    //generazione matrice
    void generamatrice(int r, int c, int matrice[r][c]){ NO: la sintassi e' sbagliata
                                                                                        NO: crei una copia LOCALE della matrice
                                                                                        quindi le modifiche non saranno visibili 
                                                                                        all'esterno
       int i,j;
       
       for(i=0; i<r; i++){
           for(j=0; j<c; j++){
              matrice[i][j]=rand()%100;
          }
      }
    }
    
    //stampa a schermo matrice
    void stampa(int r, int c, int matrice[r][c]){  NO: sintassi sbagliata
       int i,j;
    
       for (i=0; i<r; i++){
       cout<<"\n";
       for (j=0; j<c; j++){
          cout<<matrice[i][j]<<" ";
       }
       }
    }
    

    I problemi sono:

    1) dichiarazione di vettori e matrici
    2) passaggio parametri ad una funzione (PER REFERENCE/VALORE)
    3) come una funzione ritorna un valore

    QUALUNQUE buon libro sul C/C++ tratta ESTENSIVAMENTE questi argomenti.
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    Alcune considerazioni di carattere generale:
    - il return 0 nel main è superfluo;
    - come già detto nell'altro topic, nei prototipi delle funzioni l'identificatore degli argomenti può essere omesso;
    - quando includi librerie del C in un file C++, sarebbe meglio includerle come ctizio e non come tizio.h;
    - dalle immagini che hai postato mi sembra di capire che utilizzi Dev-C++, ma come IDE c'è molto di meglio in giro, tipo Code::Blocks. Quindi se puoi cambia;
    - al fine di scrivere codice più chiaro e leggibile ti suggerisco di rispettar la spaziatura, l'indentazione, di riportare una sola istruzione per riga e di evitare tutti quei commenti e spazi bianchi;
    - per le variabili e le funzioni utilizza nomi esplicativi e se gli identificatori sono costituiti da più parole utilizza degli underscore per rendere il tutto più chiaro;
    - nei cicli for all'interno dello spazio dedicato alla "inizializzazione" puoi effettuare anche una dichiarazione.

    Giusto per farti capire, alla luce di quanto appena detto il codice da te postato diventerebbe:
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    const int R = 10;
    const int C = 10;
    
    void numero_righe_colonne(int, int);
    void genera_matrice(int, int,int [R][C]);
    void stampa_matrice(int, int, int [R][C]);
    
    int main()
    {
        srand(time(0));
        int r;
        int c;
        numero_righe_colonne(r,c);
        int matrice[r][c];
        genera_matrice(r, c, matrice);
        stampa_matrice(r, c, matrice);
    }
    
    void numero_righe_colonne(int r, int c)
    {
        r = rand() % 10;
        c = r;
        if(r == 0 || r == 1)
        {
            r = 2;
            c = 2;
            return r, c;
        }
        else
        {
            return r, c;
        }
    }
    
    void genera_matrice(int r, int c, int matrice[r][c])
    {
        for(unsigned int i = 0; i < r; ++i)
        {
            for(unsigned int j = 0; j < c; ++j)
            {
                matrice[i][j] = rand() % 100;
            }
        }
    }
    
    void stampa_matrice(int r, int c, int matrice[r][c])
    {
        for(unsigned int i = 0; i < r; ++i)
        {
            cout << "\n";
            for(unsigned int j = 0; j < c; ++j)
            {
                cout << matrice[i][j] << " ";
            }
        }
    }
    Per il resto sono d'accordo con @migliorabile.
    Nell'altro post hai detto che hai iniziato a programmare da poco, se posso volevo chiederti se stai seguendo un corso oppure stai imparando da autodidatta? In tal caso da quale materiale stai studiando?
    Se ti può esser utile ti lascio il link ad un corso in C++ abbastanza ben fatto:
    http://www.bo.cnr.it/corsi-di-informatica/corsoCstandard/Lezioni/01Indice.html#Caratt_Gen

    Appurato che sul forum diventa difficile spiegarti interi argomenti di teoria, volevo cmq fare un paio di considerazioni di carattere logico:
    - premesso che le funzioni non possono ritornare due valori e che una funzione di tipo void non può ritornare un intero, relativamente alla funzione numero_righe_colonne() mi chiedo che senso ha distinguere tra righe e colonne se la matrice è quadrata;
    - se la matrice quadrata deve avere una dimensione massima di 10, l'operazione rand()%10 non va bene, in quanto restituisce un numero compreso tra 0 e 9;
    - inoltre nella stessa funzione c'è qualcosa che non va dal punto di vista puramente probabilistico, infatti nel momento in cui assegni alla dimensione un valore di 2 (nel caso in cui il numero casuale sia 0 o 1), accadrà che una matrice di dimensione 2 sarà più probabile rispetto ad una matrice di dimensione 3, 4, 5, 6, 7, 8 o 9;
    - i suddetti problemi possono essere risolti utilizzando una formula in grado di restituirci direttamente una valore compreso nell'intervallo chiuso [A;B] (ovviamente con B > A). Ti invito a riflettere per esempio sulla seguente formula: A+rand()%(B-A+1);
    - nell'altro topic avevamo detto che secondo lo standard C++ la dimensione di un array statico deve essere una costante... bene, nel main quando scrivi int matrice[r][c], r e c sono costanti o sono variabili?
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    @Nippolo, anche tu: non dire "corbellerie"!

    E si che non sei un utente inesperto !
    return 0;


    nel main e' il codice di ritorno che passa il processo al sistema operativo.

    Da script, tu puoi leggere questo valore e sapere se il programma e' terminato con successo o con fallimento:

    == 0 -> successo
    != 0 -> fallimento, ed i codice dice il tipo di fallimento, se previsto

    Il fatto che RARAMENTE si faccia questo controllo NON VUOL DIRE CHE RITORNARE 0 SIA SUPERFLUO

    Non e' la prima volta che fai questa affermazione.

    Per punizione:

    scrivi un programma che ritorna i codici di errore da 0 a 9 e per ogni valore uno script (per linux o per windows) deve scrivere a console

    non devo scrivere che ritornare 0 dal main non serve

    E posta il codice
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    Per quanto riguarda il C non so se gli standard più recenti lo prevedano (se non erro dal C99 in poi sì), ma nel C++ il valore di ritorno del main può essere omesso. Il motivo è il seguente frammento tratto dallo standard:
    A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;
    @migliorabile, se vuoi smentirmi sei libero di farlo!
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    Certo che sono libero, come chiunque e' libero di dire corbellerie

    Allora andiamo nel dettaglio:

    1) referenzia BENE lo standard: mi serve un link dove posso leggere anche quello che c'e' attorno

    2) certi consigli li puoi dare, motivandoli con l'opportuno riferimento, ad uno esperto

    NON LI PUOI DARE

    ad un neofita!

    Il motivo DOVREBBE ESSERE OVVIO ANCHE A TE:

    incasinare un INESPERTO con casi particolari NON HA SENSO!!!
    
    in main(int argc, char** argv){ ... }
    
    o se vuoi
    
    int main(int argc, char** argv, char** env){ ... }
    
    E' o NON E' una funzione?

    E' una funzione che ritorna un intero!

    Il fatto che LO POSSA O MENO ritornare, e' ININFLUENTE!

    Quindi il codice DEVE terminare con
    
    return <intero>;
    
    ANCHE SE LO STANDARD DICE CHE per questo particolarissimo caso (il main), non serve!

    Questo perche' PER QUALUNQUE ALTRA FUNZIONE si deve seguire questo particolare paradigma:

    - ha un tipo di ritorno? DEVE ritornare un valore coerente
    - e' di tipo VOID? NON DEVE ritornare niente!

    Ma andiamo piu' nel dettaglio!

    Perche' SE l'applicazione termina ma non passa per un return dovrebbe ritornare 0?

    1) il sistema operativo NON PUO' SAPERE se l'applicazione e' o meno passata per un return, quindi NON PUO' essere lui (il SO) a decidere se il programma ritorna 0 oppure no

    2) ma lo potrebbe sapere il compilatore, il quale, PER LA FUNZIONE "main" (ma a questo punto potrebbe farlo anche per altre funzioni) SA che deve generare un "return 0" la dove il flusso di esecuzione termina senza incontrare un return.


    Altrimenti, FORNISCI TU una spiegazione valida!
    Opportunamente motivata e bibliografata!


    Aggiusto il tiro:

    http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
    sezione 3.6.1 paragrafo 5 (pagina 62):

    A return statement in main has the effect of leaving the main function (destroying any objects with automatic
    storage duration) and calling std::exit with the return value as the argument. If control reaches the end
    of main without encountering a return statement, the effect is that of executing


    QUINDI e' il COMPILATORE che implementa un ulteriore
    
    return std::exit(0);
    
    alla fine del codice del main.

    Direi che la cosa e' TALMENTE particolare, che non ha senso prenderla in considerazione.

    Se ad un esame uno mi dovesse presentare un main senza return, a meno che non ci metta un commento grande come una casa sul PERCHE' non ha messo il return, lo rimando alla sessione d'esame successiva!

    E continuiamo con le castronate:

    ANCHE SE lo standard PREVEDE che nei prototipi si possa NON METTERE il nome del parametro

    E' BUONA NORMA, PRATICA CONSOLIDATA, e' ALTAMENTE AUSPICABILE che uno ci metta il nome del parametro, PERCHE' AUTA A CAPIRE CHE COSA RAPPRESENTA quel parametro!

    Se scrivi
    
    void sleep(long);
    
    in che unita' di misura temporale si deve indicare il tempo di sleep?
    Uno deve andare a spluciare la documentazione (SE ESISTE !)

    Se scrivi
    
    voi sleep(long  millis);
    
    Lo capisce anche un testone quale e' l'unita di misura.

    Gia' si commenta poco il codice, ed i giovinastri scrivono codice orrendo/orrido/orripilante

    SE POI DAI ANCHE CONSIGLI DI CATTIVA PROGRAMMAZIONE,

    non ne usciamo piu' !!!!
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    2) certi consigli li puoi dare, motivandoli con l'opportuno riferimento, ad uno esperto

    NON LI PUOI DARE

    ad un neofita!

    Il motivo DOVREBBE ESSERE OVVIO ANCHE PER TE:

    incasinare un INESPERTO con casi particolari NON HA SENSO!!!
    E' un'argomentazione condivisibile, anche se in riferimento al caso specifico mi sembra un tantino eccessivo... non credo che dire ad un neofita che nel main il return 0 può essere omesso lo mandi in cura da un'analista!
    Se ad un esame uno mi dovesse presentare un main senza return, a meno che non ci metta un commento grande come una casa sul PERCHE' non ha messo il return, lo rimando alla sessione d'esame successiva!
    Anche se tutto il resto era perfetto? Spero tu sia volutamente provocatorio per far passare il messaggio qui sul forum e che tu non sia il tipico caso di prof radical chic!
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    Grazie a tutti per le correzioni, e specialmente per la segnalazione degli errori e degli argomenti da rivedere.

    Nippolo ha scritto:


    Alcune considerazioni di carattere generale:
    - quando includi librerie del C in un file C++, sarebbe meglio includerle come ctizio e non come tizio.h;
    Chiaro, ho corretto.

    Nippolo ha scritto:


    - dalle immagini che hai postato mi sembra di capire che utilizzi Dev-C++, ma come IDE c'è molto di meglio in giro, tipo Code::Blocks. Quindi se puoi cambia;
    Purtroppo devo farci un esame su Dev-C++, quindi preferisco usarlo per "conoscere le armi della battaglia".
    Uso Code::Blocks quando sono abbastanza sicuro che il codice sia corretto e che sia il Dev a sbagliare (abbastanza raramente).

    Nippolo ha scritto:


    - per le variabili e le funzioni utilizza nomi esplicativi e se gli identificatori sono costituiti da più parole utilizza degli underscore per rendere il tutto più chiaro;
    Va bene, ho corretto.

    Nippolo ha scritto:


    - nei cicli for all'interno dello spazio dedicato alla "inizializzazione" puoi effettuare anche una dichiarazione.
    Grazie, ho corretto.

    Nippolo ha scritto:


    Per il resto sono d'accordo con @migliorabile.
    Nell'altro post hai detto che hai iniziato a programmare da poco, se posso volevo chiederti se stai seguendo un corso oppure stai imparando da autodidatta? In tal caso da quale materiale stai studiando?
    Sto imparando da autodidatta perché non posso seguire i corsi, la materia è fondamenti di informatica.

    Nippolo ha scritto:


    Se ti può esser utile ti lascio il link ad un corso in C++ abbastanza ben fatto:
    http://www.bo.cnr.it/corsi-di-informatica/corsoCstandard/Lezioni/01Indice.html#Caratt_Gen
    Grazie gentilissimo, me lo vedo con calma da domani.

    Nippolo ha scritto:


    Appurato che sul forum diventa difficile spiegarti interi argomenti di teoria, volevo cmq fare un paio di considerazioni di carattere logico:
    - premesso che le funzioni non possono ritornare due valori e che una funzione di tipo void non può ritornare un intero, relativamente alla funzione numero_righe_colonne() mi chiedo che senso ha distinguere tra righe e colonne se la matrice è quadrata;
    Grazie per le precisazioni, hai ragione, difatti ora ho cancellato la variabile c e ho lasciato solo la variabile r.

    Nippolo ha scritto:


    - se la matrice quadrata deve avere una dimensione massima di 10, l'operazione rand()%10 non va bene, in quanto restituisce un numero compreso tra 0 e 9;
    Vero, ho corretto, grazie per la segnalazione.

    Nippolo ha scritto:


    - inoltre nella stessa funzione c'è qualcosa che non va dal punto di vista puramente probabilistico, infatti nel momento in cui assegni alla dimensione un valore di 2 (nel caso in cui il numero casuale sia 0 o 1), accadrà che una matrice di dimensione 2 sarà più probabile rispetto ad una matrice di dimensione 3, 4, 5, 6, 7, 8 o 9;
    - i suddetti problemi possono essere risolti utilizzando una formula in grado di restituirci direttamente una valore compreso nell'intervallo chiuso [A;B] (ovviamente con B > A). Ti invito a riflettere per esempio sulla seguente formula: A+rand()%(B-A+1);
    Grazie per il consiglio, ma questo non è problema, l'importante è che generi una matrice quadrata casuale.

    Nippolo ha scritto:


    - nell'altro topic avevamo detto che secondo lo standard C++ la dimensione di un array statico deve essere una costante... bene, nel main quando scrivi int matrice[r][c], r e c sono costanti o sono variabili?
    Esatto, secondo lo standard del C++ la dimensione di un array statico deve essere una costante, quindi per logica visto che non sappiamo quanto sarà di preciso, l'array bidimensionale dovrà essere dinamico.
    Quando scrivo int matrice [r][r] (poiché la matrice è quadrata), r è una variabile, in quanto è un valore casuale compreso tra 2 e 10.
    Quindi il problema è che devo allocare dinamicamente un'array bidimensionale, almeno da quanto ho capito...

    Cercando su internet ho visto che scrivono cose del tipo:
    
    int **matrice;
    
    Che altro non è un puntatore a puntatore. Cioè serve a puntare al primo puntatore del vettore di puntatori...

    Però a me questo sembra più un escamotage per evitare il problema piuttosto che risolverlo...

    Posto il codice NON funzionante in parte corretto (specialmente la prima parte che doveva generare il valore casuale tra 2 e 10, l'ho provata in un programma a parte e funziona), scritto in modo tale che possa soddisfare sia te che il Prof. @migliorabile (è un professore da quanto ho capito, giusto?), quest'ultimo che ringrazio in particolar modo, in quanto è proprio il punto di vista di un docente.
    
    /*
    Programma che genera una matrice quadrata numerica casuale e la stampa a schermo
    */
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    //prototipi
    int numero_righe_e_colonne (int r);
    void generamatrice(int r,int matrice[ ][ ]); //cosa ci metto tra le quadre? secondo lo standard del C++, la dimensione degli array deve essere una costante...
    void stampa (int r,int matrice[ ][ ]); //come sopra
    
    //programma principale
    int main(){
    	
    	srand(time(0)); //inizializzazione seme
    	
    	int r; //indice righe e colonne
    	
    	////generazione numero di righe e colonne con un valore compreso tra 2 e 10
    	r=numero_righe_e_colonne (r);
    	
       int matrice[r][r];
       
       cout<<"Ora uscira' a schermo una matrice casuale.\n\n";
       
       //generazione matrice
       generamatrice(r, matrice);
       
       //stampa a schermo della matrice
       stampa(r, matrice);
       
       cout<<"\n\n\n";
    
       return 0; 
    }
    
    //sottoprogrammi
    
    //generazione numero di righe e colonne
    
    int numero_righe_e_colonne (int r){
    	r=rand()%10+1;
    	
    	if(r==0 || r==1){
    		r=2;
    		return (r);
    	}else{
    		return (r);
    	}
    }
    
    //generazione matrice
    void generamatrice(int r, int matrice[r][r]){
       for(int i=0; i<r; i++){
           for(int j=0; j<r; j++){
              matrice[i][j]=rand()%100;
          }
      }
    }
    
    //stampa a schermo matrice
    void stampa(int r, int matrice[r][r]){
       for (int i=0; i<r; i++){
       cout<<"\n";
       for (int j=0; j<r; j++){
          cout<<matrice[i][j]<<" ";
       }
       }
    }
    
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    @Nippolo, non sono radical chic, sono mooooolto peggio

    Per quanto riguarda i consigli, come sai, scrivere BUON codice e' un'operazione che richiede grande attenzione.

    Meglio IMPRIMERE (a FUOCO se possibile ) nella testolina degli inesperti le BUONE PRATICHE di programmazione, eliminando il piu' possibile quelle varianti che sono supportabili dal linguaggio ma che AUMENTANO il rischio di errori invece di ridurlo, che AUMENTANO l'entropia invece di ridurla, ecc ...

    Inoltre, e' buona pratica FORZARE il discente (:-) ) a STUDIARE SUI LIBRI, invece che fornirgli le spiegazioni qui sul forum.

    Ovviamente, NON E' per non dare spiegazioni, ma per FORZARLI a capire che il forum serve aiutare a per risolvere problemi complicati (per loro, non in generale), NON come alternativa al primo capitolo del libro!
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    nabboc++ ha scritto:


    Grazie per il consiglio, ma questo non è problema, l'importante è che generi una matrice quadrata casuale.
    Capisco che il focus è posto sulla parte prettamente informatica, ma se con "casuale" si intende che ad ogni valore compreso tra 2 e 10 sia associata la stessa probabilità, allora sia la vecchia versione della funzione numero_righe_colonne() sia quella nuova restituiscono probabilità non equamente distribuite. In particolare per la vecchia versione ("p" sta per probabilità):
    p(2) = 3/10
    p(3,4,5,6,7,8,9) = 1/10
    p(10) = 0
    Per la nuova versione:
    p(2) = 2/10
    p(3,4,5,6,7,8,9,10) = 1/10
    Rimanendo sull'ultima versione della suddetta funzione, va inoltre detto che l'espressione r=rand()%10+1 ritorna un intero compreso tra 1 e 10, converrai quindi che la condizione r==0 è inutile (in quanto sempre falsa).
    La formula che avevo proposto nell'altro post (A+rand()%(B-A+1)), nel caso specifico in cui l'intervallo di interesse è [2;10] diventa semplicemente 2+rand()%9, dove rand()%9 ritorna un intero compreso tra 0 e 8, quindi sommando 2 si ha che l'espressione ritorna un numero compreso tra 2 e 10.

    nabboc++ ha scritto:


    Esatto, secondo lo standard del C++ la dimensione di un array statico deve essere una costante, quindi per logica visto che non sappiamo quanto sarà di preciso, l'array bidimensionale dovrà essere dinamico.
    Quando scrivo int matrice [r][r] (poiché la matrice è quadrata), r è una variabile, in quanto è un valore casuale compreso tra 2 e 10.
    Quindi il problema è che devo allocare dinamicamente un'array bidimensionale, almeno da quanto ho capito...
    In realtà il problema può essere risolto anche senza scomodare l'allocazione dinamica. Basta fissare per gli array una dimensione massima (10x10 in questo caso) e poi considerare solo quelli che ci interessano (rxr in questo caso, dove r è un valore casuale compreso tra 2 e 10).

    @migliorabile, concordo, infatti non sono solito spiegare nuovi argomenti, ma mi limito a far ragionare il mio interlocutore su argomenti che in teoria dovrebbe già conoscere e ad usare quel pizzico di buon senso e di logica che non guasta mai (a prescindere dell'argomento trattato).
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    Nippolo ha scritto:


    [...]
    Rimanendo sull'ultima versione della suddetta funzione, va inoltre detto che l'espressione r=rand()%10+1 ritorna un intero compreso tra 1 e 10, converrai quindi che la condizione r==0 è inutile (in quanto sempre falsa).
    Giusto.

    Nippolo ha scritto:


    La formula che avevo proposto nell'altro post (A+rand()%(B-A+1)), nel caso specifico in cui l'intervallo di interesse è [2;10] diventa semplicemente 2+rand()%9, dove rand()%9 ritorna un intero compreso tra 0 e 8, quindi sommando 2 si ha che l'espressione ritorna un numero compreso tra 2 e 10.
    Chiaro, grazie per la spiegazione, l'ho implementato nel codice.

    Nippolo ha scritto:


    In realtà il problema può essere risolto anche senza scomodare l'allocazione dinamica. Basta fissare per gli array una dimensione massima (10x10 in questo caso) e poi considerare solo quelli che ci interessano (rxr in questo caso, dove r è un valore casuale compreso tra 2 e 10).
    Giusto, come ho fatto a non pensarci...
    @Nippolo, grazie ancora dell'aiuto, senza le tue osservazioni probabilmente sarei finito a fare testa e monitor.

    E visto che potrebbe tornare utile a qualcuno, posto il codice funzionante:
    
    /*
    Programma che genera una matrice quadrata numerica casuale e la stampa a schermo
    */
    #include <iostream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    //variabili globali
    const int righe_colonne=10;
    
    //prototipi
    int numero_righe_e_colonne (int r);
    void generamatrice(int r,int matrice[righe_colonne][righe_colonne]); 
    void stampa (int r,int matrice[righe_colonne][righe_colonne]); 
    
    //programma principale
    int main(){
    	
    	srand(time(0)); //inizializzazione seme
    	
    	int r; //indice righe e colonne
    	
    	r=numero_righe_e_colonne (r); //generazione numero di righe e colonne con un valore compreso tra 2 e 10
    	
       int matrice[righe_colonne][righe_colonne];
       
       cout<<"Ora uscira' a schermo una matrice casuale.\n\n";
       
       generamatrice(r, matrice);  //generazione matrice
       
       stampa(r, matrice); //stampa a schermo della matrice
       
       cout<<"\n\n\n";
    
       return 0; 
    }
    
    //sottoprogrammi
    
    //generazione numero di righe e colonne
    int numero_righe_e_colonne (int r){
    	r=2+rand()%9;
        return (r);
    }
    
    //generazione matrice
    void generamatrice(int r, int matrice[righe_colonne][righe_colonne]){
       for(int i=0; i<r; i++){
           for(int j=0; j<r; j++){
              matrice[i][j]=rand()%100;
          }
      }
    }
    
    //stampa a schermo matrice
    void stampa(int r, int matrice[righe_colonne][righe_colonne]){
       for (int i=0; i<r; i++){
       cout<<"\n";
       for (int j=0; j<r; j++){
          cout<<matrice[i][j]<<" ";
       }
       }
    }
    
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    migliorabile ha scritto:


    @Nippolo, non sono radical chic, sono mooooolto peggio

    Per quanto riguarda i consigli, come sai, scrivere BUON codice e' un'operazione che richiede grande attenzione.

    Meglio IMPRIMERE (a FUOCO se possibile ) nella testolina degli inesperti le BUONE PRATICHE di programmazione, eliminando il piu' possibile quelle varianti che sono supportabili dal linguaggio ma che AUMENTANO il rischio di errori invece di ridurlo, che AUMENTANO l'entropia invece di ridurla, ecc ...

    Inoltre, e' buona pratica FORZARE il discente (:-) ) a STUDIARE SUI LIBRI, invece che fornirgli le spiegazioni qui sul forum.

    Ovviamente, NON E' per non dare spiegazioni, ma per FORZARLI a capire che il forum serve aiutare a per risolvere problemi complicati (per loro, non in generale), NON come alternativa al primo capitolo del libro!
    Condivido quanto hai scritto, però se il libro ti da programmi che NON compilano, per i quali perdi 25 minuti ogni volta a ricopiarli nel DEV, implementa variabili che non ha spiegato prima, bhe, permettimi ma il libro dopo un po' non lo seguo più.

    Dopo apro un'altro thread con un programma copiato PARI PARI dal libro che non compila, e scannerizzo pure le pagine con suddetto programma per far vedere che non mi invento niente.
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    Chiaro, grazie per la spiegazione, l'ho implementato nel codice.
    Premesso che faccio fatica a vedere l'utilità della funzione numero_righe_e_colonne() (nel senso che quel calcolo potevi farlo anche nel main) e ipotizzando che tu ancora non conosca bene la differenza tra passaggio per valore e per riferimento, ti pongo una domanda: quale sarebbe l'utilità del parametro r passato alla suddetta funzione?
    Condivido quanto hai scritto, però se il libro ti da programmi che NON compilano, per i quali perdi 25 minuti ogni volta a ricopiarli nel DEV, implementa variabili che non ha spiegato prima, bhe, permettimi ma il libro dopo un po' non lo seguo più.
    Diamo anche per scontato che il libro (che ipotizzo sia quello consigliato dal prof e magari scritto dallo stesso) sia mal fatto, converrai con me che da qualche parte bisogna pur studiarla la teoria se non si vuole andare completamente a tentoni!
    Giusto, come ho fatto a non pensarci...
    @Nippolo, grazie ancora dell'aiuto, senza le tue osservazioni probabilmente sarei finito a fare testa e monitor.
    Di niente!
  • Re: Come generare una matrice quadrata casuale tramite sottoprogrammi

    Nippolo ha scritto:


    Premesso che faccio fatica a vedere l'utilità della funzione numero_righe_e_colonne() (nel senso che quel calcolo potevi farlo anche nel main)
    Diciamo che lo scopo era poter creare più funzioni possibili e lasciare il main il più libero possibile, in realtà non so se c'è un criterio preciso per quando bisogna creare un apposito sottoprogramma oppure inserirlo nel main.

    Nippolo ha scritto:


    e ipotizzando che tu ancora non conosca bene la differenza tra passaggio per valore e per riferimento, ti pongo una domanda: quale sarebbe l'utilità del parametro r passato alla suddetta funzione?
    Era per evitare di creare una nuova variabile nella funzione...

    Nippolo ha scritto:


    Diamo anche per scontato che il libro (che ipotizzo sia quello consigliato dal prof e magari scritto dallo stesso) sia mal fatto, converrai con me che da qualche parte bisogna pur studiarla la teoria se non si vuole andare completamente a tentoni!
    Giusto, difatti ora sto vedendo online, specialmente quel corso che mi hai linkato e per il quale ti ringrazio ancora.
    Per farti un esempio, sul libro non ci sta scritto che le funzioni possono ritornare un solo valore!
    Se non me l'avessi detto te, probabilmente sarei impazzito.

    Ora apro un'altra discussione con un programma fornito dal libro che non compila, con tanto di pagine scannerizzate, giusto per far capire di cosa parlo.
Devi accedere o registrarti per scrivere nel forum
13 risposte