Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [C++] Programma su array multidimensionale

    Salve a tutti!
    Devo fare un programma che riceva in input la dimensione "n" di una matrice quadrata (n*n), stampi la matrice e stampi in un vettore di interi tutti gli elementi della diagonale principale...
    Il programma l'ho terminato, con l'unico problema che l'elemeto 0,0 (il primo della diagonale maggiore) non viene visualizzato nella stampa del vettore di interi...Potreste gentilmente dare un occhiata al codice e svelarmi l'arcano? °_°

    codice:
    #include <iostream.h>
    #include <cstdlib>
    #define dim 10
    
    using namespace std;
    
    int main ()
    {
    int matrice [dim][dim];
    int vettore[dim];
    int n, i, j, diagonale;
    
    cout<<"Inserire la dimensione della matrice quadrata (massimo 10): ";
    cin>>n;
    cout<<endl;
    cout<<"Inserisci gli elementi della matrice"<<endl;
    for (i=0; i<n; i++)
       for (j=0; j<n; j++){
          cin>> matrice [i][j];
          }
          
    cout<<endl<<endl<<"Stampa della matrice quadrata"<<endl;
    for (i=0; i<n; i++){
       cout<<endl;
       for (j=0; j<n; j++){
          cout<< matrice [i][j];
          }
       }
    cout<<endl<<endl;
    cout<<"Stampa della diagonale maggiore:";
    
    diagonale=0;
    for (i=0; i<n; i++){
       if (j=i) {
         vettore[diagonale]=matrice[i][j];
         diagonale++;
       }
       }
    cout<<endl;
    for (i=0; i<diagonale; i++)
     cout<<vettore[i];   
    cout<<endl<<endl;
       
    system ("PAUSE");
    return 0;
    }
    eseguendolo inserendo per esempio n=2 e gli n*n elementi "1,2,3,4"
    mi stampa:
    12 che sarebbe la matrice
    34

    e mi stampa però solo "4" invece di "1,4" che sarebbero gli elementi completi della diagonale maggiore...
    Mi piacerebbe avere da voi anche un giudizio generale su come ho svolto il codice e qualche consiglio per migliorarlo...
    Grazie infinite a tutti!!!!1

  2. #2
    Codice PHP:
    cout<<"Stampa della diagonale maggiore:";

    diagonale=0;
    for (
    i=0i<ni++){
         
    vettore[diagonale]=matrice[i][i]; // i, i non i, j
         
    diagonale++;
       } 

  3. #3

    Re: [C++] Programma su array multidimensionale

    Originariamente inviato da SongokuSSj5
    Mi piacerebbe avere da voi anche un giudizio generale su come ho svolto il codice e qualche consiglio per migliorarlo...
    1. Non includere <iostream.h> ma <iostream>
    [cite]
    This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
    [/cite]

    2. Non usare "#define dim 10" ma piuttosto "#define MAX_DIM_OF_MATRIX 10", meglio se usi "const int kMaxDimOfMatrix = 10;".

    3. Definisci le variabili solo un attimo prima di utilizzarle; ad esempio "for (int i = 0; i < n; ++i)". Osserva che ho messo anche "++i" anziché "i++". Il primo è generalmente più efficiente del secondo (non in questo caso, ma tant'è..);

    4. Metti sempre un blocco di parentesi graffe nelle strutture di controllo, anche se non è strettamente necessario. Ad esempio:
    Codice PHP:
    for (i=0i<diagonalei++){
     
    cout<<vettore[i];

    Codice PHP:
    for (i=0i<ni++){
       for (
    j=0j<nj++){
          
    cin>> matrice [i][j];
          }

    In questo modo eviterai di picchiare la testa in errori del tipo:
    Codice PHP:
    if (false); // osservare il punto e virgola...
       
    std::cout << "Non dovrebbe MAI stampare questa riga ma invece la stampa!" << std::endl
    4. Spezza le funzionalità in funzioni (senza usare variabili globali). Ad esempio: LoadArrayFromInput, DumpArray ecc..
    5. Rendi dinamiche le dimensioni della matrice.
    6. Utilizza, quando puoi, gli algoritmi standard del C++ che trovi in
    Codice PHP:
    #include <algorithm>
    #include <functional>
    #include <numeric> 

  4. #4
    wow! grazie mille per i preziosissimi consigli!!!!
    Solo una cosa, il programma non va cmq, cioè mi da sempre quell'errore che non stampa il primo elemento della diagonale

    codice:
    cout<<"Stampa della diagonale maggiore:";
     int i,j;
    diagonale=0;
    for (int i=0; i<n; ++i){
       if (j = i) {
         vettore[diagonale]=matrice[i][j];
         ++diagonale;
       }
       }
    cout<<endl;
    for (int i=0; i<diagonale; ++i){
     cout<<vettore[i]<<" "; 
       }

    come mai?

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304

    Re: Re: [C++] Programma su array multidimensionale

    Originariamente inviato da MacApp
    3. Definisci le variabili solo un attimo prima di utilizzarle; ad esempio "for (int i = 0; i < n; ++i)". Osserva che ho messo anche "++i" anziché "i++". Il primo è generalmente più efficiente del secondo (non in questo caso, ma tant'è..);
    Posso chiederti il perchè del punto 3? O meglio:
    Definisci le variabili solo un attimo prima di utilizzarle
    Se ci si riferisce a singole istruzioni come il for, n cui la variabile serve solo come contatore e non più usata in futuro, lo capisco e concordo, ma le altre è preferibile dichiararle subito all'inizio: almeno c'è un solo posto dove andare a cercarle in caso di problemi, senza diventare matti a scorrere tutto il codice.
    Poi, questa parte meriterebbe degli approfondimenti:
    Osserva che ho messo anche "++i" anziché "i++". Il primo è generalmente più efficiente del secondo ...
    Forse è più efficiente, ma ha una semantica completamente differente (a parte il caso specifico che, come da te precisato, non ha effetti di sorta):
    codice:
    i = 0;
    a = i++;
    b = ++i;
    Il risultato, come ci si potrebbe aspettare, non è "a=1", "b=2", ma "a=0", "b=2"... questo perchè il primo si chiama "operatore di post-incremento", mentre il secondo si chiama "operatore di pre-incremento". Nella prima assegnazione, alla variabile "a" viene prima assegnato il valore di i, poi "i" viene incrementato. Nella seconda istruzione, invece, avviene il contrario.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6
    Originariamente inviato da SongokuSSj5
    wow! grazie mille per i preziosissimi consigli!!!!
    Solo una cosa, il programma non va cmq, cioè mi da sempre quell'errore che non stampa il primo elemento della diagonale

    codice:
    cout<<"Stampa della diagonale maggiore:";
     int i,j;
    diagonale=0;
    for (int i=0; i<n; ++i){
       if (j = i) {
         vettore[diagonale]=matrice[i][j];
         ++diagonale;
       }
       }
    cout<<endl;
    for (int i=0; i<diagonale; ++i){
     cout<<vettore[i]<<" "; 
       }

    come mai?
    ti ho risposto tre volte (compresa questa). La soluzione è nel primo post ;-)

  7. #7
    Uh scusami, non mi ero accorto che l'if non serviva :P
    grazie mille!!!

  8. #8

    Re: Re: Re: [C++] Programma su array multidimensionale

    Originariamente inviato da LeleFT
    Posso chiederti il perchè del punto 3? O meglio:
    [cite]
    Citazione:
    Originariamente inviato da MacApp
    "Definisci le variabili solo un attimo prima di utilizzarle"
    [/cite]
    Se ci si riferisce a singole istruzioni come il for, n cui la variabile serve solo come contatore e non più usata in futuro, lo capisco e concordo,
    ma le altre è preferibile dichiararle subito all'inizio: almeno c'è un solo posto dove andare a cercarle in caso di problemi, senza diventare matti a scorrere tutto il codice.
    Completo la mia:
    "Definisci le variabili solo un attimo prima di utilizzarle, e distruggile non appena hai finito d'utilizzarle"
    equivalente a:
    "Limitare il più possibile l'esistenza di variabili".

    La cosa è talmente utile che spesso in C (dove invece è obbligatorio definirle all'inizio di un blocco di graffe), metto dei blocchi extra di graffe proprio per limitare l'esistenza di una variabile.

    Per le seguenti ragioni:
    1. Semantica;
    2. Portabilità/Manuntenzione;
    3. Modularizzazione;
    4. Efficienza.

    1. Semantica:
    Proprio per evitare di dover scorrere il codice per capire dove sia definita e successivamente modificata una variabile. Similmente per le stesse ragioni per cui è meglio limitare (anzi escludere) l'utilizzo delle variabili globali.

    2. Portabilità/Mantenibilità:
    Portando il codice da un sistema operativo all'altro, da un compilatore all'altro, da una versione dello stesso programma all'altro, se ad esempio devi cambiare il tipo di una variabile nella chiamata di una funzione, le modifiche sono localizzate solo nell'intorno del codice di dove avviene appunto la chiamata alla funzione modificata.

    3. Modularizzazione:
    Mi accorgo che ciò che sto scrivendo può essere trasformato in una funzione, magari riutilizzabile altrove? Taglio il codice che sto scrivendo, lo funzionalizzo, senza inficiare il resto del programma.

    4. Efficienza:
    Ad esempio confronta le due funzioni:
    Codice PHP:
    void TestVariabileAdInizioBlocco (){
        
    QualunqueTipo a;
        for (
    int i 0N; ++i){
            
    GetObject (i); // Funzione che in base ad i restituisce un oggetto di tipo QualunqueTipo;
            
    a.DumpObject (); // Metodo della classe QualunqueTipo che stampa su file di log se stessa.
            
    HandleObject (a); // Funzione che fa qualcosa con l'oggetto di tipo a.
        
    }
    }

    void TestVariabileLimitata (){
        for (
    int i 0N; ++i){
            
    QualunqueTipo a GetObject (i); // Funzione che in base ad i restituisce un oggetto di tipo QualunqueTipo;
            
    a.DumpObject (); // Metodo della classe QualunqueTipo che stampa su file di log se stessa.
            
    HandleObject (a); // Funzione che fa qualcosa con l'oggetto di tipo a.
        
    }

    Sbagliando si potrebbe pensare che TestVariabileAdInizioBlocco sia più efficiente di TestVariabileLimitata, perché la variabile locale viene definita una volta sola, mentre in TestVariabileLimitata viene definita N volte.
    Ma.. in TestVariabileAdInizioBlocco, quando si assegna a "a = GetObject (i)" cosa accade? Viene chiamato l'operatore = della classe QualunqueTipo, che normalmente ha un codice equivalente (non condiviso) ad il suo distruttore + il costruttore di copia.
    Quindi per la classe QualunqueTipo siamo obbligati a definire il costruttore senza argomenti, il costruttore di copia, l'operatore = che contiene codice equivalente (ma non condiviso) al distruttore ed al costruttore di copia, il distruttore.
    In totale quindi in TestVariabileAdInizioBlocco vengono chiamati: Una volta il costruttore senza argomenti, N volte l'operatore = che equivale ad N chiamate del distruttore ed N chiamate del costruttore di copia, e finalmente una sola volta il distruttore.
    Osserva che l'operatore = non potendo condividere lo stesso codice del costruttore di copia e del suo distruttore, deve essere mantenuto separatamente. Quindi se modifico il costruttore di copia, devo modificare anche l'operatore = ecc..

    Invece in TestVariabileLimitata, non ho la necessità di definire il costruttore senza argomenti e neppure l'operatore = per la classe QualunqueTipo, viene chiamato N volte il costruttore di copia, ed N volte il suo distruttore.

    Riepilogando nel primo caso devo per la classe QualunqueTipo:
    - definire il costruttore senza argomenti;
    - definire l'operatore = che ha codice equivalente (non condiviso) al codice del suo distruttore + il suo costruttore di copia;
    - definire il costruttore di copia;
    - definire il distruttore;

    Nel secondo invece basta:
    - definire il costruttore di copia;
    - definire il distruttore;

    Aggiungiamoci anche che nel secondo caso se (com'è probabile che sia) il metodo DumpObject è costante, ed HandleObject vuole solo un const QualunqueTipo, possiamo scrivere anche "const QualunqueTipo a = GetObject (i);"

    Non solo... il corpo del for voglio trasformarlo in una funzione? Nel primo caso devo anche cancellare la definizione ad inizio blocco (e magari mi dimentico di farlo).

    Insomma devo scrivere meno codice, riduco possibili errori di sincronia tra funzioni, ed in più il risultato è più efficiente.
    Meglio di così?

    ;-)
    "

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.