PDA

View Full Version : Allocazione c++


leomagic
31-10-2003, 16:04
devo creare un vettore di tipo double di n elementi.
n = calcolo degli anni che occorrerà x raggiungere un certo valore da uno inziale con l'interessi del 3.5%.
Come posso scrivere questa funzione di allocazione?

alderighi
01-11-2003, 08:21
Leo ma che ti metti a fare, se ti vede il Calugi o la Lami, comunque interessa anche a me, anche se il prog è quasi terminato vorrei sapere come si alloca di volta in volta dinamicamente la memoria dentro un ciclo.
grazie
fate qualche esempio

verloc
01-11-2003, 10:36
Scusate ma voi,programmate senza uno straccio di guida?
Diamine queste sono le cose fondamentali.

si fa o con l'operatore new oppure con i vector della stl

Dovete imparare a cercare prima sulla guida altrimenti perdete un sacco di tempo.
Adesso però ve la procurate guida eh? ;)

(intendo per guida un file help che descrive tutte le funzioni,non un tutorial)

cionci
01-11-2003, 11:08
Mi sa che non usano la standard C++ library...altrimenti non l'avrebbetr chiesto...quindi niente vector...

Con il C++ c'è l'oepratore new che alloca la memoria...
Per aumentare le dimensioni via via che va avanti il programma in C++ non c'è una istruzione precisa come in C (in C c'è realloc)...ma si deve allocare un nuovo vettore più grande del precedente e copiarci dentro i nuovi risultati...
In teoria dovresti farlo all'inserimento di ogni nuovo elemento...ma per diminuire le operazioni di copia che sono solitamente lunghe si fa un preallocazione di N elementi...

Ad esempio questa può essere una classe che esegue queste operazioni... Non so a che punto siete in C++ quindi non uso i template (per poter generalizzare il tipo degli elementi del vettore)...


class vettore_double {
double *vett;
int len;
int maxlen;
int prealloc;
public:
vettore_double():prealloc(16);
vettore_double(vettore_double &vd);
void set_prealloc(int n);
int get_length();
double &operator[](int idx);
~vettore_double();
};

vettore_double::vettore_double()
{
vett = new[maxlen = prealloc];
len = 0;
}

vettore_double::vettore_double(vettore_double &vd)
{
prealloc = vd.prealloc;
len = vd.len;
maxlen = vd.maxlen;
vett = new[maxlen];
for(int i=0; i<len; ++i)
vett[i] = vd.vett[i];
}

double &vettore_double::operator[](int idx)
{
if(idx > (maxlen-1))
{
double *vett2 = vett;
maxlen = prealloc * (idx / prealloc + 1);
vett = new double[maxlen];
for(int i=0; i<len; ++i)
vett[i] = vett2[i];
}

if((len-1) < idx)
len = idx+1;

return vett[idx];
}


void vettore_double::set_prealloc(int n)
{
prealloc = n;
}

int vettore_double::get_length()
{
return len;
}

leomagic
01-11-2003, 12:44
o grande alde,seeeee la lami..o dio bono su un programmino mi funziona il new su quello dell'esercitazione nn va..quindi ho chiesto consigli!

Originariamente inviato da alderighi
Leo ma che ti metti a fare, se ti vede il Calugi o la Lami, comunque interessa anche a me, anche se il prog è quasi terminato vorrei sapere come si alloca di volta in volta dinamicamente la memoria dentro un ciclo.
grazie
fate qualche esempio

leomagic
01-11-2003, 12:45
Originariamente inviato da cionci
Mi sa che non usano la standard C++ library...altrimenti non l'avrebbetr chiesto...quindi niente vector...

Con il C++ c'è l'oepratore new che alloca la memoria...
Per aumentare le dimensioni via via che va avanti il programma in C++ non c'è una istruzione precisa come in C (in C c'è realloc)...ma si deve allocare un nuovo vettore più grande del precedente e copiarci dentro i nuovi risultati...
In teoria dovresti farlo all'inserimento di ogni nuovo elemento...ma per diminuire le operazioni di copia che sono solitamente lunghe si fa un preallocazione di N elementi...

Ad esempio questa può essere una classe che esegue queste operazioni... Non so a che punto siete in C++ quindi non uso i template (per poter generalizzare il tipo degli elementi del vettore)...


class vettore_double {
double *vett;
int len;
int maxlen;
int prealloc;
public:
vettore_double():prealloc(16);
vettore_double(vettore_double &vd);
void set_prealloc(int n);
int get_length();
double &operator[](int idx);
~vettore_double();
};

vettore_double::vettore_double()
{
vett = new[maxlen = prealloc];
len = 0;
}

vettore_double::vettore_double(vettore_double &vd)
{
prealloc = vd.prealloc;
len = vd.len;
maxlen = vd.maxlen;
vett = new[maxlen];
for(int i=0; i<len; ++i)
vett[i] = vd.vett[i];
}

double &vettore_double::operator[](int idx)
{
if(idx > (maxlen-1))
{
double *vett2 = vett;
maxlen = prealloc * (idx / prealloc + 1);
vett = new double[maxlen];
for(int i=0; i<len; ++i)
vett[i] = vett2[i];
}

if((len-1) < idx)
len = idx+1;

return vett[idx];
}


void vettore_double::set_prealloc(int n)
{
prealloc = n;
}

int vettore_double::get_length()
{
return len;
}


ci sono troppe cose che nn conosco in questo frammento di codice..
:cry:

leomagic
01-11-2003, 12:46
io credevo che fosse una funzione semplice del tipo..
mi faccio passare gli anni che sarebbero quante celle deve contenere il vettore.
creo un puntatore *p[3] x esempio..
poi faccio p = new(int*anni_passati)
la logica è questa..xò nn va..!!

cionci
01-11-2003, 12:49
Tra l'altro avevo sbagliato il codice per l'allocazione :) Che testa...

Comunque la new si usa così:

int *p = new int[numero di anni];

leomagic
01-11-2003, 12:51
faccio qualche prova e poi ti faccio sapere ok?

leomagic
01-11-2003, 12:51
alde te copiami il programma e ti uccido,ovvia l'idea di usare la new w nn la malloc l'ho avuta io e se il calugi mi dice che l'ho fatto uguale a te ti uccido!!

leomagic
01-11-2003, 13:04
cosa c'è che nn va?#include <iostream.h>
#include <conio.h>
#include <fstream.h>
#include <string.h>
#include <stdio.h>

void main()
{
int *p;
int dim,i,n;
cout << "dimmi dimensione vettore";
cin >> dim;
p = new int[dim];
for(i=0;i<dim;i++)
{
cout << "\ndimmi numero";
cin >> n;
*p[i]=n;
}
for(i=0;i<dim;i++)
{
cout << *p[i];
}
}

cionci
01-11-2003, 13:09
Questo: *p[i]

p[i] e quivale già a fare *(p+i)...

Comunque io avevo capito che ti serviva ridimensionare un vettore allocato con new... Se ti serve una allocazione semplice a lora va bene come hia fatto te...

p a quel punto lo puoi trattare, quasi, come un normale vettore...

leomagic
01-11-2003, 13:21
perfetto ora funziona..ho solo qualche piccolo problema non con il codice ma con il programma stesso..

cionci
01-11-2003, 13:43
Ah...mi raccomando..quando non ti serve più devi fare la delete...

delete[] p;

leomagic
01-11-2003, 13:56
ok grazie.
Ecco il nuovo problema.
Il vettore dovrà prendere la dimensione di quanti anni occorreranno x raggiungere un certo capitale da uno inziale con un tot di interessi annui.
Gli anni che occorrono verrano calcolati tramite una funzione ricorsiva..quindi io dovrei tutte le volte riallocare il puntatore e ricopiarci i dati dentro?
all'interno del vettore puntatore dovranno finirci i valori intermedi raggiunti anno anno dal capitale iniziale..

cionci
01-11-2003, 14:13
De allocarne uno nuovo, cancellare quello vecchio e ricopiare i valori in quello nuovo...

alderighi
02-11-2003, 07:54
Non ti proccupare leo mi sa che lascio il file temporaneo, almeno che l'Orsi non allochi dinamicamente la memoria, e allora sarei io l'unico bischero che non lo fa (visto che l'Orsi passa il programma a mezza classe).
Grande cionci ma sei un programmatore o un insegnante?
PS=noi usiamo il vecchio c/c++ della borland in modalità ms-dos

cionci
02-11-2003, 10:43
Il file che contiene i valori è una soluzione buona per questo tipo di problemi...

Altrimenti usa questa funzione per reallocare:

#include <string.h>

int *realloca(int *src, int dim_src, int new_dim)
{
if(new_dim < 0 && dim_src < 0) //controllo se i parametri sono buoni
return NULL;
int *dst = NULL;
if(new_dim > 0)
dst = new int[new_dim];
if(src != NULL && dim_src > 0 && new_dim > 0)
memcpy(dst, src, sizeof(double)*(dim_src > new_dim)?new_dim:dim_src);
if(dim_src > 0)
delete[] src;
return dst;
}

//esempi di utilizzo
//prima allocazione
vett = realloca(NULL, 0, 10); //alloca un vettore di 10 elementi
//modifica della diemensione
vett = realloca(vett, 10, 20); //modifica la dimensione a 20 e copia i valori
//deallocazione
vett = realloca(vett, 20, 0); //dealloca vett e ritorna NULL

A meno di errori dovrebbe andare bene... Vale sempre il discorso di fare l'allocazione a blocchi (ad esempio 10 a 10)... Quando hai finito lo spazio a disposizione allochi un altro blocco...
Originariamente inviato da alderighi
Grande cionci ma sei un programmatore o un insegnante?

Programatore...
Originariamente inviato da alderighi
PS=noi usiamo il vecchio c/c++ della borland in modalità ms-dos
Male...oltre a essere per DOS (non crea eseguibili a 32 bit) è anche uno dei copilatori fra quelli che conosco che rispetta meno los tandard sia del C che del C++...

leomagic
02-11-2003, 13:46
mi sembra un pò troppo complicato x i nostri livelli,eppure deve esistere un modo + semplice..
Io devo solo allocare un vettore d n elementi!
la cosa difficile che mi resta a me è che quel n viene calcolato da una funzione ricorsiva..

cionci
02-11-2003, 16:50
Allora devi o no modificare dinamicamente la dimensione del vettore ? Oppure la dimensione la conosci prima di allocarlo ?

Se la conosci prima di allocarlo:

n = calcola_n();

vett = new int[n];

e lo allochi...

leomagic
02-11-2003, 19:24
ricapitoliamo da capo:
int anni(double iniziale,double finale,int i,double v2[])
{
if (iniziale >= finale) //condizione x l'uscita dalla ricorsione
return 0;
iniziale = iniziale + iniziale * 0.035 * 0.875; //calcolo del guadagno
iniziale=app(iniziale); //approssimazione del numero
v2[i]=iniziale;
return 1 + anni(iniziale,finale,i+1,v2); //ricorsione
}

questo è il codice che calcola l'aumentare del capitale anno in anno.
X fare un grafico di come aumenta il capitale avevo pensato di mettere ogni valore calcolato da questa funzione in un vettore di n elementi quanti sono gli anni che occorreranno x far raggiungere il capitale finale dato da tastiera da un capitale inziale dato da tastiera.
Quel v2 è un vettore dichiarato di 100 elementi,x ottimizzare lo spazio usato in memoria avevo pensato di allocarlo dinamicamente..
Saprò esattamente quanto dovrà essere grande il vettore,ma solo alla fine della funzione,allorche avrò perso tutti i valori intermedi..
Se la rieseguò il programma perderà la sua ottimizzazione..
un pò più chiaro?

cionci
02-11-2003, 19:32
Appunto allora come dicevo io devi allocare continuamente nuova Ram...

int anni(double iniziale,double finale,int i,double &*v2, int &v2_dim)
{
if (iniziale >= finale) //condizione x l'uscita dalla ricorsione
return 0;
iniziale = iniziale + iniziale * 0.035 * 0.875; //calcolo del guadagno
iniziale=app(iniziale); //approssimazione del numero
if(i>=v2_dim)
{
v2 = realloca(v2, v2_dim, v2_dim+10);
v2_dim += 10;
}
v2[i]=iniziale;
return 1 + anni(iniziale,finale,i+1,v2,v2_dim); //ricorsione
}

Per richiamarlo fai così:

int *vett = NULL, vett_dim = 0;
int n = anni(iniziale,finale,0,vett,vett_dim);

In vett ti ritrovi il tuo vettore...con n elementi occupati, ma di dimensione vett_dim...

leomagic
02-11-2003, 19:43
non è sbagliato quel passaggio di paremetri formali con &* insieme?
cosa vuol dire quel realloca?

cionci
02-11-2003, 19:49
Sì...ho sbagliato a scrivere...è *&v2...

Passa un puntatore per riferimento...

leomagic
02-11-2003, 19:51
ma passare un puntatore per riferimento nn equivale a dire modificare il suo indirizzo?
quindi bastarebbe passare v2 no?
cosa vuol dire v2 = realloca(v2, v2_dim, v2_dim+10);
?

cionci
02-11-2003, 19:57
realloca è la funzione che avevo scritto nella pagina precedente...e aumenta (o diminuisce) la dimensione del vettore...

Il passaggio per riferimento del puntatore del vettore serve proprio perchè "realloca" cambia la posizione di allocazione del vettore e questa posizione torna modificata al chiamante...

leomagic
02-11-2003, 20:01
sinceramente.....mi sono troppo perso..cavolina..:muro: :muro: :muro:

cionci
03-11-2003, 09:41
int *realloca(int *src, int dim_src, int new_dim)
{
if(new_dim < 0 && dim_src < 0) //controllo se i parametri sono buoni
return NULL;
int *dst = NULL;
if(new_dim > 0)
dst = new int[new_dim];
if(src != NULL && dim_src > 0 && new_dim > 0)
memcpy(dst, src, sizeof(double)*(dim_src > new_dim)?new_dim:dim_src);
if(dim_src > 0)
delete[] src;
return dst;
}

int anni(double iniziale,double finale,int i,double &*v2, int &v2_dim)
{
if (iniziale >= finale) //condizione x l'uscita dalla ricorsione
return 0;
iniziale = iniziale + iniziale * 0.035 * 0.875; //calcolo del guadagno
iniziale=app(iniziale); //approssimazione del numero
if(i>=v2_dim)
{
v2 = realloca(v2, v2_dim, v2_dim+10);
v2_dim += 10;
}
v2[i]=iniziale;
return 1 + anni(iniziale,finale,i+1,v2,v2_dim); //ricorsione
}

int main()
{

int *vett = NULL, vett_dim = 0;
int n = anni(10000,20000,0,vett,vett_dim);
/* ..... */
return 0;
}

Spiegami cosa non ti torna...

PS: il codice non l'ho compilato...

leomagic
03-11-2003, 14:02
la funzione memcpy nn l'ho mai usata..come funziona?

cionci
03-11-2003, 17:10
Copia da src a dst una quantità di byte specificata dal terzo parametro...

Il terzo parametro l'ho settato come sizeof(double)*(dim_src > new_dim)?new_dim:dim_src

L'operatore condizione?statement1:statement2 è l'unico operatore ternario (a 3 operandi) presente in C e C++...

Se condizione è vera allora viene eseguito statement1, se condizione è falsa allora viene eseguito statement2...

In pratica il terzo parametro diventa la dimensione in byte dei duble moltiplicato per il minimo fra dim_src e new_dim...

In questo modo supporto sia l'aumento che la diminuzione dello spazio allocato...

leomagic
03-11-2003, 22:36
adesso ci sono,ma non cè una cosa + semplice della funzione realloca?
perchè noi a scuola nn l'abbiamo ancora fatta la funzione memcopy e le altre cose..
una cosa anche + macchinosa:
praticamente dovrei creare un puntatore = null,passarlo come parametro, dichiarare dentro la funzione un'altro puntatore di appoggio e lavorare su questi due copiandoli a vicenda?

cionci
04-11-2003, 09:12
Sì... Se non vuoi usare memcpy allora puoi sempre usare un for...

int *tmp = src; //così ti eviti anche di fare lo scambio fra src e tmp
src = new int[new_dim];
for(int i=0; i<sizeof(double)*(dim_src > new_dim)?new_dim:dim_src; ++i)
&nbsp;&nbsp;&nbsp;src[i] = tmp[i];

Ora in src hai il nuovo vettore...
Come vedi non è più semplice...
Tutti i vari if nella funzione realloca cercano di trattare ogni condizione che si può presentare alla funzione...

Passando new_dim == 0 si dealloca src e si emtte a NULL dst...
Passando src == NULL si fa la prima allocazione senza deallocare src (che genererebbe un errore)...
Se uno fra new_dim e dim_src sono < 0 allora non fa niente e ritorna NULL...

cionci
04-11-2003, 09:24
Te la riscrivo un po' più facile da leggere, visto che ho raggruppato i vari if in modo da evitare di ripetere le istruzioni...
Mi sono accorto che c'era un errore... Sulla prima condizione ci voleva un OR...

int *realloca(int *src, int dim_src, int new_dim)
{
int *dst = NULL;

if(src != NULL && dim_src > 0 && new_dim > 0)
{
dst = new int[new_dim];
memcpy(dst, src, sizeof(double)*(dim_src > new_dim)?new_dim:dim_src);
delete[] src;
}

if(src == NULL && new_dim > 0) //prima allocazione
dst = new int[new_dim];

if(src != NULL && dim_src > 0 && new_dim == 0) //deallocazione
delete[] src;

return dst;
}

Dopo tutto è molto più leggibile così...

leomagic
04-11-2003, 20:40
int *realloca(int *src, int dim_src, int new_dim)
{
int *dst = NULL;

if(src != NULL && dim_src > 0 && new_dim > 0)
{
dst = new int[new_dim];
memcpy(dst, src, sizeof(double)*(dim_src > new_dim)?new_dim:dim_src);
delete[] src;
}

if(src == NULL && new_dim > 0) //prima allocazione
dst = new int[new_dim];

if(src != NULL && dim_src > 0 && new_dim == 0) //deallocazione
delete[] src;

return dst;
}

int anni(double iniziale,double finale,int i,double &*v2, int &v2_dim)
{
if (iniziale >= finale) //condizione x l'uscita dalla ricorsione
return 0;
iniziale = iniziale + iniziale * 0.035 * 0.875; //calcolo del guadagno
iniziale=app(iniziale); //approssimazione del numero
if(i>=v2_dim)
{
v2 = realloca(v2, v2_dim, v2_dim+10);
v2_dim += 10;
}
v2[i]=iniziale;
return 1 + anni(iniziale,finale,i+1,v2,v2_dim); //ricorsione
}

int main()
{

int *vett = NULL, vett_dim = 0;
int n = anni(10000,20000,0,vett,vett_dim);
/* ..... */
return 0;
}

mi da diversi problemi sui passaggi di paramtri,cosa cè che nn va?

cionci
05-11-2003, 03:49
Avevo mescolato un po' di int e un po' di double:

#include <iostream.h>
#include <string.h>

double *realloca(double *src, int dim_src, int new_dim)
{
double *dst = NULL;

if(src != NULL && dim_src > 0 && new_dim > 0)
{
dst = new double[new_dim];
memcpy(dst, src, sizeof(double)*(dim_src > new_dim)?new_dim:dim_src);
delete[] src;
}

if(src == NULL && new_dim > 0) //prima allocazione
dst = new double[new_dim];

if(src != NULL && dim_src > 0 && new_dim == 0) //deallocazione
delete[] src;

return dst;
}

int anni(double iniziale,double finale,int i,double * &v2, int &v2_dim)
{
if (iniziale >= finale) //condizione x l'uscita dalla ricorsione
return 0;
iniziale = iniziale + iniziale * 0.035 * 0.875; //calcolo del guadagno
//iniziale=app(iniziale); //approssimazione del numero
if(i>=v2_dim)
{
v2 = realloca(v2, v2_dim, v2_dim+10);
v2_dim += 10;
}
v2[i]=iniziale;
return 1 + anni(iniziale,finale,i+1,v2,v2_dim); //ricorsione
}

int main()
{

double *vett = NULL;
int vett_dim = 0;
int n = anni(10000,20000,0,vett,vett_dim);

for(int i=0; i<n; ++i)
cout << i << " " << vett[i] << endl;

delete[] vett;
return 0;
}

leomagic
06-11-2003, 14:20
ciao,ti faccio davvero i miei complimenti x le tue conoscienze..
tutta via....è sorto un problema con la funzione che hai scritto tu.
Stamani a scuola l'ho inglobata nel programma perfettamente e solo la prima volta che fa l'allocazione mi compaiono degli 0 nel vettori incogniti..mentre la seconda volta funziona perfettamente..
gli 0 non sono tanti spazi che mi servono..
tutta via il prof mi ha dato una idea nuova, te la descrivo:
inzializzare una struttura dove al suo interno ci sarà un double che conterrà il dato che mi serve,ed un puntatore alla stuttura stessa che sarà la testa del puntatore che conterrà tutti i valori.
L'idea era di concatenare tutti i valori,passare per parametro il puntatore a struttura e cambiare la testa di volta in volta,che ne dici?
mi sembra molto più semplice del tuo e oltretutto nn dovrò utilizzare un vettore puntatore di appoggio per copiarci i valori.
A voce è facile a dirlo,purtroppo la lezione era finita..e in 5 minuti mi ha spiegato una pagina che mi sono portato a casa,magari ci lavorò un pò su e poi ti faccio sapere..cmq ti scrivo il codice di tutto il programma che ho fatto stamani:
double *realloca(double *src,int dim_src,int new_dim)
{
double *dst=NULL;
src=NULL;
if(src!=NULL && dim_src>0 && new_dim>0)
{
dst = new double[new_dim];
memcpy(dst,src,sizeof(double)*(dim_src>new_dim)?new_dim:dim_src);
delete[] src;
}
if(src==NULL && new_dim>0) //prima allocazione
dst=new double[new_dim];
if(src!=NULL && dim_src>0 && new_dim==0) //deallocazione
delete[] src;
return dst;
}

float app(float num) //Funzione che approssimerà alla seconda cifra
{ //decimale.Tutto ciò perchè l'euro ha solo
int n; //due cifre decimali
float a; //esempio di app di un numero
num=num*100; //677.447 677.111
num+=0.5; //677.947 677.151
n=num; //678 677
a=n; //678.000 677.000
return a/100; //6.78 6.77
}

int anni(double iniziale,double finale,int i,double *&v2,int &v2_dim)
{
if (iniziale >= finale) //condizione x l'uscita dalla ricorsione
return 0;
iniziale = iniziale + iniziale * 0.035 * 0.875; //calcolo del guadagno
iniziale=app(iniziale); //approssimazione del numero
if(i>=v2_dim)
{
v2=realloca(v2,v2_dim,v2_dim+10);
v2_dim=v2_dim+10;
}
v2[i]=iniziale;
return 1 + anni(iniziale,finale,i+1,v2,v2_dim); //ricorsione
}

double cap_finale(double iniziale,int anni,int i,double *&v,int &v_dim)
{
if (anni <= 0) //condizione x l'uscita dalla ricorsione
return iniziale;
iniziale = iniziale + iniziale * 0.035 * 0.875; //calcolo del guadagno
iniziale=app(iniziale); //approssimazione del numero
if(i>=v_dim)
{
v=realloca(v,v_dim,v_dim+10);
v_dim=v_dim+10;
}
v[i]=iniziale;
return cap_finale(iniziale,anni-1,i+1,v,v_dim); //ricorsione che ritorna il capitale aumentato e gli l'anno - 1
} //quando gli anni saranno uguali a 0 la funzione terminerà

char menu() //Output delle possibili scelte
{
clrscr();
cout << "Fai la tua scelta : " << endl;
cout << "1.Inserisci dato da tastiera per capitale in anni" << endl;
cout << "2.Inserisci dato da tastiera per anni in capitale" << endl;
cout << "3.Leggi dato da file" << endl;
cout << "4.Uscita" << endl;
return getch();
}

void scrivi_file(int anni,float cap,float n)
{
fstream uscite;
uscite.open("uscite.txt",ios::app);
uscite << "per raggiungere " << n << " euro da " << cap << " euro occorrono " << anni << " anni" << endl;
uscite.close();
}

void scrivi_file2(float capitale,int anni,float ini)
{
fstream uscite;
uscite.open("uscite.txt",ios::app);
uscite << "il capitale che raggiungerai dopo " << anni << " anno partendo da " << ini << " euro sara' "<< capitale << endl;
uscite.close();
}

void file(double *&v,double *&v2)
{
fstream informazioni;
fstream uscite;
int cod;
float cap_ini,n,anni_maturazione;
double cap_fin;
char nome[20];
clrscr;
fflush(stdin);
cout << "dimmi nome file da aprire ";
cin.getline(nome,20);
informazioni.open(nome,ios::in);
uscite.open("uscite.txt",ios::out);
uscite.close();
if(!informazioni)
{
cout << "file inesistente";
getch();
}
else
{
while(informazioni >> cod >> cap_ini >> n)
{
if(cod==1)
{
cout << "attenzione,sta per essere calcolato gli anni che occoreranno";
cout << " per raggiungere " << n;
cout << " da un capitale di " << cap_ini << endl;
cout << "Premere un tasto per continuare";
getch();
anni_maturazione=anni(cap_ini,n,0,v2,0);
cout << "\nGli anni sono : " << anni_maturazione << endl;
scrivi_file(anni_maturazione,cap_ini,n);
}
if(cod==2)
{
cout << "attenzione,sta per essere calcolato il capitale che ";
cout << " raggiungerai dopo " << n;
cout << " partendo da un capitale di " << cap_ini << endl;
cout << "Premere un tasto per continuare";
getch();
cap_fin=cap_finale(cap_ini,n,0,v,0);
cout << "\nil capitale e' " << cap_fin << endl;
scrivi_file2(cap_fin,n,cap_ini);
}
}
}
informazioni.close();
}

void main ()
{
double *vett2=NULL,*vett=NULL;
int vett2_dim=0,vett_dim=0;
int n,j,a,i;
float iniziale,finale;
char sc;
do
{
sc=menu();
switch (sc)
{
case '1':
clrscr;
cout << "Dimmi capitale inziale ";
cin >> iniziale;
cout << "Dimmi capitale da raggiungere ";
cin >> finale;
a=anni(iniziale,finale,0,vett2,vett2_dim);
cout << "Gli anni sono " << a << endl << endl;
for(j=0;j<a+5;j++) // stampa vettore dati temporanei
cout << vett2[j] << endl;
getch();
break;
case '2':
clrscr;
cout << "Dimmi capitale inziale ";
cin >> iniziale;
cout << "In quanti anni?";
cin >> n;
cout << "Il capitale maturato e' " << cap_finale(iniziale,n,0,vett,vett_dim) << endl << endl;
for(j=0;j<n+5;j++) // stampa vettore dati temporanei
cout << vett[j] << endl;
getch();
break;
case '3':
clrscr;
file(vett,vett2);
break;
}
}
while(sc!='4');
delete[] vett,vett2;
}

mi sbaglia tutta l'indentazione..:cry:

leomagic
06-11-2003, 14:54
per la scrittura del record avevo pensato ad una cosa così,può andare?
typedef struct
{
double valore;
testa *pt;
}testa;

alderighi
06-11-2003, 15:50
leo leo e se te lo rubassi??
non ti preoccupare non te lo rubo, a me funzia da dio con il file temporaneo (oddio non esageriamo, diciamo che gira discretamente facciamo le corna), il prof ti vuole far fare la struttura ad albero che è semplice ma difficile allo stesso tempo
Buon divertimento

leomagic
06-11-2003, 15:56
alde mi dai una mano?
io nn so come cavolo far richiamare quella struttura dentro un'altra..nn cè modo mi da sempre errore..
porco cagniuzzo..
il prof mi ha complicato d + la vita..mi sa che ci prova gusto..

alderighi
06-11-2003, 15:59
dammi il pezzo di codice che ti da errore e solo quello
PS=
calugi=non chiedergli nulla, ti complica la vita non risolvendoti il problema ma creandoti altri dubbi
lami=se sa risolvere il problema è disposta ad aiutarti e non si arrende facilmente

leomagic
06-11-2003, 19:39
credo di aver risolto,stasera quando ho finito magari vi posto il codice e mi dite se cè qualcosa che nn va..
Cmq cionci il codice che hai scritto tu mi da errore,cioè..ho provato anche quel frammento che mi avevi scritto tu e mi fa le stesse cose..
E' come se sbagliasse a fare la prima allocazione,xche le altre le fa bene.

cionci
07-11-2003, 19:44
A me il frammento che ho scritto io funziona bene...
Fammi vedere cosa ti da in output...

leomagic
09-11-2003, 11:55
partendo da un capitale di 5 x arrivare a 10 mi scrive

5.15
1.29544e-320
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
8.74262e-312
9.41
9.7
10

cionci
09-11-2003, 17:06
C'era un'errore di rpecedenza sugli operatori * e ? ;)

double *realloca(double *src,int dim_src,int new_dim)
{
double *dst=NULL;

if(src!=NULL && dim_src>0 && new_dim>0)
{
dst = new double[new_dim];
memcpy(dst,src,sizeof(double)*((dim_src>new_dim)?new_dim:dim_src));
delete[] src;
}
if(src==NULL && new_dim>0) //prima allocazione
dst=new double[new_dim];
if(src!=NULL && dim_src>0 && new_dim==0) //deallocazione
delete[] src;
return dst;
}

leomagic
09-11-2003, 20:32
ora è tutto perfetto!mannaggia ste parentesi..

leomagic
09-11-2003, 21:41
solo una cosa..

v=realloca(v,v_dim,v_dim+10);

questo è il richiamo,ma se metto +1 cosa cambia?

cionci
10-11-2003, 03:24
Originariamente inviato da leomagic
solo una cosa..

v=realloca(v,v_dim,v_dim+10);

questo è il richiamo,ma se metto +1 cosa cambia?
Cambia che riallochi il vettore di elemento in elemento...con una notevole perdita di tempo... Qui ne allochi 10 alla volta e fino a quando non li hai finiti non ne allochi di nuovi...

leomagic
10-11-2003, 14:01
ok..un'altra cosa..

if(src!=NULL && dim_src>0 && new_dim==0) //deallocazione
delete[] src;


questo cancella solo il vettore di appoggio vero?
ma se io dopo aver allocato 20 elementi,vado a richiamare la funzione principale e me ne occorre solo 10 posso cancellare gli altri 10?

cionci
10-11-2003, 14:36
Se 20 sono già allocati puoi ridimensionare il vettore passando come nuova dimensione 10...

leomagic
10-11-2003, 14:53
qua i problemi nn finiscono mai..quando scrivo sui file mi dai errore!

leomagic
10-11-2003, 20:48
la funzione che richiama la prima scrittura sui file file(vett,vett2);

con vett e vett2 dichiarati null nel main.

la funzione file

void file(double *&v,double *&v2)
{
fstream informazioni;
fstream uscite;
int cod;
float cap_ini,n,anni_maturazione;
double cap_fin;
char nome[20];
clrscr;
fflush(stdin);
cout << "dimmi nome file da aprire ";
cin.getline(nome,20);
informazioni.open(nome,ios::in);
uscite.open("uscite.txt",ios::out);
uscite.close();
if(!informazioni)
{
cout << "file inesistente";
getch();
}
else
{
while(informazioni >> cod >> cap_ini >> n)
{
if(cod==1)
{
cout << "attenzione,sta per essere calcolato gli anni che occoreranno";
cout << " per raggiungere " << n;
cout << " da un capitale di " << cap_ini << endl;
cout << "Premere un tasto per continuare";
getch();
anni_maturazione=anni(cap_ini,n,0,v2,0);
cout << "\nGli anni sono : " << anni_maturazione << endl;
scrivi_file(anni_maturazione,cap_ini,n);
}
if(cod==2)
{
cout << "attenzione,sta per essere calcolato il capitale che ";
cout << " raggiungerai dopo " << n;
cout << " partendo da un capitale di " << cap_ini << endl;
cout << "Premere un tasto per continuare";
getch();
cap_fin=cap_finale(cap_ini,n,0,v,0);
cout << "\nil capitale e' " << cap_fin << endl;
scrivi_file2(cap_fin,n,cap_ini);
}
}
}
informazioni.close();
}

che richiama la funzione anni che a sua volta richiama realloca..

dove è l'errore?
la prima volta me l'alloca,la seconda mi da errore..

cionci
11-11-2003, 02:18
anni_maturazione=anni(cap_ini,n,0,v2,0);
cap_fin=cap_finale(cap_ini,n,0,v,0);

L'ultimo parametro deve essere una variabile di tipo int...in tutti i compilatori moderni questo è un errore !!!

leomagic
11-11-2003, 12:36
giusto xche alle funzione passo x indirizzo quel valore,e loro trovandosi uno 0 nn possono modificarlo,vero?
dici che mi conviene usare 4 vettori distinti?
farei meno casino..

cionci
11-11-2003, 12:43
Io dico che ti basterebbe usare un solo vettore...mantendo la sua dimensione in un int...

O semplicemente ne potresti usare uno nella file e uno nel main... Senza dover passare il vettore come parametro...

Ma i parametri n e cap_ini perchè non li richiedi ? Dentro file li devi richiedere o farteli passare dal main...
Se te li fai passare dal main allora puoi anche mantenere i risultati in due vettori scrivendoli sul file direttamente senza ricalcolarli...

leomagic
11-11-2003, 12:47
nn li faccio passare dal main ma li leggo da un file..
avevo pensato a 4 vettori xche 2 per le funzioni che leggo da tastiera e altri 2 x vettori che leggo da file..
uso i vettori xche devo farci il grafico..

leomagic
11-11-2003, 21:14
x ora ho deciso di utilizzare 2 vettori..se poi riuscirò a capire come si fa con uno ne metterò uno..un'altra cosa..quando vado a fare il grafico se metto dei valori alti mi esce dal programma..ti posto il codice..

void grafico(int n,double finale,double *v,double *v2,int sc) //Funzione che disegna il grafico dell'andamento
{ //del capitale negli anni
clrscr();
//INIZIALIZZAZIONE SCHEDA GRAFICA
int driver_grafico=VGA;
int modalita_grafica=VGAHI;
int errore; // Se si è verificato un errore nell'inizializzazione della
//grafica, ne segnala il tipo.
initgraph(&driver_grafico, &modalita_grafica, "C:\\BC5\\BGI\\");
errore = graphresult();
//SE SI E' VERIFICATO UN ERRORE LO STAMPA
if (errore) // E POI ESCE DAL PROGRAMMA
{
cout << "ERRORE: " << grapherrormsg(errore) << endl;
getch();
exit(1);
}
else //ALTRIMENTI CONTINUA
{
int x,aint,bint,maxx=getmaxx(),maxy=getmaxy();; //Dichiarazione
long double adouble,bdouble,cdouble,y[2];
line(2,maxy-15,maxx,maxy-15); //Asse orizzontale
line(15,maxy-2,15,15); //Asse verticale

if (sc==1)
{
y[0]=0;
y[1]=v[0];
cdouble=y[1];
adouble= (maxy-27)/(finale-y[1]);
for(x=0; x<n; x++)
{
y[0]=y[1];
y[1]=v[x];
bdouble=adouble*(y[0]-cdouble);
aint=bdouble;
bdouble=adouble*(y[1]-cdouble);
bint=bdouble;
setcolor(RED); line(12,maxy-15-aint,17,maxy-15-aint);
setcolor(RED); line((x+1)*((maxx-15)/n),maxy-12,(x+1)*((maxx-15)/n),maxy-17);
setcolor(4);
line(15+x*((maxx-15)/n),maxy-15-aint,15+(x+1)*((maxx-15)/n),maxy-15-bint);
}
}
else
{
y[0]=0;
y[1]=v2[0];
cdouble=y[1];
adouble= (maxy-5)/(finale-y[1]);
for(x=0; x<n; x++)
{
y[0]=y[1];
y[1]=v2[x];
bdouble=adouble*(y[0]-cdouble);
aint=bdouble;
bdouble=adouble*(y[1]-cdouble);
bint=bdouble;
putpixel(2,maxy-5-aint,6);
putpixel((1+x)*((maxx-5)/n),maxy-2,5);
setcolor(4);
line(5+x*((maxx-5)/n),maxy-5-aint,5+(x+1)*((maxx-5)/n),maxy-5-bint);
}
}


getch();
}
closegraph();
}

cionci
12-11-2003, 08:23
Forse perchè vai al di fuori della viewport...
Devi crearti un fattore di scala a cui rapportare tutte le dimensioni...

Ad esempio:

double fattY = (maxy-30) / max(v, n);
double fattX = (maxx-30) / n;

double max(double *v, int n); è una semplice funzione che cerca il max del vettore...

alderighi
12-11-2003, 15:26
non dovrebbe essere per quello leo, lo fa a tutta la classe anche con le funzioni di autoridimensionamento, il prof dice perchè se no vengono troppe iterazioni o roba del genere, comunque sta di fatto che anche con il programma di due ragazzi dell'anno passato da lo stesso errore

leomagic
12-11-2003, 15:31
cioè quale errore alde?
poi cè un piccolo problema,a me il grafico lo inzia a fare nn proprio dall'incontro degli assi ma un poco + qua..circa 20 pixel..devo ancora riguardarlo..e per domani cè da consegnarlo..:muro:

alderighi
12-11-2003, 18:23
che se dai troppi anni (in genere più di 110 con numeri mediamente grossi) o la differenza tra cap iniziale e finale è grossotta esce direttamente dal programma e chiude la finestra sotto dos.
Per domani o seri dubbi che qualcheduno consegni visto che siamo circa in 4 gruppi un po' più avanti degli altri

leomagic
12-11-2003, 20:51
ihihi ho visto una cosa molto interessante..la farò presente al prof domani..ho fatto il calcolo partendo da 5 € in 350 anni e me lo fa..ma ho fatto qualche modifica :D