Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare
Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare
Realizzato da Lenovo e installato presso il Cineca di Casalecchio di Reno, Pitagora offre circa 44 PFlop/s di potenza di calcolo ed è dedicato alla simulazione della fisica del plasma e allo studio dei materiali avanzati per la fusione, integrandosi nell’ecosistema del Tecnopolo di Bologna come infrastruttura strategica finanziata da EUROfusion e gestita in collaborazione con ENEA
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA
Rullo di lavaggio dei pavimenti abbinato a un potente motore da 28.000 Pa e a bracci esterni che si estendono: queste, e molte altre, le caratteristiche tecniche di Z60 Ultra Roller Complete, l'ultimo robot di Mova che pulisce secondo le nostre preferenze oppure lasciando far tutto alla ricca logica di intelligenza artificiale integrata
Renault Twingo E-Tech Electric: che prezzo!
Renault Twingo E-Tech Electric: che prezzo!
Renault annuncia la nuova vettura compatta del segmento A, che strizza l'occhio alla tradizione del modello abbinandovi una motorizzazione completamente elettrica e caratteristiche ideali per i tragitti urbani. Renault Twingo E-Tech Electric punta su abitabilità, per una lunghezza di meno di 3,8 metri, abbinata a un prezzo di lancio senza incentivi di 20.000€
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 01-06-2006, 12:16   #1
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
[C++] ancora su puntatori ad indirizzi, * e &

se ho una funzione

void esempio(double *x) {

double i;
double numero=7;

for (i = 0; i<numero; i++) {
*(x+i)=i;
}

} //end function



se nel main attivo


double test[7];
esempio(&test[0]);


alla fine avrò:

test[0]=0;
test[1]=1;
test[2]=2;
test[3]=3;
test[4]=4;
test[5]=5;
test[6]=6;



domanda:
ma...se io NON so a priori il ciclo for dentro la funzione quante volte verrà attivato (al posto del "numero=7" ho un valore che saprò solo durante lo svolgimento della funzione).Ebbene:
poichè nel main ho definito

double test[7];
ovvero è come se avessi detto (tanto per capire)
test[numero]; visto che numero=7

come faccio?
io num non lo so.

se la funzione mi "spara" numero=12
che ne so io a priori da scrivere nel listato
double test[12];


come risolvo?

cioè come faccio a apssare alla funzione l'indirizzo del primo elemento di un array di cui però non ho idea di quanti elementi avrà l'array e quindi non posso definirlo a priori?

oppure c'è un altro metodo?

insoma io devo costruire un array dentro una funzione, atrray che sarà poi visibile come variabile globale nel main e di cui non so quanto deve essere grosso a priori ma solo durante lo svolgimento della function stessa.
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 01-06-2006 alle 12:39.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 13:00   #2
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
se ho una funzione

void esempio(double *x) {

double i;
double numero=7;

for (i = 0; i<numero; i++) {
*(x+i)=i;
}

} //end function



se nel main attivo


double test[7];
esempio(&test[0]);


alla fine avrò:

test[0]=0;
test[1]=1;
test[2]=2;
test[3]=3;
test[4]=4;
test[5]=5;
test[6]=6;
Ok, non fa una piega. Io userei solo l'indice del for di tipo intero e poi userei x[i] invece di *(x+i), che comunque sarebbe la stessa cosa.

Quote:
Originariamente inviato da vermaccio
domanda:
ma...se io NON so a priori il ciclo for dentro la funzione quante volte verrà attivato (al posto del "numero=7" ho un valore che saprò solo durante lo svolgimento della funzione).Ebbene:
poichè nel main ho definito

double test[7];
ovvero è come se avessi detto (tanto per capire)
test[numero]; visto che numero=7

come faccio?
io num non lo so.

se la funzione mi "spara" numero=12
che ne so io a priori da scrivere nel listato
double test[12];


come risolvo?

cioè come faccio a apssare alla funzione l'indirizzo del primo elemento di un array di cui però non ho idea di quanti elementi avrà l'array e quindi non posso definirlo a priori?

oppure c'è un altro metodo?

insoma io devo costruire un array dentro una funzione, atrray che sarà poi visibile come variabile globale nel main e di cui non so quanto deve essere grosso a priori ma solo durante lo svolgimento della function stessa.
Questo non è molto chiaro. Se una funzione deve operare su un array, deve almeno sapere, in qualche modo, quanti elementi contiene!!! Devi allocare dinamicamente l'array??? E poi cosa significa "visibile come variabile globale nel main"???
Spiega meglio cosa vorresti fare.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 13:05   #3
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
la situazione è questa: devo creare tramite un function un array bidimensionale nX2 (una matrice di 2 righe e n colonne).

iquesta matrice, una volta chiusa la funziona che la crea, deve esere visibile da altre funzioni che si attiveranno in seguito. quiandi la "matrice" deve essre una variabile globale.

il problem è che finchè la funzione creatirce non si attiva non saprò quante colonne "n" avrà la matrice.

quindi la domanda è:

data una function che al suo interno "dichiara" il numero di colonne......

come faccio nel main a dichiarare una variabile globale in cui mettere i dati della matrice?

qualsiasi soluzione va bene.


quindi
1)si attiva la funzione
2)nella funzione vine e detto, in base al suo scopo, che n=qualcosa (es:21) che varia ad ogni chiamata
3)viene riempita una matrice 2Xn
4)la funzione si chiude

come fare per avere fuori della funzione, una volta chiusa, quella matrice o un qualcosa del genere che contenga i dati della matrice?
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 13:45   #4
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Io farei così:
Codice:
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    double **array;
    int rows;
    int columns;
} DOUBLE_2D;

DOUBLE_2D alloc_double_2d (int rows, int columns)
{
    int i;
    DOUBLE_2D double2d;

    double2d.array = (double**) malloc (rows * sizeof (double*));

    for (i = 0; i < rows; i++)
        double2d.array[i] = (double*) malloc (columns * sizeof (double));

    double2d.rows = rows;
    double2d.columns = columns;

    return double2d;
}

void free_double_2d (DOUBLE_2D *double2d)
{
    int i;

    for (i = 0; i < double2d->rows; i++)
        free (double2d->array[i]);

    free (double2d->array);

    double2d->array = NULL;
    double2d->rows = 0;
    double2d->columns = 0;
}


DOUBLE_2D tua_funzione (void)
{
    int n = 21;
    DOUBLE_2D double2d;

    /* .... */

    double2d = alloc_double_2d (2, n);

    return double2d;
}


int main (void)
{
    DOUBLE_2D arr;

    arr = tua_funzione ();

    free_double_2d (&arr);

    return 0;
}
Sull'utilizzo del puntatore ** per gestire delle matrici bidimensionali, se n'era già parlato in <questo> thread.
Come avevo detto io, un array di questo tipo non è esattamente un array come inteso dal linguaggio "C". Perché i dati non sono tutti contigui in memoria, in pratica così è semplicemente "un array di array".
Ma in molti casi va bene, non frega niente se non è contiguo ma solo se la dimensionalità è uguale 2.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 14:16   #5
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
mumble.. mumble...
quindi usi una struttura!
grande idea!

A)
DOUBLE_2D alloc_double_2d
alloca e crea la "matrice" rowXcolumns

B)
void free_double_2d (DOUBLE_2D *double2d)
cancella e dealloca la memoria occupata dalla matrice rowXcolumns prima creata

C)
DOUBLE_2D tua_funzione (void)
qui dentro richiamo la A per creare la matrice rowXcolumns in base ai valori row e columns che qui dentro vengono definiti

D)
ne main
free_double_2d (&arr);
uccide quella matrice.

domanda1:
------------
ma se non la uccido viene sovrascritta oppure rimane ad occupare memoria perchè la successiva chiamata della funzione A crea un altra matrice ma quella "vecchia" è ancora li ma senza puntatore per usarla? quindi se non cancello ogni volta la matrice creata alla lunga la memoria si riempie?

domanda2:
-----------
nella A

double2d.array = (double**) malloc (rows * sizeof (double*));
alloca la memoria necessaria per le row righe ognuna avente columns colonne. ma che significa "**" nel double?

domanda3:
-----------
sempre nella A:
for (i = 0; i < rows; i++)
double2d.array[i] = (double*) malloc (columns * sizeof (double));
riempie i campi dell'array.



domanda4:
------------
nel main
int main (void)
{
DOUBLE_2D arr; /definisco la "variabile" globale arr! ma non si sa ancora quanto è grande l "array" la dentro!

arr = tua_funzione ();
qui dentro riempio la variabile arr dopo averne definito il contenuto. visto che la arr è globale ogni modifica sarà visibile ancora dopo aver chiuso chiuso la funzione tua_funzione.

free_double_2d (&arr);
ammazzo la arr ora creata

return 0;
}


tutto ok?




ps: ci speravo fossi tu a rispondere al mio quesito! sei il mio micio preferito!
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 15:00   #6
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
ma se non la uccido viene sovrascritta oppure rimane ad occupare memoria perchè la successiva chiamata della funzione A crea un altra matrice ma quella "vecchia" è ancora li ma senza puntatore per usarla? quindi se non cancello ogni volta la matrice creata alla lunga la memoria si riempie?
Esatto, rimane lì allocata senza che il programma abbia dei riferimenti a quelle locazioni.

Quote:
Originariamente inviato da vermaccio
nella A

double2d.array = (double**) malloc (rows * sizeof (double*));
alloca la memoria necessaria per le row righe ognuna avente columns colonne. ma che significa "**" nel double?

sempre nella A:
for (i = 0; i < rows; i++)
double2d.array[i] = (double*) malloc (columns * sizeof (double));
riempie i campi dell'array.
La struttura di un tale array è la seguente:

In pratica è "un array di array". C'è un primo array che contiene dei puntatori agli array della seconda dimensione. Ecco perché serve allocare prima un array delle righe che contengono double* e poi per ogni riga allocare un array di N elementi double.

double** perché solo così si può fare: double2d.array[r][c]

Quote:
Originariamente inviato da vermaccio
nel main
int main (void)
{
DOUBLE_2D arr; /definisco la "variabile" globale arr! ma non si sa ancora quanto è grande l "array" la dentro!

arr = tua_funzione ();
qui dentro riempio la variabile arr dopo averne definito il contenuto. visto che la arr è globale ogni modifica sarà visibile ancora dopo aver chiuso chiuso la funzione tua_funzione.

free_double_2d (&arr);
ammazzo la arr ora creata

return 0;
}
arr non è globale! È una variabile locale del main. Se la vuoi globale la metti fuori dalle funzioni. La tua_funzione restituisce una copia della struttura, che viene quindi assegnata ad arr.

Quote:
Originariamente inviato da vermaccio
ps: ci speravo fossi tu a rispondere al mio quesito! sei il mio micio preferito!
miaaao!
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 15:10   #7
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
usi operativi della matrice "double2d" rowXcolumns:

1)
nella funzione
DOUBLE_2D tua_funzione (void)
se
row=2
columns=21

e se volessi settare gli elementi come faccio?
con un ciclo for.
ma come setto UN elemento dentro il ciclo for?

per dire che voglio che l'elemento riga 2, colonna 8 sia un double uguale a 999, come scrivo?

[tra parentesi: la numerazione va da 0 in poi per gli elementi?]


2)
e invece nel main se voglio leggere
l'elemento riga2 e colonne 12 di double2d ed assegnarlo alla variabile "double estratto;"?


3)
se devo passare ad un altra funzione la matrice bidimensionale, come gliela passo?
cioè se ho:

void altra_funzione (DOUBLE_2D interna) {
...
blabla
...
}

la richiamo dal main con
altra_funzione (double2d);
?
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 15:25   #8
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
1)
nella funzione
DOUBLE_2D tua_funzione (void)
se
row=2
columns=21

e se volessi settare gli elementi come faccio?
con un ciclo for.
ma come setto UN elemento dentro il ciclo for?

per dire che voglio che l'elemento riga 2, colonna 8 sia un double uguale a 999, come scrivo?
Se hai dichiarato un DOUBLE_2D arr devi usare arr.array[r][c].

Quote:
Originariamente inviato da vermaccio
[tra parentesi: la numerazione va da 0 in poi per gli elementi?]
Sì.

Quote:
Originariamente inviato da vermaccio
2)
e invece nel main se voglio leggere
l'elemento riga2 e colonne 12 di double2d ed assegnarlo alla variabile "double estratto;"?
Vedi sopra. Esempio: arr.array[2][12].

Quote:
Originariamente inviato da vermaccio
3)
se devo passare ad un altra funzione la matrice bidimensionale, come gliela passo?
cioè se ho:

void altra_funzione (DOUBLE_2D interna) {
...
blabla
...
}

la richiamo dal main con
altra_funzione (double2d);
?
Esatto, così la passi "per valore" (passi una copia della struttura) ma la puoi passare anche tramite un puntatore. Dipende da cosa fa più comodo.
Nota: in ANSI "C" è permesso passare/ritornare strutture per valore.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 15:30   #9
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
A2)

(quesito3)

se NON voglio passarla per valore ma per qualcosa=indirizzo?

nel main la richiamo con
altra_funzione (&arr[0][0]);
?

e dentro la funzione
void altra_funzione (DOUBLE_2D* interna) {
con dentro la funzione cose del tipo

-->per assegnare
(*interna)=qualcosa; per modificare il primo elemento
e
(*interna+column+row*column)=qualcosa; per modificare l'elemento alla posizione row,column?

-->per leggere
qualcosa=(*interna);
e
qualcosa=(*interna+column+row*column);


???

B2)

inoltre essendo una variabile del main posso comunque evitare questa paranoia ed usare direttamente
definire

void altra_funzione2 (altre cose) {


e chiamarla con
altra_funzione2 (...);
al cui interno faccio diretamente
arr.array[row][column]=qualcosa;
e
qualcosa=arr.array[row][column];

???
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 01-06-2006 alle 15:40.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 16:03   #10
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
A2)

(quesito3)

se NON voglio passarla per valore ma per qualcosa=indirizzo?

nel main la richiamo con
altra_funzione (&arr[0][0]);
?

e dentro la funzione
void altra_funzione (DOUBLE_2D* interna) {
con dentro la funzione cose del tipo

-->per assegnare
(*interna)=qualcosa; per modificare il primo elemento
e
(*interna+column+row*column)=qualcosa; per modificare l'elemento alla posizione row,column?

-->per leggere
qualcosa=(*interna);
e
qualcosa=(*interna+column+row*column);
Per passarla:
altra_funzione (&arr);

arr è una struttura, NON il double** (che è invece contenuto all'interno della struttura).

nella funzione si userà quindi:

interna->array[r][c] = ....;

... = interna->array[r][c];

Quote:
Originariamente inviato da vermaccio
B2)

inoltre essendo una variabile del main posso comunque evitare questa paranoia ed usare direttamente
definire

void altra_funzione2 (altre cose) {


e chiamarla con
altra_funzione2 (...);
al cui interno faccio diretamente
arr.array[row][column]=qualcosa;
e
qualcosa=arr.array[row][column];
Sì, ma solo se arr è globale, cioè dichiarato fuori dalle funzioni.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 16:07   #11
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
Quote:
Originariamente inviato da andbin
Per passarla:
altra_funzione (&arr);

arr è una struttura, NON il double** (che è invece contenuto all'interno della struttura).

nella funzione si userà quindi:

interna->array[r][c] = ....;

... = interna->array[r][c];
quindi così come per gli array passati per indirizzo (con la &) chiamando la funzione io faccio *(array+cella)

per una struttura passta con la & io faccio

struttura->campo[x][y]
se campo è un array bidimensionale.

Quote:
Originariamente inviato da andbin
Sì, ma solo se arr è globale, cioè dichiarato fuori dalle funzioni.

ok. è il mio caso. quindi invece di impazzirmi con passaggi "&" e le conseguenti "->" faccio prima così.
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 01-06-2006 alle 16:10.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 16:27   #12
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
FACCIAMOCI DEL MALE!!!!!!

sempre più contorto


sino ad ora abbiamo chiarito come creare e riempire una struttura con dentro un array bidimensionale le cui dimensioni sono decide dentro una funzione che poi la riempie anche.
Però si è dato per scontato che la funzione "decida" row e columns una volta per tutte, poi crea l'array rowXcolmns e lo riempie.


che fare nel caso in cui la funzione solo alla fine saprà columns MA (dolore!) a mano a mano che aggiunge columns deve salvare i dati?

esempio:
sono ad occhi chiusi in una stanza piena di sedie.
apro gli occhi e mano mano che giro su me stesso (sino a fare un giro completo di 360°) per ogni 10gradi di rotazione conto quante sedie vedo davanti a me.
alla fine columns=numero sedie viste.
Però nell'array bidimensionale devo stoccare, per ogni colonna:
riga1=numero totali gambe delle sedie che vedo in quel momento
riga2=numero totali delle sedie che vedo

io creo una nuova colonna solo se nel punto di osservazione istantaneo vedo sedie.
se non ne vedo non faccio nulla a ruotoun altro po.

se ad esempio ho solo 1 sedia alla mia sinistra ,due dietro, e una a destra: io avrò tre colonne.

4 8 4
1 2 1

con il metodo prima visto io avrò ALLA FINE columns=3
e creo array 2X3 e lo riempio...
ma...
con cosa?
io devo riempirlo MENTRE giro (quando non so che alla fine columns=3), NON a giro finito (quando so columns=3)!

quindi devo riempire a mano a mano la struttura senza sapere quanto è grossa!

una soluzione è far si che nella function:
1)giro su me stesso
2)a mano a mano stocco dati dentro un altra entità locale
3) a fine giro so il numero colonne
4)creo struuttura esterna come detto in tutto il resto del thread
5)copio valori da entità locale e struttura esterna


ma..
entità=????

siamo da capo:
che uso per stoccare dati a mano a mano senza sapere quanti saranno alla fine???????????
arghhhhhhhh!
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII

Ultima modifica di vermaccio : 01-06-2006 alle 16:31.
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 16:53   #13
andbin
Senior Member
 
L'Avatar di andbin
 
Iscritto dal: Nov 2005
Città: TO
Messaggi: 5206
Quote:
Originariamente inviato da vermaccio
sempre più contorto


sino ad ora abbiamo chiarito come creare e riempire una struttura con dentro un array bidimensionale le cui dimensioni sono decide dentro una funzione che poi la riempie anche.
Però si è dato per scontato che la funzione "decida" row e columns una volta per tutte, poi crea l'array rowXcolmns e lo riempie.


che fare nel caso in cui la funzione solo alla fine saprà columns MA (dolore!) a mano a mano che aggiunge columns deve salvare i dati?
Ci sono diverse soluzioni.

Non puoi creare una volta sola un array di dimensioni "ragionevolmente" grandi in modo che ti vada bene???
Se questa soluzione non ti piace, non ti va bene o non ti basta, si può fare in un altro modo: creare una apposita funzione di riallocazione dell'array. Come gestire la riallocazione dell'array ... bisogna vedere. Il problema è questo: se ogni volta che devi aggiungere 1 elemento, allarghi le colonne dell'array ... credo che il tuo programma passerà più tempo a fare (ri)-allocazioni che altro!

Comunque ci penso un attimo. Risistemo il codice che avevo postato mettendo magari anche la gestione degli errori ... e poi riposto il codice.
__________________
Andrea, SCJP 5 (91%) - SCWCD 5 (94%)
andbin è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 17:07   #14
mind_
Member
 
L'Avatar di mind_
 
Iscritto dal: Apr 2006
Città: Trieste
Messaggi: 141
Quote:
Originariamente inviato da andbin
Ci sono diverse soluzioni.

Non puoi creare una volta sola un array di dimensioni "ragionevolmente" grandi in modo che ti vada bene???
Se questa soluzione non ti piace, non ti va bene o non ti basta, si può fare in un altro modo: creare una apposita funzione di riallocazione dell'array. Come gestire la riallocazione dell'array ... bisogna vedere. Il problema è questo: se ogni volta che devi aggiungere 1 elemento, allarghi le colonne dell'array ... credo che il tuo programma passerà più tempo a fare (ri)-allocazioni che altro!

Comunque ci penso un attimo. Risistemo il codice che avevo postato mettendo magari anche la gestione degli errori ... e poi riposto il codice.
Non ho letto tutta la discussione, in ogni caso puoi usare vector<class T> della libreria standard. E' un vettore che si espande da solo ed è ottimizzato per usi generali. In questi casi di solito si alloca un quantità ragionevolmente grande che si provvede ad espandere quando serve. Puoi anche allocare il minimo indispensabile ma questo comporta un notevole sovraccarico per la cpu che si può evitare a costa di (poca) memoria.
Saluti
mind_ è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 17:28   #15
vermaccio
Senior Member
 
L'Avatar di vermaccio
 
Iscritto dal: Sep 2001
Città: Roma
Messaggi: 2141
Quote:
Originariamente inviato da mind_
Non ho letto tutta la discussione, in ogni caso puoi usare vector<class T> della libreria standard. E' un vettore che si espande da solo ed è ottimizzato per usi generali. In questi casi di solito si alloca un quantità ragionevolmente grande che si provvede ad espandere quando serve. Puoi anche allocare il minimo indispensabile ma questo comporta un notevole sovraccarico per la cpu che si può evitare a costa di (poca) memoria.
Saluti

puoi postare un esempietto pratico?

comunque non posso permettermi sovraccarichi di cpu: il codice cpp una volta lanciato lancia altre applicazioni e già così un AMD2600+ fa fatica a stargli dietro.
e se la simulazione inizia a "scattare" è la fine!

preferisco sprecare memoria che avere sovraccarichi di cpu.

credo che la soluzione "a spanne" di creare un entità di appoggio sovrabbondante sia valida.
ad esempio
double entità[2][100];
magari nel 99% dei casi ne riempirò solo le prima 5 colonne.
a 100 non arriverà MAI.
__________________
..strisc...strisc...oooooOOoooO
http://digilander.iol.it/pentiumII Navi da battaglia giapponesi classe Yamato WWII
vermaccio è offline   Rispondi citando il messaggio o parte di esso
Old 01-06-2006, 23:02   #16
mr_hyde
Senior Member
 
Iscritto dal: Nov 2005
Città: Genova
Messaggi: 937
Per quanto riguarda l'esempio scemo sull'uso del vector<T> eccoti questa cavolata:

Codice:
#include <vector>
#include <iostream>




void stampaAllaC(const std::vector<int>& arr)
{
	unsigned int i;

	for (i = 0; i < arr.size(); i++)
	{
		std::cout << "vettore[" << i << "] = " << arr[i] << std::endl;
	}

}

void stampaAllaCPP(const std::vector<int>& arr)
{
	std::vector<int>::const_iterator it;

	for (it = arr.begin(); it != arr.end(); ++it)
	{
		std::cout << *it << std::endl;
	}
}


int main()
{
	const int minLimit = 0;
	const int maxLimit = 200;

	int i;

	std::vector<int> vect;

	for (i = minLimit; i <= maxLimit; i++)
	{
		if ((i % 3) == 0)
		{
			vect.push_back(i);
		}
	}

	std::cout << "Alla fine gli elementi nel vettore sono " << vect.size() << std::endl;

	// puoi recuperare i dati con l'operatore [] come si fa in C
	stampaAllaC(vect);

	// oppure usare gli iteratori
	stampaAllaCPP(vect);

	return 0;
}
La potenza dei contenitori della Standard Template Library consiste nel fatto che:
1) li puoi usare non solo con i tipi "standard" (int come in questo caso, long, float, car ecc ecc) ma anche con tipi definiti da te (unica accortezza: per certi contenitori devi definire l'ogetto da memorizzare come una classe che abbia l'operatore di assegnazione (operator=), il costruttore di defult, il costruttore di copia e l'operatore di ordinamento < (operator<)
2) qui ho usato un "vector" che era quello che ti era gia' stato nominato: in realta' ne esistono numerosi altri (map, set...)

Uno che trovo molto utile e' la map<KEY,VAL> che e' un contenitore associativo.
Ti permette di associare una chiave (di qualsiasi tipo, anche definito da te) ad un valore da memorizzare (di qualsiasi tipo, anche definito da te).

Ad esempio se hai

Codice:
std::map<std::string, float> coeff; // creo una mappa vuota
puoi memorizzare i coefficienti per la conversione in metri cosi';

Codice:
// inizio a popolare la mappa
coeff[std::string("metro")] = 1.0;
coeff[std::string("kilometro")] = 1000.0;
coeff[std::string("decimetro")] = 0.1;
e anche qui hai a disposizione gli operatori per stampare il contenuto della mappa senza sapere quanti elementi ne fanno parte.

3) i contenitori hanno gia' operazioni quali ad esempio l'ordinamento, l'operatore di copia (quindi puoi copiare tutto un vettore semplicemente usando il carattee "=")

4) tramite i connettori (ma questo per favore non farmelo spigare) puoi "applicare" diverse operazioni su ogni elemento del contenitore senza scrivere il solito ciclo per scorrere tutti gli elementi presenti nel contenitore

5) come gia' detto prima gli elementi e le chiavi possono essere di qualsiasi tipo.
Questo permette anche di memorizzare un contenitore in un contenitore, ovvero
puoi ad esempio creare vettori di mappe e mappe di mappe di mappe (giuro, l'ho visto fare)

Questi sono solo i primi vantaggi che mi sono venuti in mente.

Altra cosa: spesso si dice che il C++ e' piu' lento (in termini di tempi di esecuzione) rispetto al C. Per esperienza personale (con il C e C++ ci campo da una vita), e stando anche a quanto affermato piu' volte da B. Stroustrup (speriamo stavolta di averlo scritto bene... e' l'inventore del C++) , SE IL CMPILATORE CHE USI E' FATTO BENE e se hai scritto in maniera decente il tuo programma, non dovresti avere problemi di prestazioni negative rispetto all'analogo algoritmo implementato in C.
IMHO se non usi le classi e tutto il mondo del C++, e' uno spreco usare il C++ per far girare un algoritmo scritto in C.

Ciao,
Mr Hyde
__________________
MacMini Late 2009/MacMini 2018

Ultima modifica di mr_hyde : 01-06-2006 alle 23:07. Motivo: aggiunta
mr_hyde è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare Cineca inaugura Pitagora, il supercomputer Lenov...
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA Mova Z60 Ultra Roller Complete: pulisce bene gra...
Renault Twingo E-Tech Electric: che prezzo! Renault Twingo E-Tech Electric: che prezzo!
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media Il cuore digitale di F1 a Biggin Hill: l'infrast...
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica DJI Osmo Mobile 8: lo stabilizzatore per smartph...
HONOR 500 Pro, scheda tecnica confermata...
GeForce NOW si prepara a vivere un mese ...
Exynos 2600: temperature più bass...
Apple si ispirerà a Nothing? Back...
Da Intel ad AMD, il grande salto di Kulk...
Velocità 12 volte superiore a que...
Una piccola Morte Nera è gi&agrav...
Sei frodi che minacciano gli utenti nel ...
BioShock 4: Take-Two rassicura sullo svi...
Tesla, Musk promette FSD 'quasi pronto' ...
BioWare conferma: il nuovo Mass Effect &...
5 robot aspirapolvere di fascia alta in ...
Xiaomi Redmi Note 14 5G a 179€ è ...
Veri affari con gli sconti de 15% Amazon...
Tutti gli iPhone 16 128GB a 699€, 16e a ...
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: 20:07.


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