Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
DJI Romo 2: tante novità lo rendono un robot completo
DJI Romo 2: tante novità lo rendono un robot completo
Romo 2 è la seconda generazione di robot lavapavimenti di DJI, un modello che si caratterizza per la precisione nel sistema di navigazione e per il funzionamento particolarmente silenzioso. Con le modifiche introdotte in questa seconda versione, e un posizionamento di prezzo più allineato alla concorrenza, rappresenta una valida alternativa sul mercato delle soluzioni di pulizia domestica
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Il primo Sony con retroilluminazione True RGB alla prova del banco di misura e dei contenuti: luminanza enorme, colori accurati in HDR e un antiriflesso molto efficace. I limiti sono due sole HDMI 2.1 e il blooming fuori asse
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 18-03-2006, 15:06   #1
FagioloOne
Member
 
L'Avatar di FagioloOne
 
Iscritto dal: Sep 2005
Città: Venezia
Messaggi: 160
[c++]array bidimensionali

Sono un programmatore autodidatta perciò se il problema è stupido, o dovuto alla mia ignoranza mi scuso già in precedenza.

Devo creare una funzione che dato un determinato array me lo ridia indietro modificato, come unico valore qualcuno mi sa aiutare. Il mio libro non spiega un bel niente e tutte le mie prove con i puntatori sono stati infruttuose, grazie in anticipo per le vostre eventuali risposte.
FagioloOne è offline   Rispondi citando il messaggio o parte di esso
Old 18-03-2006, 18:14   #2
Ziosilvio
Moderatore
 
L'Avatar di Ziosilvio
 
Iscritto dal: Nov 2003
Messaggi: 16215
Non ti sei spiegato molto bene.
Devi manipolare i valori delle componenti di un array bidimensionale?
Oppure devi ottenere un singolo valore, che in qualche modo ti rappresenta l'intero array (ad esempio: una stringa hash)?

Comunque, visto che parli di array bidimensionali... si possono fare, con un trucco.
Quando tu dichiari, ad esempio, "int m[5][6]", m è un array (statico) di 5 array (statici) a 6 componenti intere. Tu vuoi riprodurre questo comportamento con i puntatori, in modo da poter allocare la matrice in modo dinamico.

La prima difficoltà sta nel capire il tipo giusto.
Se m fosse un array di int, e tu lo passassi a una funzione, esso verrebbe convertito in un puntatore di tipo int* (al suo primo elemento): ma dato che m è un array di array, dovrebbe essere convertito in un puntatore ad array di int anziché ad int. Effettuando un'altra conversione, viene fuori che m deve diventare un puntatore a puntatore a int.

Adesso che hai capito che tipo di oggetto devi trattare, devi capire come farlo.
Anzitutto, devi allocare la memoria giusta: se la matrice ha rows righe e cols colonne, allora è chiaro che dovrai allocare prima un vettore di rows vettori di int, e poi rows vettori di cols int.
Ad esempio:
Codice:
int **matrix_alloc(int rows, int cols)
{
    int i, **p;

    p = (int**)malloc(rows*sizeof(int*));
    if (p==NULL)
        return NULL;
    for (i=0; i<rows; i++)
    {
        p[i] = (int*)malloc(cols*sizeof(int));
        if (p[i]==NULL) break;
    }
    if (i<rows) /* l'inizializzazione della riga i-esima e' fallita */
    {
        for (--i; i>=0; i--)
            free(p[i]);
        free(p);
        return NULL;
    }
    return p;
}
Nota la sintassi di inizializzazione delle righe: dato che p è un puntatore, p[i] ha lo stesso significato di *(p+i). Questo torna utile quando devi scrivere i valori delle componenti della matrice:
Codice:
m[i][j] = my_expr();
Per deallocare, liberi prima le singole righe, e poi il vettore:
Codice:
void matrix_dealloc(int **p, int rows)
{
    int i;

    for (i=0; i<rows; i++)
        free(p[i]);
    free(p);
}
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" Chi scherza col fuoco si brucia.
Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici
REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu
Ziosilvio è offline   Rispondi citando il messaggio o parte di esso
Old 18-03-2006, 19:49   #3
wingman87
Senior Member
 
Iscritto dal: Nov 2005
Messaggi: 2794
Ho sentito dire che la memoria va disallocata nell'ordine inverso a quello in cui la si è allocata, un po' come fa il tuo programma quando dice "l'inizializzazione della riga i-esima e' fallita".
Non so spiegarti bene il perchè ma da quel che ho capito quando disallochi la memoria parte dal puntatore che gli dai fino alla fine+1, andando a fare un casino poi nei puntatori successivi.
wingman87 è offline   Rispondi citando il messaggio o parte di esso
Old 18-03-2006, 20:14   #4
mr_hyde
Senior Member
 
Iscritto dal: Oct 2005
Città: Genova
Messaggi: 937
anche io non ho capito benissimo la domanda.
Parli di C++ (quindi classi, ereditarieta', eccezioni...) e array.
Hai bisogno di una funzione che modifichi un array.

Da quanto dici immagino che l'array esista gia' e tu non lo debba creare (in caso contrario ti e' gia' stato spiegato come fare, anche se, in C++, e' meglio usare new[], delete [] e try/catch(std::bad_alloc)).

Immagino quindi diverse possibilita':
1) hai una CLASSE che implementa il tipo di dato array (e, dal titolo del tuo thread, immagino array bidimensionale)

In questo caso, dovresti creare una funzione del tipo

void Mastrussa(CMatrix& mat)
{
[...]
funzioni varie che elaborano e modificano "mat"
}

Nota che in realta' si passa il reference dell'istanza di una classe: e' questo che ti permette di "cambiare" all'interno della funzione il parametro, pe meglio dire NON viene creata una copia del parametro ma elaborato DIRETTAMENTE il parametro passato.

Al termine della funzione "mat" sara' restituita al chiamante modificata.

2) tu hai gia' una classe che implementa la matrice e vuoi aggiungere un metodo che elabori i dati in essa contenuti e restituisca un qualche risultato su questi, ad esempio per il calcolo del deteminante di una matrice

Allora dovresti avere una cosa del tipo

class CMatrix
{
[...]
public:
double determinante() const
throw(std::runtime_error);

dove:
1 - "const" si ha perche' il calcolo del determinante non porta ad alcuna modificazione dei dati interni della matrice;
2 - la throw e' per comunicare al chiamante eventuali errori (ad esempio nel caso in cui si sia chiesto il determinante di una matrice NON quadrata)

e quindi dovresi implementare la funzione:

double CMatrix::determinante const
{
if (this->rows() != this->columns())
throw std::runtime_error("Matrice non quadrata, determinante impossibile");

// calcolail determinante
}

In questo caso puoi avere il determinate della matrice come:

CMatrix mat;

// popola mat in qualche modo

double det;
try
{
det = mat.determinante();
std::cout << "Determinante = " << det << std::endl;
}
catch (const std::exception& e)
{
std::cerr << "Impossbile calcolare il determinante - " << e.what() << std::endl;
}

Se invece la tua funzione deve cambiare in qualche modo i dati della matrice la funzione non dovra' essere const, ad esempio
/**
* \brief Inverte la matrice
*
* \throw std::runtime_error in caso di errori
*/
void inverti() throw(std::runtime_error);

E il codice per la chiamata:

CMatrix mat;

try
{
mat.inverti();
std::cout << "Matrice inversa: " << std::endl << mat << std::endl;
}
catch (const std exception& e)
{
std::cerr << "Impossibile invertire matrice - " << e.what() << std::endl;
}

3) (caso comune al C)
hai un array bidimensionale e devi creare una funzione che ne cambi i valori.
In questo caso, visto che in realta' per passare un array devi passare un puntatore, tu passi gia' i valori "per reference" (be', in realta' passare un puntatore e' il modo del C per implementare il passaggio di parametri per reference), quindi modifichi gia' la matrice

Un ultima cosa:
per gli array monodimensionali in C e' lecito scrivere

void funzione(int the_array[])

ovvero indichi alla funzione che trattera' un array ma non specifichi le dimensioni

Per i bi-dimensionali invece NON e' possibile scrivere

void funzione(int the_matrix[][])

Devi indicare almeno una delle dimensioni (mi sembra la seconda, ma non ricordo bene). Immagiono che questo limite sia dovuto a come vengono memorizzate in C le matrici in un unico blocco di memoria contiguo...

Ciao,
Mr Hyde
__________________
MacMini Late 2009/MacMini 2018
mr_hyde è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Geely EX5, un mese al volante: il SUV elettrico cinese che ci ha sorpreso (quasi) senza riserve Geely EX5, un mese al volante: il SUV elettrico ...
Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare Mova Z70 Ultra Roller Complete: motore potente, ...
Valve apre le prenotazioni di Steam Fram...
ECOVACS T50 OMNI Gen3 a 379€: il riferim...
Netflix e Sega insieme: arrivano i film ...
Veeam ottiene la certificazione da parte...
XIAOMI Redmi Buds 8 a 37,94€: auricolari...
Il fotovoltaico scende sott'acqua: nuove...
Microsoft chiede supervisione umana nell...
MicroSD Samsung T9 da 256GB a 65,88€: sc...
Una RTX 3090 e nessuna riga di codice: Q...
Windows e Excel di nuovo nel caos dopo i...
Nuovi Samsung Galaxy S26 FE ora disponib...
EU Kids Act: una legge per riscrivere l'...
IonQ annuncia Superion 256, un computer ...
Tesla Semi arriva in Europa: fino a 500 ...
realme 16 Pro Harry Potter Edition &egra...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 11:26.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v