Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - problema passaggio di parametri
Forum - C/C++ - problema passaggio di parametri

Avatar
grasszilla (Normal User)
Newbie


Messaggi: 4
Iscritto: 07/02/2013

Segnala al moderatore
Postato alle 12:20
Lunedì, 20/05/2013
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:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <conio.h>
  4. #define TIPO int
  5. TIPO MAX = 100;
  6. TIPO MIN = 1;
  7. int DIM = 0;
  8. int primoavvio=0;
  9. int primopopolo=0;
  10.  
  11.  
  12. TIPO Accetta()
  13. {
  14.     TIPO temp;
  15.     scanf("%d",&temp);
  16.     while ( getchar() != '\n' );
  17.     return temp;
  18. }
  19.  
  20. void DimVet()
  21. {
  22.     int temp=DIM;
  23.     do
  24.     {
  25.             printf("\n\nInserisci la nuova dimensione del vettore(intero positivo maggiore di zero): ");
  26.             DIM=Accetta();
  27.     }while(DIM<=0);
  28.     printf("\nLa nuova nuova dimensione del vettore e' %d\n", DIM);
  29.     primoavvio=1;
  30.     if(temp<DIM) primopopolo=0;
  31. }
  32.  
  33. void RandDIM()
  34. {
  35.     int temp=DIM,MIN,MAX;
  36.     printf("\nDefinisci l'intervallo di estrazione (min e max) ");
  37.     do{printf("\nMIN = ");MIN=Accetta();}while(MIN<0);
  38.     do{printf("\nMAX = ");MAX=Accetta();}while(MAX<MIN);
  39.     DIM=rand()%(MAX-MIN+1)+MIN;
  40.     printf("\nLa nuova nuova dimensione del vettore e' %d\n", DIM);
  41.     primoavvio=1;
  42.     if(temp<DIM) primopopolo=0;
  43. }
  44.  
  45. void CaricaVet(TIPO vet[],int DIM)
  46. {
  47.     int i;
  48.     for(i=0;i<DIM;i++)
  49.     {
  50.  
  51.         printf("\nInserisci l'elemento del vettore di posto %d:  ",i);
  52.         vet[i]=Accetta();
  53.     }
  54.     primopopolo=1;
  55. }
  56.  
  57. void RandVet(TIPO vet[],int DIM)
  58. {
  59.     int i;
  60.     printf("\nDefinisci l'intervallo di estrazione degli elementi del vettore (min e max) ");
  61.     printf("\nMIN = ");MIN=Accetta();
  62.     do{printf("\nMAX = ");MAX=Accetta();}while(MAX<MIN);
  63.     for(i=0;i<DIM;i++)
  64.     {
  65.         vet[i]=rand()%(MAX-MIN+1)+MIN;
  66.         printf("\nVET[%d]=%d",i,vet[i]);
  67.     }
  68.     primopopolo=1;
  69. }
  70.  
  71. void Scambia(int a,int b,TIPO vet[])
  72. {
  73.     TIPO temp=vet[a];
  74.     vet[a]=vet[b];
  75.     vet[b]=temp;
  76. }
  77.  
  78. int PosMin(TIPO vet[],int DIM)
  79. {
  80.     int i,posmin=0;
  81.     for(i=1;i<DIM;i++)
  82.         if(vet[posmin]>vet[i]) posmin=i;
  83.  
  84.     return posmin;
  85. }
  86.  
  87. int PosMax(TIPO vet[],int DIM)
  88. {
  89.     int i,posmax=0;
  90.     for(i=1;i<DIM;i++)
  91.         if(vet[posmax]<vet[i]) posmax=i;
  92.     return posmax;
  93. }
  94.  
  95. int MediaInt(TIPO vet[],int DIM)
  96. {
  97.     TIPO media=0;
  98.     int i;
  99.     for(i=0;i<DIM;i++)
  100.         media+=vet[i];
  101.  
  102.     return (int) media/DIM;
  103. }
  104.  
  105. float MediaFloat(TIPO vet[],int DIM)
  106. {
  107.     float media=0;
  108.     int i;
  109.     for(i=0;i<DIM;i++)
  110.         media+=vet[i];
  111.  
  112.     return (float) media/DIM;
  113. }
  114.  
  115. int Scarto(TIPO vet[],int DIM)
  116. {
  117.     int i,posmin=0,media=MediaInt(vet,DIM);
  118.     for(i=1;i<DIM;i++)
  119.             if(abs(media-vet[posmin])>abs(media-vet[i])) posmin=i;
  120.  
  121.     return posmin;
  122. }
  123.  
  124. void OrdinaC(TIPO vet[],int DIM)
  125. {
  126.     int i,j,pos;
  127.     for(i=0;i<DIM;i++)
  128.         {
  129.             pos=i;
  130.             for(j=i+1;j<DIM;j++)
  131.                 if(vet[j]<vet[pos])pos=j;
  132.                 Scambia(i,pos,vet);
  133.         }
  134. }
  135.  
  136. void OrdinaD(TIPO vet[],int DIM)
  137. {
  138.     int i,j,pos;
  139.         for(i=0;i<DIM;i++)
  140.             {
  141.                 pos=i;
  142.                 for(j=i+1;j<DIM;j++)
  143.                     if(vet[j]>vet[pos])pos=j;
  144.                 Scambia(i,pos,vet);
  145.             }
  146. }
  147.  
  148. void OrdinaBC(TIPO vet[],int DIM)
  149. {
  150.     int i,flag=1,n=DIM-1;
  151.     do
  152.     {
  153.         flag=0;
  154.         for(i=0;i<n;i++)
  155.             if(vet[i]>vet[i+1])
  156.             {
  157.                 Scambia(i,i+1,vet);
  158.                 flag++;
  159.             }
  160.         n--;
  161.     }while(flag>0);
  162. }
  163.  
  164. void OrdinaBD(TIPO vet[],int DIM)
  165. {
  166.     int i,flag=1,n=DIM-1;
  167.     do
  168.     {
  169.         flag=0;
  170.         for(i=0;i<n;i++)
  171.             if(vet[i]<vet[i+1])
  172.             {
  173.                 Scambia(i,i+1,vet);
  174.                 flag++;
  175.             }
  176.         n--;
  177.     }while(flag>0);
  178. }
  179.  
  180. void StampaEle(int i,TIPO vet[])
  181. {
  182.     printf("\n VET[%d]=%d",i,vet[i]);
  183. }
  184.  
  185. void Stampa(TIPO vet[],int DIM)
  186. {
  187.     int i;
  188.     for(i=0;i<DIM;i++)
  189.         StampaEle(i,vet);
  190. }
  191.  
  192. void Occorrenze(TIPO vet[],int DIM)
  193. {
  194.     int i,j,num;
  195.     for(i=0;i<DIM;i++)
  196.         {
  197.                 num=0;
  198.                 for(j=0;j<DIM;j++)
  199.                         if(i>j && vet[i]== vet[j]) break;
  200.                         else if (vet[i]==vet[j]) num++;
  201.         if(num!=0)printf("\nil valore %d e' stato estratto %d volte",vet[i],num);
  202.     }
  203. }
  204.  
  205. int Cerca(int ele,TIPO vet[],int DIM)
  206. {
  207.     int i=0;
  208.     while((vet[i]!=ele) && i++<DIM);
  209.     return i;
  210. }
  211.  
  212. void Shuffle(TIPO vet[],int DIM)
  213. {
  214.     int i;
  215.     for(i=0;i<DIM;i++)
  216.         Scambia(i,rand()%DIM,vet);
  217. }
  218.  
  219. void Uscita()
  220. {
  221.     printf("\nARRIVEDERCI!");
  222.     system("PAUSE");
  223. }
  224.  
  225. int mcd(int a, int b) //ALGORITMO DI EUCLIDE
  226. {
  227. if (b == 0)
  228. return a;
  229. else
  230. return mcd(b, a % b);
  231. }
  232.  
  233. int MCD(TIPO vet[],int DIM)
  234. {
  235.     int i=0,a=0;
  236.     if(vet[PosMin(vet,DIM)]==1) return 1;
  237.     if(DIM==1) return vet[0];
  238.     while(i<DIM)a=mcd(a,vet[i++]);
  239.     return a;
  240. }
  241.  
  242. int mcm(int a,int b)
  243. {
  244.     return (a*b)/mcd(a,b);
  245. }
  246.  
  247. int MCM(TIPO vet[],int DIM)
  248. {
  249.     int i=0,a=1;
  250.     if(DIM==1) return vet[0];
  251.     while(i<DIM)a=mcm(a,vet[i++]);
  252.     return a;
  253. }
  254.  
  255. int SottoMenu(int n)
  256. {
  257.         switch(n)
  258.         {
  259.             case 3 ... 4:
  260.                 {
  261.                 if(primoavvio==0)
  262.                     printf("\n\tNon hai ancora dichiarato la dimensione del vettore");
  263.                 else
  264.                     {
  265.                     printf("\n\tLa dimensione attuale del vettore e' %d, vuoi cambiarla?",DIM);
  266.                     printf("\n\t0: Usa la dimensione attuale");
  267.                     }
  268.                 printf("\n\t1: Inserisci manualmente la dimensione del vettore");
  269.                 printf("\n\t2: Genera casualmente la dimensione del vettore");
  270.                 printf("\n\t3: Torna al menu\n\t");
  271.                 break;
  272.                 }
  273.             case 10: {
  274.                 printf("\n\t0: Ordina in verso crescente (ordinamento ingenuo)");
  275.                 printf("\n\t1: Ordina in verso decrescente (ordinamento ingenuo)");
  276.                 printf("\n\t2: Ordina in verso crescente (bubble sort)");
  277.                 printf("\n\t3: Ordina in verso decrescente (bubble sort)");
  278.                 printf("\n\t4: Torna al menu\n\t");
  279.                 break;}
  280.         }
  281. }
  282.  
  283. void SottoScelta(int n,TIPO vet[],int DIM)
  284. {
  285.     SottoMenu(n);
  286.     switch(n)
  287.     {
  288.         case 3:{
  289.                 switch(Accetta())
  290.                 {
  291.                 case 1: DimVet();break;
  292.                 case 2: RandDIM();break;
  293.                 }
  294.                 CaricaVet(vet,DIM);
  295.                 break;
  296.                 }
  297.         case 4:{
  298.                 switch(Accetta())
  299.                 {
  300.                 case 1: DimVet();break;
  301.                 case 2: RandDIM();break;
  302.                 }
  303.                 RandVet(vet,DIM);
  304.                 break;
  305.                 }
  306.         case 10:{
  307.                 switch(Accetta())
  308.                 {
  309.                 case 0: OrdinaC(vet,DIM);break;
  310.                 case 1: OrdinaD(vet,DIM);break;
  311.                 case 2: OrdinaBC(vet,DIM);break;
  312.                 case 3: OrdinaBD(vet,DIM);break;
  313.                 }
  314.                 Stampa(vet,DIM);break;
  315.                 }
  316.         }
  317. }
  318.  
  319. int Menu()
  320. {
  321.     int temp=0;
  322.     void PrimiQuattro()
  323.     {
  324.         printf("\n");
  325.         printf("\nSchiaccia il tasto relativo alla funzione che vuoi attivare");
  326.         printf("\n0: Uscita");
  327.         printf("\n1: Definisci dimensione del vettore");
  328.         printf("\n2: Genera casualemente la dimensione del vettore");
  329.         printf("\n3: Inserisci manualmente gli elementi del vettore");
  330.         printf("\n4: Genera casualmente gli elementi del vettore\n");
  331.     }
  332.  
  333.  
  334.     system("cls");
  335.     if(primopopolo==0)
  336.         {
  337.         if(primoavvio==0)   printf("\nProgramma per la gestione dei vettori\nPer iniziare dichiara la dimensione del vettore");
  338.         else    printf("\nDevi ancora popolare il vettore");
  339.         PrimiQuattro();
  340.         return Accetta();
  341.         }
  342.     PrimiQuattro();
  343.     printf("5: Estrai il minimo dal vettore");
  344.     printf("\n6: Estrai il massimo dal vettore");
  345.     printf("\n7: Calcola la media intera");
  346.     printf("\n8: Calcola la media reale");
  347.     printf("\n9: Estrai il valore piu' vicino alla media");
  348.     printf("\n10: Ordina il vettore");
  349.     printf("\n11: Stampa il vettore");
  350.     printf("\n12: Stampa un elemento del vettore");
  351.     printf("\n13: Calcola occorrenze");
  352.     printf("\n14: Cerca elemento nel vettore");
  353.     printf("\n15: Mischia il vettore");
  354.     printf("\n16: Calcola M.C.D. e m.c.m.");
  355.     printf("\n");
  356.     return Accetta();
  357. }
  358.  
  359. void Scelta(int vet[],int DIM)
  360. {
  361.     int temp,a;
  362.     do
  363.         {
  364.         do
  365.             {
  366.             temp=Menu();
  367.             }
  368.         while((primopopolo==0 && (temp<0 || temp>4))||(primopopolo!=0 && (temp<0 || temp>16)));
  369.         switch (temp)
  370.             {
  371.             case 1: DimVet();break;
  372.             case 2: RandDIM();break;
  373.             case 3: SottoScelta(temp,vet,DIM);break;
  374.             case 4: SottoScelta(temp,vet,DIM);break;
  375.             case 5: printf("\nIl minimo vale %d ed occupa la posizione %d", vet[PosMin(vet,DIM)],PosMin(vet,DIM));break;
  376.             case 6: printf("\nIl massimo vale %d ed occupa la posizione %d", vet[PosMax(vet,DIM)],PosMax(vet,DIM));break;
  377.             case 7: printf("\nLa media intera vale %d",MediaInt(vet,DIM));break;
  378.             case 8: printf("\nLa media reale vale %f",MediaFloat(vet,DIM));break;
  379.             case 9: printf("\nIl valore piu' vicino alla media vale %d e occupa la posizione %d",vet[Scarto(vet,DIM)],Scarto(vet,DIM));break;
  380.             case 10: SottoScelta(temp,vet,DIM);break;
  381.             case 11: Stampa(vet,DIM);break;
  382.             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;}
  383.             case 13: Occorrenze(vet,DIM);break;
  384.             case 14: {printf("\n\nInserisci il valore dell'elemento che vuoi cercare ");Cerca(Accetta(),vet,DIM);break;}
  385.             case 15: {Shuffle(vet,DIM);Stampa(vet,DIM);break;}
  386.             case 16: printf("\nIl massimo comune divisore vale: %d\nIl minimo comune multiplo vale: %d",MCD(vet,DIM),MCM(vet,DIM));break;
  387.             }
  388.         printf("\n\nPremere un tasto per continuare...");
  389.         getch();
  390.         }
  391.     while(temp!=0);
  392. }
  393.  
  394. int main()
  395. {
  396.     TIPO vet[DIM];
  397.     srand(time(NULL));
  398.     Scelta(vet,DIM);
  399.     Uscita();
  400.     return 0;
  401. }




grazie mille in anticipo

Ultima modifica effettuata da grasszilla il 20/05/2013 alle 13:41
PM Quote
Avatar
grasszilla (Normal User)
Newbie


Messaggi: 4
Iscritto: 07/02/2013

Segnala al moderatore
Postato alle 13:17
Lunedì, 20/05/2013
mi sono appena accorto di aver sbagliato sezione, mi scuso e chiedo gentilmente di sposrtarla

PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 22:51
Lunedì, 20/05/2013
Topic spostato.


Il mio blog: https://piero.dev
PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 23:24
Martedì, 21/05/2013
Testo quotato

Postato originariamente da grasszilla:
il codice funziona, perchè se dichiaro il vettore come variabile globale funziona benissimo.



Il codice "funziona" quando dichiari la variabile come globale per pura fortuna (e probabilmente per vettori di piccole dimensioni). Prova ad inserire un vettore di grandi dimensioni, e vedi se funziona...

Il problema parte da qui:

Codice sorgente - presumibilmente C/C++

  1. TIPO vet[DIM];
  2.     srand(time(NULL));
  3.     Scelta(vet,DIM);
  4.     Uscita();
  5.     return 0;



DIM e' 0. Il tuo codice alloca un vettore di un solo elemento (nello stack). Quando poi lo passi alle funzioni e inserisci piu' di un elemento, il tuo codice sovvrascrive lo stack (e causa un molto probabile crash nelle migliore delle ipotesi, dei risultati sbagliati nelle peggiori).

La soluzione piu' semplice (non ottimale) e' quella di allocare spazio sufficiente per poter contenere gli elementi che un utente inserira' (MAX_INT - 1 probabilmente e' un buon numero).

Siccome sei uno studente, ti consiglio di leggere meglio come funziona l'allocazione delle variabili, la differenza tra stack e heap e un po' di basi del C in generale (ma che libro usano all'universita'?)


Il mio blog: https://piero.dev
PM Quote