PDA

View Full Version : [C] problema passaggio parametri


grasszilla
20-05-2013, 21:31
buon giorno a tutti ragazzi!
sono un giovane studente di informatica e sto sviluppando un programmino da portare al professore per fine anno scolastico.
il programma raccoglie tutte le funzioni che abbiamo studiato fino ad ora riguardo la gestione dei vettori (ne mancano ancora alcune, ma vabbeh..) e sto trovando difficoltà riguardo il passaggio dei parametri.
io sapevo che i vettori vengono passati per definizione sempre per indirizzo, ma evidentemente non è così quando si tratta di più funzioni annidiate.
il codice funziona, perchè se dichiaro il vettore come variabile globale funziona benissimo.
ho provato ad usare i puntatori ma con scarsi risultati (non abbiamo affrontato ancora bene questo argomento a scuola).
vi incollo il codice (non funzionante) che ho scritto con codeblocks:



#include <stdio.h>
#include <time.h>
#include <conio.h>
#define TIPO int
TIPO MAX = 100;
TIPO MIN = 1;
int DIM = 0;
int primoavvio=0;
int primopopolo=0;


TIPO Accetta()
{
TIPO temp;
scanf("%d",&temp);
while ( getchar() != '\n' );
return temp;
}

void DimVet()
{
int temp=DIM;
do
{
printf("\n\nInserisci la nuova dimensione del vettore(intero positivo maggiore di zero): ");
DIM=Accetta();
}while(DIM<=0);
printf("\nLa nuova nuova dimensione del vettore e' %d\n", DIM);
primoavvio=1;
if(temp<DIM) primopopolo=0;
}

void RandDIM()
{
int temp=DIM,MIN,MAX;
printf("\nDefinisci l'intervallo di estrazione (min e max) ");
do{printf("\nMIN = ");MIN=Accetta();}while(MIN<0);
do{printf("\nMAX = ");MAX=Accetta();}while(MAX<MIN);
DIM=rand()%(MAX-MIN+1)+MIN;
printf("\nLa nuova nuova dimensione del vettore e' %d\n", DIM);
primoavvio=1;
if(temp<DIM) primopopolo=0;
}

void CaricaVet(TIPO vet[],int DIM)
{
int i;
for(i=0;i<DIM;i++)
{

printf("\nInserisci l'elemento del vettore di posto %d: ",i);
vet[i]=Accetta();
}
primopopolo=1;
}

void RandVet(TIPO vet[],int DIM)
{
int i;
printf("\nDefinisci l'intervallo di estrazione degli elementi del vettore (min e max) ");
printf("\nMIN = ");MIN=Accetta();
do{printf("\nMAX = ");MAX=Accetta();}while(MAX<MIN);
for(i=0;i<DIM;i++)
{
vet[i]=rand()%(MAX-MIN+1)+MIN;
printf("\nVET[%d]=%d",i,vet[i]);
}
primopopolo=1;
}

void Scambia(int a,int b,TIPO vet[])
{
TIPO temp=vet[a];
vet[a]=vet[b];
vet[b]=temp;
}

int PosMin(TIPO vet[],int DIM)
{
int i,posmin=0;
for(i=1;i<DIM;i++)
if(vet[posmin]>vet[i]) posmin=i;

return posmin;
}

int PosMax(TIPO vet[],int DIM)
{
int i,posmax=0;
for(i=1;i<DIM;i++)
if(vet[posmax]<vet[i]) posmax=i;
return posmax;
}

int MediaInt(TIPO vet[],int DIM)
{
TIPO media=0;
int i;
for(i=0;i<DIM;i++)
media+=vet[i];

return (int) media/DIM;
}

float MediaFloat(TIPO vet[],int DIM)
{
float media=0;
int i;
for(i=0;i<DIM;i++)
media+=vet[i];

return (float) media/DIM;
}

int Scarto(TIPO vet[],int DIM)
{
int i,posmin=0,media=MediaInt(vet,DIM);
for(i=1;i<DIM;i++)
if(abs(media-vet[posmin])>abs(media-vet[i])) posmin=i;

return posmin;
}

void OrdinaC(TIPO vet[],int DIM)
{
int i,j,pos;
for(i=0;i<DIM;i++)
{
pos=i;
for(j=i+1;j<DIM;j++)
if(vet[j]<vet[pos])pos=j;
Scambia(i,pos,vet);
}
}

void OrdinaD(TIPO vet[],int DIM)
{
int i,j,pos;
for(i=0;i<DIM;i++)
{
pos=i;
for(j=i+1;j<DIM;j++)
if(vet[j]>vet[pos])pos=j;
Scambia(i,pos,vet);
}
}

void OrdinaBC(TIPO vet[],int DIM)
{
int i,flag=1,n=DIM-1;
do
{
flag=0;
for(i=0;i<n;i++)
if(vet[i]>vet[i+1])
{
Scambia(i,i+1,vet);
flag++;
}
n--;
}while(flag>0);
}

void OrdinaBD(TIPO vet[],int DIM)
{
int i,flag=1,n=DIM-1;
do
{
flag=0;
for(i=0;i<n;i++)
if(vet[i]<vet[i+1])
{
Scambia(i,i+1,vet);
flag++;
}
n--;
}while(flag>0);
}

void StampaEle(int i,TIPO vet[])
{
printf("\n VET[%d]=%d",i,vet[i]);
}

void Stampa(TIPO vet[],int DIM)
{
int i;
for(i=0;i<DIM;i++)
StampaEle(i,vet);
}

void Occorrenze(TIPO vet[],int DIM)
{
int i,j,num;
for(i=0;i<DIM;i++)
{
num=0;
for(j=0;j<DIM;j++)
if(i>j && vet[i]== vet[j]) break;
else if (vet[i]==vet[j]) num++;
if(num!=0)printf("\nil valore %d e' stato estratto %d volte",vet[i],num);
}
}

int Cerca(int ele,TIPO vet[],int DIM)
{
int i=0;
while((vet[i]!=ele) && i++<DIM);
return i;
}

void Shuffle(TIPO vet[],int DIM)
{
int i;
for(i=0;i<DIM;i++)
Scambia(i,rand()%DIM,vet);
}

void Uscita()
{
printf("\nARRIVEDERCI!");
system("PAUSE");
}

int mcd(int a, int b) //ALGORITMO DI EUCLIDE
{
if (b == 0)
return a;
else
return mcd(b, a % b);
}

int MCD(TIPO vet[],int DIM)
{
int i=0,a=0;
if(vet[PosMin(vet,DIM)]==1) return 1;
if(DIM==1) return vet[0];
while(i<DIM)a=mcd(a,vet[i++]);
return a;
}

int mcm(int a,int b)
{
return (a*b)/mcd(a,b);
}

int MCM(TIPO vet[],int DIM)
{
int i=0,a=1;
if(DIM==1) return vet[0];
while(i<DIM)a=mcm(a,vet[i++]);
return a;
}

int SottoMenu(int n)
{
switch(n)
{
case 3 ... 4:
{
if(primoavvio==0)
printf("\n\tNon hai ancora dichiarato la dimensione del vettore");
else
{
printf("\n\tLa dimensione attuale del vettore e' %d, vuoi cambiarla?",DIM);
printf("\n\t0: Usa la dimensione attuale");
}
printf("\n\t1: Inserisci manualmente la dimensione del vettore");
printf("\n\t2: Genera casualmente la dimensione del vettore");
printf("\n\t3: Torna al menu\n\t");
break;
}
case 10: {
printf("\n\t0: Ordina in verso crescente (ordinamento ingenuo)");
printf("\n\t1: Ordina in verso decrescente (ordinamento ingenuo)");
printf("\n\t2: Ordina in verso crescente (bubble sort)");
printf("\n\t3: Ordina in verso decrescente (bubble sort)");
printf("\n\t4: Torna al menu\n\t");
break;}
}
}

void SottoScelta(int n,TIPO vet[],int DIM)
{
SottoMenu(n);
switch(n)
{
case 3:{
switch(Accetta())
{
case 1: DimVet();break;
case 2: RandDIM();break;
}
CaricaVet(vet,DIM);
break;
}
case 4:{
switch(Accetta())
{
case 1: DimVet();break;
case 2: RandDIM();break;
}
RandVet(vet,DIM);
break;
}
case 10:{
switch(Accetta())
{
case 0: OrdinaC(vet,DIM);break;
case 1: OrdinaD(vet,DIM);break;
case 2: OrdinaBC(vet,DIM);break;
case 3: OrdinaBD(vet,DIM);break;
}
Stampa(vet,DIM);break;
}
}
}

int Menu()
{
int temp=0;
void PrimiQuattro()
{
printf("\n");
printf("\nSchiaccia il tasto relativo alla funzione che vuoi attivare");
printf("\n0: Uscita");
printf("\n1: Definisci dimensione del vettore");
printf("\n2: Genera casualemente la dimensione del vettore");
printf("\n3: Inserisci manualmente gli elementi del vettore");
printf("\n4: Genera casualmente gli elementi del vettore\n");
}


system("cls");
if(primopopolo==0)
{
if(primoavvio==0) printf("\nProgramma per la gestione dei vettori\nPer iniziare dichiara la dimensione del vettore");
else printf("\nDevi ancora popolare il vettore");
PrimiQuattro();
return Accetta();
}
PrimiQuattro();
printf("5: Estrai il minimo dal vettore");
printf("\n6: Estrai il massimo dal vettore");
printf("\n7: Calcola la media intera");
printf("\n8: Calcola la media reale");
printf("\n9: Estrai il valore piu' vicino alla media");
printf("\n10: Ordina il vettore");
printf("\n11: Stampa il vettore");
printf("\n12: Stampa un elemento del vettore");
printf("\n13: Calcola occorrenze");
printf("\n14: Cerca elemento nel vettore");
printf("\n15: Mischia il vettore");
printf("\n16: Calcola M.C.D. e m.c.m.");
printf("\n");
return Accetta();
}

void Scelta(int vet[],int DIM)
{
int temp,a;
do
{
do
{
temp=Menu();
}
while((primopopolo==0 && (temp<0 || temp>4))||(primopopolo!=0 && (temp<0 || temp>16)));
switch (temp)
{
case 1: DimVet();break;
case 2: RandDIM();break;
case 3: SottoScelta(temp,vet,DIM);break;
case 4: SottoScelta(temp,vet,DIM);break;
case 5: printf("\nIl minimo vale %d ed occupa la posizione %d", vet[PosMin(vet,DIM)],PosMin(vet,DIM));break;
case 6: printf("\nIl massimo vale %d ed occupa la posizione %d", vet[PosMax(vet,DIM)],PosMax(vet,DIM));break;
case 7: printf("\nLa media intera vale %d",MediaInt(vet,DIM));break;
case 8: printf("\nLa media reale vale %f",MediaFloat(vet,DIM));break;
case 9: printf("\nIl valore piu' vicino alla media vale %d e occupa la posizione %d",vet[Scarto(vet,DIM)],Scarto(vet,DIM));break;
case 10: SottoScelta(temp,vet,DIM);break;
case 11: Stampa(vet,DIM);break;
case 12: {do{printf("\nInserisci la posizione dell'elemento che vuoi stampare (tra 0 a %d)",DIM-1);scanf("%d",&a);}while(a<0 || a>=DIM);StampaEle(a,vet);break;}
case 13: Occorrenze(vet,DIM);break;
case 14: {printf("\n\nInserisci il valore dell'elemento che vuoi cercare ");Cerca(Accetta(),vet,DIM);break;}
case 15: {Shuffle(vet,DIM);Stampa(vet,DIM);break;}
case 16: printf("\nIl massimo comune divisore vale: %d\nIl minimo comune multiplo vale: %d",MCD(vet,DIM),MCM(vet,DIM));break;
}
printf("\n\nPremere un tasto per continuare...");
getch();
}
while(temp!=0);
}

int main()
{
TIPO vet[DIM];
srand(time(NULL));
Scelta(vet,DIM);
Uscita();
return 0;
}

clockover
20-05-2013, 21:57
Dovresti dire almeno che errori hai... Comunque prova a fare questo cambiamento nel main
TIPO * vet = malloc(sizeof(TIPO) * DIM);
srand(time(NULL));
Scelta(vet,DIM);
Uscita();
free(vet);
return 0;

fammi sapere come va... ci sarebbero alcune cose inesatte nel tuo codice ma ora non ho molto tempo..
Ricorda di scrivere che errore da la prossima volta

lorenzo001
20-05-2013, 22:02
Scusa ma DIM è eguale a zero ... quindi nel main all'inizio quel vettore non esiste ...

E poi cosa pensi di fare con la funzione DimVet ?

grasszilla
20-05-2013, 22:07
beh, credo ci sia qualcosa che ho omesso nel passaggio dei parametri, in quanto ogni volta che chiamo una procedura non funziona (come ade esempio quella per generare a caso gli elementi del vettore).
ma il codice è corretto perchè se dichiaro vet come variabile globale e tolgo tutti i parametri(quelli non essenziali) il programma funziona

grasszilla
20-05-2013, 22:09
Dovresti dire almeno che errori hai... Comunque prova a fare questo cambiamento nel main
TIPO * vet = malloc(sizeof(TIPO) * DIM);
srand(time(NULL));
Scelta(vet,DIM);
Uscita();
free(vet);
return 0;

fammi sapere come va... ci sarebbero alcune cose inesatte nel tuo codice ma ora non ho molto tempo..
Ricorda di scrivere che errore da la prossima volta


scusa, puoi spiegarmi a cosa servono le funzioni che hai usato?

grasszilla
20-05-2013, 22:11
Scusa ma DIM è eguale a zero ... quindi nel main all'inizio quel vettore non esiste ...

E poi cosa pensi di fare con la funzione DimVet ?

cambiare la dimensione del vettore e assicurarmi che non rimangano posizioni vuote prima di chiamare altre funzioni





ecco, questa è la versione funzionante del codice(senza passaggio del vettore nei parametri):
#include <stdio.h>
#include <time.h>
#include <conio.h>
#define TIPO int
TIPO MAX = 100;
TIPO MIN = 1;
TIPO vet[];
int DIM = 0;
int primoavvio=0;
int primopopolo=0;


TIPO Accetta()
{
TIPO temp;
scanf("%d",&temp);
while ( getchar() != '\n' );
return temp;
}

void DimVet()
{
int temp=DIM;
do
{
printf("\n\nInserisci la nuova dimensione del vettore(intero positivo maggiore di zero): ");
DIM=Accetta();
}while(DIM<=0);
printf("\nLa nuova nuova dimensione del vettore e' %d\n", DIM);
primoavvio=1;
if(temp<DIM) primopopolo=0;
}

void RandDIM()
{
int temp=DIM,MIN,MAX;
printf("\nDefinisci l'intervallo di estrazione (min e max) ");
do{printf("\nMIN = ");MIN=Accetta();}while(MIN<0);
do{printf("\nMAX = ");MAX=Accetta();}while(MAX<MIN);
DIM=rand()%(MAX-MIN+1)+MIN;
printf("\nLa nuova nuova dimensione del vettore e' %d\n", DIM);
primoavvio=1;
if(temp<DIM) primopopolo=0;
}

void CaricaVet()
{
int i;
for(i=0;i<DIM;i++)
{

printf("\nInserisci l'elemento del vettore di posto %d: ",i);
vet[i]=Accetta();
}
primopopolo=1;
}

void RandVet()
{
int i;
printf("\nDefinisci l'intervallo di estrazione degli elementi del vettore (min e max) ");
printf("\nMIN = ");MIN=Accetta();
do{printf("\nMAX = ");MAX=Accetta();}while(MAX<MIN);
for(i=0;i<DIM;i++)
{
vet[i]=rand()%(MAX-MIN+1)+MIN;
printf("\nVET[%d]=%d",i,vet[i]);
}
primopopolo=1;
}

void Scambia(int a,int b)
{
TIPO temp=vet[a];
vet[a]=vet[b];
vet[b]=temp;
}

int PosMin()
{
int i,posmin=0;
for(i=1;i<DIM;i++)
if(vet[posmin]>vet[i]) posmin=i;

return posmin;
}

int PosMax()
{
int i,posmax=0;
for(i=1;i<DIM;i++)
if(vet[posmax]<vet[i]) posmax=i;
return posmax;
}

int MediaInt()
{
TIPO media=0;
int i;
for(i=0;i<DIM;i++)
media+=vet[i];

return (int) media/DIM;
}

float MediaFloat()
{
float media=0;
int i;
for(i=0;i<DIM;i++)
media+=vet[i];

return (float) media/DIM;
}

int Scarto()
{
int i,posmin=0,media=MediaInt();
for(i=1;i<DIM;i++)
if(abs(media-vet[posmin])>abs(media-vet[i])) posmin=i;

return posmin;
}

void OrdinaC()
{
int i,j,pos;
for(i=0;i<DIM;i++)
{
pos=i;
for(j=i+1;j<DIM;j++)
if(vet[j]<vet[pos])pos=j;
Scambia(i,pos);
}
}

void OrdinaD()
{
int i,j,pos;
for(i=0;i<DIM;i++)
{
pos=i;
for(j=i+1;j<DIM;j++)
if(vet[j]>vet[pos])pos=j;
Scambia(i,pos);
}
}

void OrdinaBC()
{
int i,flag=1,n=DIM-1;
do
{
flag=0;
for(i=0;i<n;i++)
if(vet[i]>vet[i+1])
{
Scambia(i,i+1);
flag++;
}
n--;
}while(flag>0);
}

void OrdinaBD()
{
int i,flag=1,n=DIM-1;
do
{
flag=0;
for(i=0;i<n;i++)
if(vet[i]<vet[i+1])
{
Scambia(i,i+1);
flag++;
}
n--;
}while(flag>0);
}

void StampaEle(int i)
{
printf("\n VET[%d]=%d",i,vet[i]);
}

void Stampa()
{
int i;
for(i=0;i<DIM;i++)
StampaEle(i);
}

void Occorrenze()
{
int i,j,num;
for(i=0;i<DIM;i++)
{
num=0;
for(j=0;j<DIM;j++)
if(i>j && vet[i]== vet[j]) break;
else if (vet[i]==vet[j]) num++;
if(num!=0)printf("\nil valore %d e' stato estratto %d volte",vet[i],num);
}
}

int Cerca(int ele)
{
int i=0;
while((vet[i]!=ele) && i++<DIM);
return i;
}

void Shuffle()
{
int i;
for(i=0;i<DIM;i++)
Scambia(i,rand()%DIM);
}

void Uscita()
{
printf("\nARRIVEDERCI!");
system("PAUSE");
}

int mcd(int a, int b) //ALGORITMO DI EUCLIDE
{
if (b == 0)
return a;
else
return mcd(b, a % b);
}

int MCD()
{
int i=0,a=0;
if(vet[PosMin()]==1) return 1;
if(DIM==1) return vet[0];
while(i<DIM)a=mcd(a,vet[i++]);
return a;
}

int mcm(int a,int b)
{
return (a*b)/mcd(a,b);
}

int MCM()
{
int i=0,a=1;
if(DIM==1) return vet[0];
while(i<DIM)a=mcm(a,vet[i++]);
return a;
}

int SottoMenu(int n)
{
switch(n)
{
case 3 ... 4:
{
if(primoavvio==0)
printf("\n\tNon hai ancora dichiarato la dimensione del vettore");
else
{
printf("\n\tLa dimensione attuale del vettore e' %d, vuoi cambiarla?",DIM);
printf("\n\t0: Usa la dimensione attuale");
}
printf("\n\t1: Inserisci manualmente la dimensione del vettore");
printf("\n\t2: Genera casualmente la dimensione del vettore");
printf("\n\t3: Torna al menu\n\t");
break;
}
case 10: {
printf("\n\t0: Ordina in verso crescente (ordinamento ingenuo)");
printf("\n\t1: Ordina in verso decrescente (ordinamento ingenuo)");
printf("\n\t2: Ordina in verso crescente (bubble sort)");
printf("\n\t3: Ordina in verso decrescente (bubble sort)");
printf("\n\t4: Torna al menu\n\t");
break;}
}
}

void SottoScelta(int n)
{
SottoMenu(n);
switch(n)
{
case 3:{
switch(Accetta())
{
case 1: DimVet();break;
case 2: RandDIM();break;
}
CaricaVet();
break;
}
case 4:{
switch(Accetta())
{
case 1: DimVet();break;
case 2: RandDIM();break;
}
RandVet();
break;
}
case 10:{
switch(Accetta())
{
case 0: OrdinaC();break;
case 1: OrdinaD();break;
case 2: OrdinaBC();break;
case 3: OrdinaBD();break;
}
Stampa();break;
}
}
}

int Menu()
{
int temp=0;
void PrimiQuattro()
{
printf("\n");
printf("\nSchiaccia il tasto relativo alla funzione che vuoi attivare");
printf("\n0: Uscita");
printf("\n1: Definisci dimensione del vettore");
printf("\n2: Genera casualemente la dimensione del vettore");
printf("\n3: Inserisci manualmente gli elementi del vettore");
printf("\n4: Genera casualmente gli elementi del vettore\n");
}


system("cls");
if(primopopolo==0)
{
if(primoavvio==0) printf("\nProgramma per la gestione dei vettori\nPer iniziare dichiara la dimensione del vettore");
else printf("\nDevi ancora popolare il vettore");
PrimiQuattro();
return Accetta();
}
PrimiQuattro();
printf("5: Estrai il minimo dal vettore");
printf("\n6: Estrai il massimo dal vettore");
printf("\n7: Calcola la media intera");
printf("\n8: Calcola la media reale");
printf("\n9: Estrai il valore piu' vicino alla media");
printf("\n10: Ordina il vettore");
printf("\n11: Stampa il vettore");
printf("\n12: Stampa un elemento del vettore");
printf("\n13: Calcola occorrenze");
printf("\n14: Cerca elemento nel vettore");
printf("\n15: Mischia il vettore");
printf("\n16: Calcola M.C.D. e m.c.m.");
printf("\n");
return Accetta();
}

void Scelta()
{
int temp,a;
do
{
do
{
temp=Menu();
}
while((primopopolo==0 && (temp<0 || temp>4))||(primopopolo!=0 && (temp<0 || temp>16)));
switch (temp)
{
case 1: DimVet();break;
case 2: RandDIM();break;
case 3: SottoScelta(temp);break;
case 4: SottoScelta(temp);break;
case 5: printf("\nIl minimo vale %d ed occupa la posizione %d", vet[PosMin()],PosMin());break;
case 6: printf("\nIl massimo vale %d ed occupa la posizione %d", vet[PosMax()],PosMax());break;
case 7: printf("\nLa media intera vale %d",MediaInt());break;
case 8: printf("\nLa media reale vale %f",MediaFloat());break;
case 9: printf("\nIl valore piu' vicino alla media vale %d e occupa la posizione %d",vet[Scarto()],Scarto());break;
case 10: SottoScelta(temp);break;
case 11: Stampa();break;
case 12: {do{printf("\nInserisci la posizione dell'elemento che vuoi stampare (tra 0 a %d)",DIM-1);scanf("%d",&a);}while(a<0 || a>=DIM);StampaEle(a);break;}
case 13: Occorrenze();break;
case 14: {printf("\n\nInserisci il valore dell'elemento che vuoi cercare ");if(Cerca(Accetta())==DIM)printf("\nElemento non trovato");else printf("\nElemento trovato al posto %d",Cerca(Accetta()));break;}
case 15: {Shuffle();Stampa();break;}
case 16: printf("\nIl massimo comune divisore vale: %d\nIl minimo comune multiplo vale: %d",MCD(),MCM());break;
}
printf("\n\nPremere un tasto per continuare...");
getch();
}
while(temp!=0);
}

int main()
{
srand(time(NULL));
Scelta();
Uscita();
return 0;
}

lorenzo001
20-05-2013, 22:20
Cambi solamente il valore di DIM ma non lo spazio riservato al vettore che viene determinato una sola volta quando esegui

TIPO vet[DIM];

Altrimenti, come ti è stato indicato, devi usare l' "allocazione dinamica" del vettore e quindi malloc/realloc per allocare/riallocare il vettore.

grasszilla
20-05-2013, 22:30
Cambi solamente il valore di DIM ma non lo spazio riservato al vettore che viene determinato una sola volta quando esegui

TIPO vet[DIM];

Altrimenti, come ti è stato indicato, devi usare l' "allocazione dinamica" del vettore e quindi malloc/realloc per allocare/riallocare il vettore.

ah ecco, quindi dovrei usare queste funzioni...
ma comunque rimane sempre il problema riguardo il passaggio dei parametri che da solo non sono riuscito a risolvere

lorenzo001
20-05-2013, 22:33
Il problema non è nel passaggio dei parametri ma nell'allocazione del vettore.

Correggila ...

grasszilla
20-05-2013, 23:04
domani appena ho tempo studierò queste funzioni e cercherò di implementarle nel codice, ma non funzioneranno lo stesso, perchè se vedi bene la seconda versione che ho pubblicato per farlo funzionare ho dovuto dichiarare vet come variabile globale e funziona come dico io senza nemmeno toccare le procedure (giusto o sbagliato che sia)

lorenzo001
21-05-2013, 12:53
mi chiedo come si faccia a fare C senza avere chiaro cos'è la memoria, cos'è l'allocazione statica-dinamica, cosa sono heap e stack

Concordo pienamente

rifletti ...

Sacrosanta verità ... ma anch'io non mi stupisco più di nulla ...

Oceans11
22-05-2013, 00:05
inoltre, non è detto che siccome funziona tutto con la variabile globale, le funzioni sono scritte bene anche nel caso di passaggio di parametri.

ps: manco io mi stupisco, visto che ci sono professori che ti dicono che "i vettori vengono passati per indirizzo", quando in realtà in c tutti i parametri vengono copiati. Se poi quello che viene copiato è un indirizzo, il risultato è che nella funzione chiamata (a qualsiasi livello di chiamata) riesci a modificare il valore puntato dal puntatore che punta alla copia del suddetto indirizzo.

ho cercato di essere il più chiaro possibile, spero sia bastato.

grasszilla
22-05-2013, 19:06
allora ragazzi, come vi ho già detto sono ancora uno studente (e questo è il primo anno, quindi la mia ignoranza è giustificata), e mi sembra normale che alcune cose non le abbia ancora trattate o approfondite (come l'allocazione dinamica della memoria del quale non sapevo nemmeno l'esistenza).
Il professore ha chiesto una funzione per cambiare la dimensione del vettore (ma spesso ci da problemi che non siamo ancora in grado di risolvere per vedere che strade usiamo per risolverli), e questa è la più banale che mi è saltata in mente, ma avevo anche pensato di cambiare semplicemente il valore di DIM e di richiamare il main program in modo che le variabili vengano reinizializzate (se è sbagliato prima di insultarmi fatemi capire il perchè).
per ora l'ho riscritto utilizzando malloc/realloc e le variabili puntatore, però credo di aver fatto un guaio perchè il programma si blocca quando inizializzo vet[2].
vi prego di darci uno sguardo e di segnalarmi qualche errore grossolano, perchè ho fatto un casino con le & e i *



#include <stdio.h>
#include <time.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#define TIPO int
TIPO MAX = 100;
TIPO MIN = 1;
int DIM = 1;
int primoavvio=0;
int primopopolo=0;


TIPO Accetta()
{
TIPO temp;
scanf("%d",&temp);
while (getchar()!='\n');
return temp;
}

void DimVet(TIPO *vet, int *DIM)
{
int temp=*DIM;
do
{
printf("\n\nInserisci la nuova dimensione del vettore(intero positivo): ");
*DIM=Accetta();
}while(*DIM<=0);
TIPO *tmp = realloc(vet, *DIM);
vet = tmp;
printf("\nLa nuova nuova dimensione del vettore e' %d\n", *DIM);
primoavvio=1;
if(temp<*DIM) primopopolo=0;
}

void RandDIM(TIPO *vet,int *DIM)
{
int temp=*DIM,MIN,MAX;
printf("\nDefinisci l'intervallo di estrazione (min e max) ");
do{printf("\nMIN = ");MIN=Accetta();}while(MIN<=0);
do{printf("\nMAX = ");MAX=Accetta();}while(MAX<=MIN);
*DIM=rand()%(MAX-MIN+1)+MIN;
TIPO *tmp = realloc(vet, *DIM);
vet = tmp;
printf("\nLa nuova nuova dimensione del vettore e' %d\n", *DIM);
primoavvio=1;
if(temp<*DIM) primopopolo=0;
}

void CaricaVet(TIPO *vet[],int DIM)
{
int i;
for(i=0;i<DIM;i++)
{
printf("\nInserisci l'elemento del vettore di posto %d: ",i);
*vet[i]=Accetta();
}
primopopolo=1;
}

void RandVet(TIPO *vet[],int DIM)
{
int i;
printf("\nDefinisci l'intervallo di estrazione degli elementi del vettore (min e max) ");
printf("\nMIN = ");MIN=Accetta();
do{printf("\nMAX = ");MAX=Accetta();}while(MAX<MIN);
for(i=0;i<DIM;i++)
{
*vet[i]=rand()%(MAX-MIN+1)+MIN;
printf("\nVET[%d]=%d",i,*vet[i]);
}
primopopolo=1;
}

void Scambia(int a,int b,TIPO *vet[])
{
TIPO temp=*vet[a];
*vet[a]=*vet[b];
*vet[b]=temp;
}

int PosMin(TIPO vet[],int DIM)
{
int i,posmin=0;
for(i=1;i<DIM;i++)
if(vet[posmin]>vet[i]) posmin=i;

return posmin;
}

int PosMax(TIPO vet[],int DIM)
{
int i,posmax=0;
for(i=1;i<DIM;i++)
if(vet[posmax]<vet[i]) posmax=i;
return posmax;
}

int MediaInt(TIPO vet[],int DIM)
{
TIPO media=0;
int i;
for(i=0;i<DIM;i++)
media+=vet[i];

return (int) media/DIM;
}

float MediaFloat(TIPO vet[],int DIM)
{
float media=0;
int i;
for(i=0;i<DIM;i++)
media+=vet[i];

return (float) media/DIM;
}

int Scarto(TIPO vet[],int DIM)
{
int i,posmin=0,media=MediaInt(vet,DIM);
for(i=1;i<DIM;i++)
if(abs(media-vet[posmin])>abs(media-vet[i])) posmin=i;

return posmin;
}

void OrdinaC(TIPO *vet[],int DIM)
{
int i,j,pos;
for(i=0;i<DIM;i++)
{
pos=i;
for(j=i+1;j<DIM;j++)
if(*vet[j]<*vet[pos])pos=j;
Scambia(i,pos,&*vet);
}
}

void OrdinaD(TIPO *vet[],int DIM)
{
int i,j,pos;
for(i=0;i<DIM;i++)
{
pos=i;
for(j=i+1;j<DIM;j++)
if(*vet[j]>*vet[pos])pos=j;
Scambia(i,pos,&*vet);
}
}

void OrdinaBC(TIPO *vet[],int DIM)
{
int i,flag=1,n=DIM-1;
do
{
flag=0;
for(i=0;i<n;i++)
if(*vet[i]>*vet[i+1])
{
Scambia(i,i+1,&*vet);
flag++;
}
n--;
}while(flag>0);
}

void OrdinaBD(TIPO *vet[],int DIM)
{
int i,flag=1,n=DIM-1;
do
{
flag=0;
for(i=0;i<n;i++)
if(*vet[i]<*vet[i+1])
{
Scambia(i,i+1,&*vet);
flag++;
}
n--;
}while(flag>0);
}

void StampaEle(int i,TIPO vet[])
{
printf("\n VET[%d]=%d",i,vet[i]);
}

void Stampa(TIPO vet[],int DIM)
{
int i;
for(i=0;i<DIM;i++)
StampaEle(i,vet);
}

void Occorrenze(TIPO vet[],int DIM)
{
int i,j,num;
for(i=0;i<DIM;i++)
{
num=0;
for(j=0;j<DIM;j++)
if(i>j && vet[i]== vet[j]) break;
else if (vet[i]==vet[j]) num++;
if(num!=0)printf("\nil valore %d e' stato estratto %d volte",vet[i],num);
}
}

int Cerca(int ele,TIPO vet[],int DIM)
{
int i=0;
while((vet[i]!=ele) && i++<DIM);
return i;
}

void Shuffle(TIPO vet[],int DIM)
{
int i;
for(i=0;i<DIM;i++)
Scambia(i,rand()%DIM,vet);
}

void Uscita()
{
printf("\nARRIVEDERCI!");
system("PAUSE");
}

int mcd(int a, int b) //ALGORITMO DI EUCLIDE
{
if (b == 0)
return a;
else
return mcd(b, a % b);
}

int MCD(TIPO vet[],int DIM)
{
int i=0,a=0;
if(vet[PosMin(vet,DIM)]==1) return 1;
if(DIM==1) return vet[0];
while(i<DIM)a=mcd(a,vet[i++]);
return a;
}

int mcm(int a,int b)
{
return (a*b)/mcd(a,b);
}

int MCM(TIPO vet[],int DIM)
{
int i=0,a=1;
if(DIM==1) return vet[0];
while(i<DIM)a=mcm(a,vet[i++]);
return a;
}

int SottoMenu(int n)
{
switch(n)
{
case 3 ... 4:
{
if(primoavvio==0)
printf("\n\tNon hai ancora dichiarato la dimensione del vettore");
else
{
printf("\n\tLa dimensione attuale del vettore e' %d, vuoi cambiarla?",DIM);
printf("\n\t0: Usa la dimensione attuale");
}
printf("\n\t1: Inserisci manualmente la dimensione del vettore");
printf("\n\t2: Genera casualmente la dimensione del vettore");
printf("\n\t3: Torna al menu\n\t");
break;
}
case 10: {
printf("\n\t0: Ordina in verso crescente (ordinamento ingenuo)");
printf("\n\t1: Ordina in verso decrescente (ordinamento ingenuo)");
printf("\n\t2: Ordina in verso crescente (bubble sort)");
printf("\n\t3: Ordina in verso decrescente (bubble sort)");
printf("\n\t4: Torna al menu\n\t");
break;}
}
}

void SottoScelta(int n,TIPO *vet[],int *DIM)
{
SottoMenu(n);
switch(n)
{
case 3:{
switch(Accetta())
{
case 1: DimVet(&*vet,&*DIM);break;
case 2: RandDIM(&*vet,&*DIM);break;
}
CaricaVet(&*vet,&*DIM);
break;
}
case 4:{
switch(Accetta())
{
case 1: DimVet(&*vet,&*DIM);break;
case 2: RandDIM(&*vet,&*DIM);break;
}
RandVet(&*vet,&*DIM);
break;
}
case 10:{
switch(Accetta())
{
case 0: OrdinaC(&*vet,&*DIM);break;
case 1: OrdinaD(&*vet,&*DIM);break;
case 2: OrdinaBC(&*vet,&*DIM);break;
case 3: OrdinaBD(&*vet,&*DIM);break;
}
Stampa(*vet,*DIM);break;
}
}
}

int Menu()
{
int temp=0;
void PrimiQuattro()
{
printf("\n");
printf("\nSchiaccia il tasto relativo alla funzione che vuoi attivare %d",DIM);
printf("\n0: Uscita");
printf("\n1: Definisci dimensione del vettore");
printf("\n2: Genera casualemente la dimensione del vettore");
printf("\n3: Inserisci manualmente gli elementi del vettore");
printf("\n4: Genera casualmente gli elementi del vettore\n");
}


system("cls");
if(primopopolo==0)
{
if(primoavvio==0) printf("\nProgramma per la gestione dei vettori\nPer iniziare dichiara la dimensione del vettore");
else printf("\nDevi ancora popolare il vettore");
PrimiQuattro();
return Accetta();
}
PrimiQuattro();
printf("5: Estrai il minimo dal vettore");
printf("\n6: Estrai il massimo dal vettore");
printf("\n7: Calcola la media intera");
printf("\n8: Calcola la media reale");
printf("\n9: Estrai il valore piu' vicino alla media");
printf("\n10: Ordina il vettore");
printf("\n11: Stampa il vettore");
printf("\n12: Stampa un elemento del vettore");
printf("\n13: Calcola occorrenze");
printf("\n14: Cerca elemento nel vettore");
printf("\n15: Mischia il vettore");
printf("\n16: Calcola M.C.D. e m.c.m.");
printf("\n");
return Accetta();
}

void Scelta(TIPO *vet[],int *DIM)
{
int temp,a;
do
{
do
{
temp=Menu();
}
while((primopopolo==0 && (temp<0 || temp>4))||(primopopolo!=0 && (temp<0 || temp>16)));
switch (temp)
{
case 1: DimVet(&*vet,&*DIM);break;
case 2: RandDIM(&*vet,&*DIM);break;
case 3: SottoScelta(temp,&*vet,&*DIM);break;
case 4: SottoScelta(temp,&*vet,&*DIM);break;
case 5: printf("\nIl minimo vale %d ed occupa la posizione %d", *vet[PosMin(*vet,*DIM)],PosMin(*vet,*DIM));break;
case 6: printf("\nIl massimo vale %d ed occupa la posizione %d", *vet[PosMax(*vet,*DIM)],PosMax(*vet,*DIM));break;
case 7: printf("\nLa media intera vale %d",MediaInt(*vet,*DIM));break;
case 8: printf("\nLa media reale vale %f",MediaFloat(*vet,*DIM));break;
case 9: printf("\nIl valore piu' vicino alla media vale %d e occupa la posizione %d",*vet[Scarto(*vet,*DIM)],Scarto(*vet,*DIM));break;
case 10: SottoScelta(temp,&*vet,*DIM);break;
case 11: Stampa(*vet,*DIM);break;
case 12: {do{printf("\nInserisci la posizione dell'elemento che vuoi stampare (tra 0 a %d)",*DIM-1);scanf("%d",&a);}while(a<0 || a>=*DIM);StampaEle(a,*vet);break;}
case 13: Occorrenze(*vet,*DIM);break;
case 14: {printf("\n\nInserisci il valore dell'elemento che vuoi cercare ");Cerca(Accetta(),*vet,*DIM);break;}
case 15: {Shuffle(&*vet,*DIM);Stampa(*vet,*DIM);break;}
case 16: printf("\nIl massimo comune divisore vale: %d\nIl minimo comune 7multiplo vale: %d",MCD(*vet,*DIM),MCM(*vet,*DIM));break;
}
printf("\n\nPremere un tasto per continuare...");
getch();
}
while(temp!=0);
}

int main()
{
TIPO *vet=malloc(sizeof(TIPO) * DIM);
srand(time(NULL));
Scelta(&*vet,&DIM);
Uscita();
free(vet);
vet=NULL;
return 0;
}