Discussione Ufficiale Programmiamo con Inforge | Esercitazione 01 in C | Livello base

Una Discussione Ufficiale punta a raccogliere tutte le informazioni su un argomento o un fatto di attualità, con costanti aggiornamenti da parte del creatore e dei partecipanti.
Visualizza allegato 50142

Presentazione - Programmiamo con Inforge

Ad oggi, sul web, si trovano moltissime guide sui vari linguaggi di programmazione e sulle loro molteplici applicazioni. Tuttavia, chi si approccia a queste risorse, non sempre riesce a mettere in pratica ciò che ha appreso. Al fine di limitare queste mancanze, nasce Programmiamo con Inforge.

In questa rubrica potrai scrivere codice per la risoluzione di alcuni problemi legati alla programmazione, mettendo in pratica quanto stai apprendendo dalla teoria oppure mostrando le tue abilità e competenze nel campo dell’informatica.


Esercitazione 01 in C | Livello base
L'esercitazione si compone di 7 esercizi nei quali ti sarà richiesto di definire una serie di funzioni utili per lo svolgimento di diverse operazioni sugli array. Una volta scritte le funzioni, dovrai richiamarle nel main() e chiedere all'utente di svolgerle.

*** Hidden text: cannot be quoted. ***

Soluzioni
*** Hidden text: cannot be quoted. ***

Conclusioni
Ricorda che puoi confrontarti con il resto della community in questo thread, chiedere aiuto o aiutare gli altri ;)
Bella idea
 
Ultima modifica:
PS: già che ci sono levatemi un dubbio. Come si fa rendere i messaggi visibili solo se si risponde a 3d?

Secondo me conviene pubblicare sotto spoiler, così da occupare meno spazio nel thread e soprattutto lasciare a chi partecipa la scelta di visualizzare una soluzione oppure no. ;)


Ps. in teoria dovresti utilizzare C e non C++
 
Aggiungo rispetto al mio commento precedente che, al di la dei codici, apprezzo molto la vostra voglia di mettervi in gioco. Il confronto e le opinioni (se costruttive) sono caratteri alla base della nostra community. Quindi grazie per il vostro tempo e ricordo che l'esercitazione è sempre aperta a tutti! Mettetevi in gioco, soprattutto se non siete abili in C, sfruttate queste occasioni per capire quale sia il vostro livello di comprensione del linguaggio e provate a migliorarlo insieme a noi!
 
Al di la di un errore sulle firme di una funzione, come citato sopra, ci possono essere dei piccoli accorgimenti per non utilizzare variabili temporanee e render il codice più compatto, semplice e comprensibile... per il resto è perfetto. Ottimo lavoro @GabryBarbe
Grazie @Kode . Quali punti potrebbero essere snelliti?

Per quanto dice invece @DispatchCode , in che modo potrei ottimizzare lo scope delle variabili?
 
Ultima modifica:
@Kode una cosa sul chiamare le funzioni: di solito non si fa una cosa simile? Nel senso, si crea un .lib in cui inserisci le funzioni che poi richiami in diversi programmi, qui le ho scritte direttamente nello stesso file però il richiamarle dovrebbe essere qualcosa di "normale", o ricordo male?

Modificato un pò di cose per renderlo un pò meno 'meccanico', ma ancora il print dei valori mi restituisce tutti 0, e non capisco cos'altro c'è da cambiare oltre a double->float.

Anzi ora che ci penso, non dovrebbe neanche stampare i valori in automatico per come l'ho scritto, anche peggio.

C++:
#include <stdio.h>
#include <math.h>
#include <iostream>
#include <fstream>




float array_mean(float arr_1[],int dim)
{

float med=0,temp=0;

    for(int i=0;i<dim;i++)
    {
        temp+=arr_1[i];
    }
   
    return temp/dim;
}

}


void array_print_to_screen(float arr_1[],int dim)
{
    for(int i=0;i<dim;i++)
    {
        printf("\narr_1[%d]= %f",i,arr_1[i]);
    }
}


void array_input(float arr_1[],int dim)
{
    for(int i=0;i<dim;i++)
    {
        printf("\nInserire %do valore: ",i+1);
        scanf("%f",&arr_1[i]);
    }  
}


float* array_alloc(int dim)
{
    float* arr_1;
    arr_1=(float*)malloc(dim*sizeof(float));
    if (arr_1 == NULL) {
        printf("\nMalloc non riuscito.");
        exit(0);
    }
    else
    {
        printf("\nMalloc riuscito.");
    }

    return arr_1;
}


float array_min_index(float arr_1[],int dim)
{
    float min=0;

    for(int i=1;i<=dim;i++)
    {
        if(arr_1[i-1]<arr_1[i])
        {
            min=arr_1[i-1];
        }
        else
        {
            min=arr_1[i];
        }
    }

    return min;
}


float array_sort(float arr_1[],int dim)
{
    for(int i=0; i<dim; i++)
    {
        for(int j=i+1;j<dim;j++)
        {
            if(arr_1[j]<arr_1[i])
            {
                float temp;
                temp=arr_1[j];
                arr_1[j]=arr_1[i];
                arr_1[i]=temp;                          
            }  
        }
    }
}


void array_write_to_file(float arr_1[],int dim,FILE* Wfile)
{
    for(int i=0;i<dim;i++)
    {
        fprintf(Wfile,"%d.%f\n",i+1,arr_1[i]);
    }
}

void scelta(int menu,float arr_1[],int dim)
{
    bool close=false;
    do
    {
        switch(menu)
        {
            case 0://CHIUSURA
            {
                close==true;
                printf("\nChiusura...");
                break;
            }
      
            case 1://STAMPA ARRAY
            {
                array_print_to_screen(arr_1,dim);
                break;
            }
      
            case 2://ORDINAMENTO ARRAY
            {
                array_sort(arr_1,dim);
                break;
            }
      
            case 3://SCRITTURA FILE
            {
                array_print_to_screen(arr_1,dim);
                break;
            }
      
            case 4://MEDIA
            {
                array_mean(arr_1,dim);
                break;
            }
      
            case 5://MINIMO
            {
                array_min_index(arr_1,dim);
                break;
            }
      
            default://INPUT NON VALIDO
            {
                printf("\nInserisci un numero da 1 a 5 per continuare, 0 per terminare.\n");
                printf("1.arrayPrint\n2.arraySort\n3.writeOnFile\n4.arrayMean\n5.arrayMinIndex\n0.Close)");
                break;
            }
        }
    }while(menu!=0 && close==false);
}


int main()
{
    int dim=0,menu;
    printf("Dimensione array: ");
    scanf("%d",&dim);

    float* arr_1;
    FILE * Wfile;

    arr_1=array_alloc(dim);
    array_input(arr_1,dim);


    Wfile=fopen("values.dat","w");
    if (arr_1 != NULL)
    {
        printf("1.arrayPrint\n2.arraySort\n3.writeOnFile\n4.arrayMean\n5.arrayMinIndex\n0.Close)");
        scanf("%d",&menu);
        scelta(menu,arr_1,dim);
    }

    fclose(Wfile);

    free(arr_1);

    return 0;
}
 
Ultima modifica:
@Kode il malloc.h non sono sicuro del perché l'ho messo, forse pensavo che per usare il malloc servisse la libreria o.ò
La funzione del minore dovrei averla sistemata, o almeno in un file nuovo funziona (e mi sembra di aver capito che il return funziona solo con numeri interi, e i float li arrotonda, quindi tocca per forza fare una stampa?)
C++:
void array_min_index(float arr_1[],int dim)
{
float min=arr_1[0];

    for(int i=1;i<dim;i++)
    {
        if(arr_1[i]<arr_1[0] && arr_1[i]<min)
            {
                min=arr_1[i];            
            }
    }
    printf("\nMin=%f",min);
    //return min;
}

Scelta l'ho messa per fare in modo che si potessero richiamare le funzioni tutte le volte che si vuole fino a che non si "chiude il menu", senza star a eseguire di continuo.
Probabilmente va in loop per il default, così su due piedi: ho cercato velocemente un modo per controllare che l'input rientrasse nel range richiesto da me(da 0 a x ovvero il numero di funzioni da mettere dentro lo switch, e ora che ci penso avrei potuto anche mettere un controllo per evitare lettere, caratteri speciali etc.) e consigliavano di farlo in una funzione, così da richiamarla nel default per "resettarla" ma immagino che vada fatto in un certo modo.
Al momento non conosco altri metodi per resettare uno switch.
 
Ci siamo quasi, hai sistemato il punto di partenza, ossia hai assegnato per default che il minimo fosse il primo elemento. Ora basta vedere solamente se un elemento i-esimo è minore del minimo corrente, se lo è lo assegni a min altrimenti vai avanti. Per quanto riguarda il ciclo conta che facendo cosi dovresti andare in overflow. Perché? Perché gli indici di un array con n elementi va da 0 a n-1, quindi quando legge arr_1[n] vai fuori dall'area di memoria dell'array instanziato.
i<dim non va bene? Su {5,4,3,2,1} i[0] non lo controllo, quindi con un ciclo che va da [1] a [4] ovvero i<dim=5 non dovrebbe avere problemi, o no?
Per quanto riguarda lo statement nella clausola if il fatto che dovresti controllare ogni valore dell'array con l'elemento della prima cella può essere evitato.Perchè? Perché a te interessa solamente il confronto con il valore minimo corrente salvato all'interno della variabile min. Per quanto riguarda la stampa puoi benissimo metterla fuori e porre il valore di ritorno a float dato che è un float e fuori ti prelevi il valore come se fosse un float quindi puoi benissimo spostare quella stampa anche fuori.

In sintesi:
C:
// da void a float
float array_min_index(float arr_1[],int dim)
{
float min=arr_1[0];

    for(int i=1;i<dim-1;i++) // da 1 a dim-1, non facciamo il controllo a 0 dato che min = arr_1[0]
    {
        if( arr_1[i]<min) // il confronto solo con il valore min corrente
            {
                min=arr_1[i];           // nel caso sia minore quello letto dall'array, sarà il nuovo minimo
            }
    }
    // printf("\nMin=%f",min); lo possiamo fare fuori
    return min;
}

// [...]

//public void scelta([...]){

// dentro il case di array_min_index...

float x = array_min_index(arr_1, dim);
printf("\nMin=%f\n", min);
break;
Sul doppio controllo ho realizzato adesso che è inutile, non so cos'avevo in testa quando l'ho messo ahahah
Il return però l'ho messo commentato perché arrotondava i decimali, quindi mettendo 1.1 restituiva sempre 1, 0.9 dava 0 etc.
C'è un modo per fare in modo che non accada? O all'eventuale variabile che richiama la funzione arriva lo stesso il valore corretto?
 
i<dim non va bene? Su {5,4,3,2,1} i[0] non lo controllo, quindi con un ciclo che va da [1] a [4] ovvero i<dim=5 non dovrebbe avere problemi, o no?

Sul doppio controllo ho realizzato adesso che è inutile, non so cos'avevo in testa quando l'ho messo ahahah
Il return però l'ho messo commentato perché arrotondava i decimali, quindi mettendo 1.1 restituiva sempre 1, 0.9 dava 0 etc.
C'è un modo per fare in modo che non accada? O all'eventuale variabile che richiama la funzione arriva lo stesso il valore corretto?

Se ad un float assegni un altro float non dovrebbero esserci arrotondamenti dato che il numero è sempre a singola precisione.
 
Se ad un float assegni un altro float non dovrebbero esserci arrotondamenti dato che il numero è sempre a singola precisione.
return int1.png

return int 2.png
return int3.png