#include<iostream>
#include<conio.h>
#include<stdio.h>
using namespace std;
const int n=10;

//dichiarazione vettore  
int v[n];
/*****************************
prototipi delle funzioni
cioè   dichiarazioni di tutte le funzioni  del programma
chiuse dal  ; 
*******************************/
void carica(int v[n]);
void stampa(int v[n]);
void ricerca_molti(int v[n]);
void ricerca_uno(int v[n]);
void ordina_primometodo(int v[n]);
void ordina_secondometodo(int v[n]);
/**************************************************************************
in tutte le funzioni precedenti il passaggio del vettore è  per variabile
perchè alla struttura vettore è sempre associato l'indirizzo del suo primo elemento
anche senza il simbolo &
******************************************************************************/
void scambio (int &x, int &y);
//questa procedura scambia due interi passati per variabile


int main() //inizio programma principale
{
 int risp; //variabile di scelta
 /*********************************
  inizio ciclo del menu per
  consentire all'utente di scegliere piu' funzionalità
  fino alla digitazione del tasto di uscita
  
 *********************************************************************/
 do             //inizio menu di scelta
  {
    cout<<"digita :"<<endl;
    cout<<"1 carica vett"<<endl;
    cout<<"2 stampa vett"<<endl;
    cout<<"3 ricerca molti"<<endl;
    cout<<"4 ricerca uno"<<endl;
    cout<<"5 primo metodo di ordinamento"<<endl;
    cout<<"6 secondo metodo di ordinamento"<<endl;
    cout<<"7 per uscire"<<endl;
    cin>>risp;    //scelta dell'utente
    switch(risp)   //inizio selezione multipla
        {
                case 1:carica(v);break;
                case 2:stampa(v);break;
                case 3:ricerca_molti(v);break;
                case 4:ricerca_uno(v);break;
                case 5:ordina_primometodo(v);break;
                case 6:ordina_secondometodo(v);break;
        };
   }
 while(risp!=7);   //quando risp è = a 7 termina il ciclo
}

/***************************************************
esaminiamo meglio il passaggio dei parametri
in fase dichiarativa
       void carica(int v[n]) 
vengono inseriti tra () i parametri FORMALI,  cioè il tipo delle variabili
sulle quali la  funzione lavora ed il nome utilizzato per il parametro non ha importanza 

in fase di chiamata
        case 1:carica(v);
vengono inseriti tra () i parametri ATTUALI,  cioè l'effettivo nome delle variabili; 
il nome utilizzato è molto importante, perchè indica su quali variabili del programma
agirà la funzione in esecuzione. 
E' inoltre fondamentale rispettare la coerenza tra tipo e numero dei parametri tra i 
prototipi delle funzioni e le successive implementazioni (cioè le istruzione scritte 
per ogni funzione dopo il main) e tra queste e le chiamate nel programma principale

***************************************************************************/
/*implementazione delle procedure sopra dichirate
 da notare come le dichiarazione NON devono terminare con ; */
void carica(int v[n])
{
     int i;
     
     for(i=0;i<n;i++)
     {
        cout<<"inserisci il valore:  "<<i<<" °";
        cin>>v[i];
     };
}

void stampa(int v[n])
{
     int i;
     for(i=0;i<n;i++)
     cout<<"il valore  "<<i<<" ° e': "<<v[i]<<endl;
     system("pause");
}
void ricerca_molti(int v[n])
{
     int i,k;
     cout<<"inserisci un valore da ricercare presente molte volte  ";
     cin>>k;
     for(i=0;i<n;i++)
       {
        if(v[i]==k)
         cout<<"il valore si trova in posizione :"<<i<<endl;
          }
     system("pause");
}
void ricerca_uno(int v[n])
{
     int k;
     cout<<"inserisci un valore da ricercare presente una sola volta  ";
     cin>>k;
     int i=0;//inizializzare sempre le variabili locali
     while (v[i]!=k &&i<n-1)
       i=i+1;
     if(v[i]==k)
         cout<<"trovato in posizione"<<i<<endl;
     else 
        cout<<"non presente"<<endl;         
     system("pause");
}
//procedura da richiamare negli ordinamenti
void scambio (int &x, int &y)
 {
   int appo;
   appo=x;
   x=y;
   y=appo;
   }
   
/*questo primo metodo  ordina grazie ad un ciclo precondizionato
una variabile viene usata come flag  per consentire l'uscita quando il vettore 
risulterà completamente ordinato
il numero di cicli è quindi variabile da un'esecuzione all'altra, in base alla grado di disordine 
del vettore */   
void ordina_primometodo(int v[n])
{
     int i;
     float appo;
     bool flag=true;
     while (flag==true) 
      {
      flag=false; 
      for(i=0;i<n-1;i++)
      {
      if(v[i]>v[i+1])
      {
       scambio(v[i],v[i+1]);      
       flag=true;
       }
       }
}
  }  
  
 /*questo secondo metodo ordina attraverso il confronto tra ogni elemento del
 vettore e tutti gli altri, il numero di scansioni è fisso ed indipendente dalla
 situazione di disordine del vettore*/
void ordina_secondometodo(int v[n])
{ 
     float appo;
     int i,j;
     for(i=0;i<n-1;i++)
        for(j=i+1;j<n;j++)
            if(v[i]>v[j]) 
               scambio(v[i],v[j]);
   
 }     

