Benvenuto su Inforge
Rimuovi la pubblicità e partecipa alla più grande comunità italiana sul mondo digitale presente sul web sin dal 2007.
Iscriviti

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.

GabryBarbe

Utente Bronze
26 Dicembre 2020
59
26
31
C++:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
float vet_mean(float vet[], size_t len){
    size_t i;
    float S=0;
    for(i=0;i<len;i++){
        S=S+vet[i];
    }
    return S/len;
}
void vet_print(float vet[], size_t len){
    size_t i;
    for(i=0;i<len;i++){
        cout  <<  vet[i]  <<  " ";
    }
}
void vet_input(float vet[], size_t len){
    size_t i;
    for(i=0;i<len;i++){
        cout  <<  "Inserisci valore: ";
        cin  >>  vet[i];
    }
}
float *vet_alloc(size_t len){
    return (float*)malloc(len*sizeof(float));
}
size_t vet_min_index(float vet[], size_t len){
    size_t i, m=0;
    for(i=0;i<len;i++){
        if (vet[i]<vet[m])
            m=i;
    }
    return m;
}
float vet_swap(float vet[], size_t i, size_t j){
    float tmp;
    tmp = vet[i];
    vet[i]=vet[j];
    vet[j]=tmp;
}
void vet_sort(float vet[], size_t len){
    size_t i, x;
    for(i=0;i<len;i++){
        x=vet_min_index(&vet[i], len-i);
        vet_swap(vet,i,x+i);
    }
}
void vet_output_file(float vet[], size_t len, FILE *fn, float M){
    size_t i;
    fprintf(fn,"Array ordinato\n");
    for(i=0;i<len;i++)
        fprintf(fn,"%f \n",vet[i]);
    fprintf(fn,"Media dei numeri: ");
    fprintf(fn, "%f", M);
}
int main(){
    float *vet; 
    size_t len;
    FILE* fn;
    float M;
    cout  <<  "Inserisci numero di caratteri Array: ";
    cin  >>  len;
    vet=vet_alloc(len);
    cout  <<  "Riempi Array"  <<  endl;
    vet_input(vet, len);
    cout  <<  "Il tuo Array è: ";
    vet_print(vet, len);
    cout  <<  endl  <<  "Il tuo Array oridnato è: ";
    vet_sort(vet, len);
    vet_print(vet, len);
    fn = fopen("values.dat","w");
    M=vet_mean(vet, len);
    vet_output_file(vet, len, fn, M);
    fclose(fn);
}

Codice molto basico, ma fa quello che deve fare haha.

PS: già che ci sono levatemi un dubbio. Come si fa rendere i messaggi visibili solo se si risponde a 3d?
 
  • Love
Reactions: Not an engineer

Valley

Super Moderatore
Super Moderatore
10 Aprile 2011
12,734
3,125
1,339
C++:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
float vet_mean(float vet[], size_t len){
    size_t i;
    float S=0;
    for(i=0;i<len;i++){
        S=S+vet[i];
    }
    return S/len;
}
void vet_print(float vet[], size_t len){
    size_t i;
    for(i=0;i<len;i++){
        cout  <<  vet[i]  <<  " ";
    }
}
void vet_input(float vet[], size_t len){
    size_t i;
    for(i=0;i<len;i++){
        cout  <<  "Inserisci valore: ";
        cin  >>  vet[i];
    }
}
float *vet_alloc(size_t len){
    return (float*)malloc(len*sizeof(float));
}
size_t vet_min_index(float vet[], size_t len){
    size_t i, m=0;
    for(i=0;i<len;i++){
        if (vet[i]<vet[m])
            m=i;
    }
    return m;
}
float vet_swap(float vet[], size_t i, size_t j){
    float tmp;
    tmp = vet[i];
    vet[i]=vet[j];
    vet[j]=tmp;
}
void vet_sort(float vet[], size_t len){
    size_t i, x;
    for(i=0;i<len;i++){
        x=vet_min_index(&vet[i], len-i);
        vet_swap(vet,i,x+i);
    }
}
void vet_output_file(float vet[], size_t len, FILE *fn, float M){
    size_t i;
    fprintf(fn,"Array ordinato\n");
    for(i=0;i<len;i++)
        fprintf(fn,"%f \n",vet[i]);
    fprintf(fn,"Media dei numeri: ");
    fprintf(fn, "%f", M);
}
int main(){
    float *vet;
    size_t len;
    FILE* fn;
    float M;
    cout  <<  "Inserisci numero di caratteri Array: ";
    cin  >>  len;
    vet=vet_alloc(len);
    cout  <<  "Riempi Array"  <<  endl;
    vet_input(vet, len);
    cout  <<  "Il tuo Array è: ";
    vet_print(vet, len);
    cout  <<  endl  <<  "Il tuo Array oridnato è: ";
    vet_sort(vet, len);
    vet_print(vet, len);
    fn = fopen("values.dat","w");
    M=vet_mean(vet, len);
    vet_output_file(vet, len, fn, M);
    fclose(fn);
}

Codice molto basico, ma fa quello che deve fare haha.

PS: già che ci sono levatemi un dubbio. Come si fa rendere i messaggi visibili solo se si risponde a 3d?
Per commentare il codice passo il compito a @Not an engineer
Per lo spoiler: è disponibile al momento solo allo staff :)
 
  • Mi piace
Reactions: GabryBarbe
Supporta Inforge con una donazione
Lv.105 - Middleschool - International SV

DispatchCode

Moderatore
24 Maggio 2016
380
245
193
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++
 

DispatchCode

Moderatore
24 Maggio 2016
380
245
193
Riporto alcune mie considerazioni taggando chi ha dato la propria soluzione (colgol'occasione per ringraziare anticipatamente chi ha partecipato e sta partecipando!) :)


Ciò detto, ben fatto a tutti e soprattutto grazie per la partecipazione! :)
Se avete domande o volete commentare qualcosa, sentitevi liberi di postare.
 
Lv.105 - Middleschool - International SV
Supporta Inforge con una donazione

Kode

Utente Emerald
10 Dicembre 2013
1,336
334
393
Bene, da Programmatore in C vi do qualche mia considerazione sui codice. Non sono un critico né un esperto in C/C++, quindi ciò che farò è dare solamente la mia opinione personale con il fine di darvi dei feedback in grado di migliorarvi nel coding.

Rispondo e grazie

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

Direi che @demtor abbia fatto un codice impeccabile, ottima gestione delle variabili temporanee andando ad eliminare anche delle linee di codice superflue rispetto alla soluzione ufficiale. Inoltre, io size_t lo uso solamente quando si ha un riferimento di dimensionamento cosa che non si ha ad esempio per la dichiarazione di variabili temporanee utilizzate nei cicli, quindi questo, secondo me, ti dia un punto qualitativo migliore.

Sono più arrugginito di quanto pensassi ma a prima vista la logica penso di averla azzeccata, ovviamente il codice non parte mai al primo tentativo ma lo condivido lo stesso
:rofl:


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


double array_mean(double arr_1[],int dim)
{
    double med=0,temp=0;

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

    return med;
}


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


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


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

    return arr_1;
}


double array_min_index(double arr_1[],int dim)
{
    double 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;
}


double array_sort(double 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(double arr_1[],int dim,FILE* Wfile)
{
    for(int i=0;i<dim;i++)
    {
        fprintf(Wfile,"%d.%f\n",i+1,arr_1[i]);
    }
}


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

    double* arr_1;
    FILE * Wfile;

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

    array_sort(arr_1,dim);
    array_print_to_screen(arr_1,dim);

    Wfile=fopen("values.dat","w");
    if (arr_1 != NULL)
    {
        array_write_to_file(arr_1,dim,Wfile);
    }
    fclose(Wfile);

    free(arr_1);

    return 0;
}

Ottimo controllo per le malloc che non hai dato dentro la funzione di allocazione che sia avvenuta sempre con successo, l'unica pecca qui, rispetto al commento precedente è che non hai minimizzato l'uso di variabili temporanee che, ripeto, non è un errore ma qualitativamente non è ottimale. Nel complesso, ottimo codice @Sax3r28 anche se presenta alcuni errori semantici (provate sempre il codice mi raccomando!) e credo che è solo una bozza di una versione completa viste le chiamate a funzioni del main, o sbaglio?

Ecco il mio codice, spero sia almeno decente ahahah

C++:
#include <iostream>
#include <fstream>


// Calcolo media array (esercizio 1)
float array_mean(float array[], int number_of_items) {
    int i;
    float media;
 
    for(i = 0; i < number_of_items; i++) {
        media = media + array[i];
    }
 
    media = media / number_of_items;
 
    return media;
}

// Stampa array (esercizio 2)
void array_print_to_screen(float array[], int number_of_items) {
 
    using namespace std;
 
    int i;
    for(i = 0; i < number_of_items; i++) {
        cout<<array[i]<<" ";
    }
}


// Richiesta input dei valori float (esercizio 3)
void array_input(float array[], int number_of_items) {
 
    using namespace std;
 
    int i;
    for(i = 0; i < number_of_items; i++) {
        cout<<"\nInserisci "<<i+1<<"*"<<" valore float\n";
        cin>>array[i];
    }
}

// Allocazione array dinamico (esercizio 4)
void array_alloc(float **array, int number_of_items) {
    *array = new float[number_of_items];
}

// Restituzione del numero più piccolo dell'array (esercizio 5)
void array_min_index(float *array, int number_of_items) {
 
    using namespace std;
 
    int i, j, max;
    float com;
     
    // Ordinamento array dal più piccolo al più grande
    for(j = number_of_items-1; j > 0; j--) {
        for(i=0; i<j; i++) {
            if(array[i] > array[i+1]) {
                com = array[i];
                array[i] = array[i+1];
                array[i+1] = com;
            }
        }
    }
    // Stampa array
    cout<<"\nStampa array ordinato ";
    array_print_to_screen(array, number_of_items);
    cout<<"\n";
 
    // Stampa dell'elemento più piccolo
    cout<<"Elemento piu piccolo array: "<<array[0];
}

// Stampa vettore ordinato (esercizio 6) -> Viene già fatto nel 5


// Salvataggio vettore su un file e deallocamento dello stesso (esercizio 7)
void array_write_to_file(float array[], int number_of_items) {
 
    using namespace std;
 
    int i;
 
    ofstream OutFile;
    OutFile.open("values.dat");
    if(!OutFile) {
        cout<<"Error";
    } else {
        OutFile<<"Array:\n";
        for(i=0;i<number_of_items;i++) {
            OutFile<<array[i]<<" ";
        }
        OutFile.close();
    }
}





int main() {
 
    using namespace std;
 
    int number_of_items, i;
    float media;
    float* array;
 
    cout<<"Numero elementi array ";
    cin>>number_of_items;
 
    // Allocazione array dinamico
    array_alloc(&array, number_of_items);
 
    // Richiesta input dei valori float
    array_input(array, number_of_items);
 
 
    // Calcolo media array
    media = array_mean(array, number_of_items);
 
    // Stampa array
    cout<<"\nStampa array ";
    array_print_to_screen(array, number_of_items);
 
    // Numero più piccolo
    array_min_index(array, number_of_items);
 
    // File
    array_write_to_file(array, number_of_items);
 
    cout<<"\nMedia: " << media;
 
    // Deallocazione array (esercizio 8)
    delete[] array;
 
    return 0;
}

Ottimo codice, ho notato giusto qualche piccola ottimizzazione possibile andando a ridurre il numero di variabili temporanee che, ripeto anche questa volta, è solo per "leggerezza del codice" e non di efficienza (in tempi computazionali. non ci sta differenza e qualche byte temporaneo usato in più non è un problema). Unica pecca @ConanDP, Il fatto che tu abbia unito due funzioni (esercizio 5 e 6) non è buono in generale, questo perché quando due funzionalità non sono separate non sono divisibile atomicamente, ergo: non sono singolarmente utilizzabili e si crea un codice meno riutilizzabile.

C++:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
float vet_mean(float vet[], size_t len){
    size_t i;
    float S=0;
    for(i=0;i<len;i++){
        S=S+vet[i];
    }
    return S/len;
}
void vet_print(float vet[], size_t len){
    size_t i;
    for(i=0;i<len;i++){
        cout  <<  vet[i]  <<  " ";
    }
}
void vet_input(float vet[], size_t len){
    size_t i;
    for(i=0;i<len;i++){
        cout  <<  "Inserisci valore: ";
        cin  >>  vet[i];
    }
}
float *vet_alloc(size_t len){
    return (float*)malloc(len*sizeof(float));
}
size_t vet_min_index(float vet[], size_t len){
    size_t i, m=0;
    for(i=0;i<len;i++){
        if (vet[i]<vet[m])
            m=i;
    }
    return m;
}
float vet_swap(float vet[], size_t i, size_t j){
    float tmp;
    tmp = vet[i];
    vet[i]=vet[j];
    vet[j]=tmp;
}
void vet_sort(float vet[], size_t len){
    size_t i, x;
    for(i=0;i<len;i++){
        x=vet_min_index(&vet[i], len-i);
        vet_swap(vet,i,x+i);
    }
}
void vet_output_file(float vet[], size_t len, FILE *fn, float M){
    size_t i;
    fprintf(fn,"Array ordinato\n");
    for(i=0;i<len;i++)
        fprintf(fn,"%f \n",vet[i]);
    fprintf(fn,"Media dei numeri: ");
    fprintf(fn, "%f", M);
}
int main(){
    float *vet;
    size_t len;
    FILE* fn;
    float M;
    cout  <<  "Inserisci numero di caratteri Array: ";
    cin  >>  len;
    vet=vet_alloc(len);
    cout  <<  "Riempi Array"  <<  endl;
    vet_input(vet, len);
    cout  <<  "Il tuo Array è: ";
    vet_print(vet, len);
    cout  <<  endl  <<  "Il tuo Array oridnato è: ";
    vet_sort(vet, len);
    vet_print(vet, len);
    fn = fopen("values.dat","w");
    M=vet_mean(vet, len);
    vet_output_file(vet, len, fn, M);
    fclose(fn);
}

Codice molto basico, ma fa quello che deve fare haha.

PS: già che ci sono levatemi un dubbio. Come si fa rendere i messaggi visibili solo se si risponde a 3d?
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
 

Sax3r28

Utente Gold
8 Aprile 2016
589
293
218
@DispatchCode
Ecco, la cosa del %lf l'avevo totalmente cancellata dalla memoria, e sì ho usato c++ in parte perché ricordavo solo quello dopo quasi 6 anni senza codice, e non avendo tirato dritto in uni, tutto quello che ci mostrarono alle superiori era assembly, c# e c++. Immagino che cambiando da double a float forse funzionerebbe ahahah
Alcune funzioni non le ho richiamate perché non erano elencate nel punto 8 :V che sarebbe tutto quello che ho messo nel main.
Domani mattina lo ricontrollo per bene e vediamo se parte tutto.

@Kode
Sì diciamo che è la bozza di una bozza :rofl: non potevo aspettarmi qualcosa di funzionante e scritto a modo dopo anni in cui non ho scritto quasi niente ahahah
 
  • Mi piace
Reactions: Kode

Kode

Utente Emerald
10 Dicembre 2013
1,336
334
393
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!
 
Lv.105 - Middleschool - International SV
Supporta Inforge con una donazione

GabryBarbe

Utente Bronze
26 Dicembre 2020
59
26
31
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?
 

Sax3r28

Utente Gold
8 Aprile 2016
589
293
218
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;
}
 

DispatchCode

Moderatore
24 Maggio 2016
380
245
193
Grazie @Kode . Quali punti potrebbero essere snelliti?

Per quanto dice invece @DispatchCode , in che modo potrei ottimizzare lo scope delle variabili?

Puoi sia compattarlo che evitare di dare "scope" così ampi. Se tu dichiari la variabile nella parte di inizializzazione del for, quella variabile sarà locale al solo ciclo. Idem le variabili che usi solo nel corpo dei ciclo.

C:
void vet_sort(float vet[], size_t len){
    size_t i, x;
    for(i=0;i<len;i++){
        x=vet_min_index(&vet[i], len-i);
        vet_swap(vet,i,x+i);
    }
}

Quindi in questo caso questa funzione puoi modificarla così:
C:
void vet_sort(float vet[], size_t len){
    for(size_t i=0;i<len;i++){
        size_t x=vet_min_index(&vet[i], len-i);
        vet_swap(vet,i,x+i);
    }
}
 
Lv.105 - Middleschool - International SV
Supporta Inforge con una donazione

Kode

Utente Emerald
10 Dicembre 2013
1,336
334
393
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>
#include <malloc.h>



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;
}
Se intendi un .h per rendere un tuo set di funzione come se fossero funzioni di libreria (quindi includendo con #include <nome.h>) si, ma per programmi semplici come questo è un lavoro un pò oneroso, poi conta che per le funzioni di librerie ci sta un costrutto da dover seguire (se sei curioso vedi stdio.h come è strutturato, al di la delle macro concentrati sulla strutturazione del printf per esempio).

Tralasciando questa piccola parentesi, prima di vedere l'esecuzione del programma ho dato un occhio più attento ad alcune cose, una delle funzioni che non trovo in altri codici è la funzione "scelta()" che alla fine fornisce una sorta di scelta sulle invocazioni. L'idea non è male ma quel while non mi convinceva, ho provato il programma e mi va in loop, mi sapresti dire perché?

In genere poi quando si tratta di loop, è sempre meglio farlo al di fuori di una funzione per mantenere una gestione ottimale dello stack delle invocazione (per farla breve è anche lo stack che ti gestisce le ricorsioni).

Detto ciò, ho commentato il codice e modificato alcune cose, l'unica cosa che non ho debuggato è la funzione min. Ci sta un errore di inizializzazione e di gestione della condizione if dentro il ciclo for, sapresti dirmi cosa dover modificare? @Sax3r28

C:
#include <stdio.h>
#include <math.h>
// #include <malloc.h> ???
#include <stdlib.h>

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;
}


// KODE: restituisce sempre 0, ci sta un problema... vedi bene che non è difficile trovare dove sia ;)
float array_min_index(float arr_1[],int dim)
{
    float min=0; // KODE: attento qua

    for(int i=1;i<=dim;i++)
    {
        if(arr_1[i-1]<arr_1[i]) // KODE: attento qua
        {
            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; KODE: booleano ridondante, alla fine basta vedere quando menu = 0
    //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
            {
                printf("\nMedia: %lf\n", array_mean(arr_1,dim)); //Non stampava la media
                break;
            }
   
            case 5://MINIMO
            {
                printf("\nMin: %lf\n", array_min_index(arr_1,dim)); //Non stampava il minimo
                break;
            }
   
            default://INPUT NON VALIDO
            {
                // KODE: i due printf sotto sono ridondanti ora, quindi li ho eliminati
                //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)");
                printf("Input non valido");
                break;
            }
        }
    // }while(menu!=0 && close==false); KODE: va in loop, in genere quando si vuole effettuare una funzione
    // di switching i cicli sono nel body della funzione invocatrice (nel nostro caso il main)
}


int main()
{
    int dim=0, menu = 1;
    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)

    // KODE: Ho messo il ciclo all'interno del main piuttosto che in scelta
    {
        while(menu != 0){
        printf("\n1.arrayPrint\n2.arraySort\n3.writeOnFile\n4.arrayMean\n5.arrayMinIndex\n0.Close\n)"); // KODE: ti ho aggiunto un \n perchè odiavo il fatto che non andasse da capo
        printf("Digita la tua scelta:");
        scanf("%d",&menu);
        scelta(menu, arr_1, dim);
        // KODE: quando finisce l'operazione dentro la scelta effettuata ritorna qui, nel caso di 0 termina il ciclo
        }
    }

    // KODE: Grazie per aver liberato le risorse, la memoria ti ringrazia
    fclose(Wfile);

    free(arr_1);

    return 0;
}

Grazie @Kode . Quali punti potrebbero essere snelliti?

Per quanto dice invece @DispatchCode , in che modo potrei ottimizzare lo scope delle variabili?

@GabryBarbe i punti da snellire li ha detti DispatchCode nel commento di prima, ma conta che per me il codice va già bene cosi, era solo per puntualizzare e fare "l'avvocato del diavolo".
 
  • Love
Reactions: Not an engineer

Sax3r28

Utente Gold
8 Aprile 2016
589
293
218
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.
 

GabryBarbe

Utente Bronze
26 Dicembre 2020
59
26
31
Ultima modifica:
Puoi sia compattarlo che evitare di dare "scope" così ampi. Se tu dichiari la variabile nella parte di inizializzazione del for, quella variabile sarà locale al solo ciclo. Idem le variabili che usi solo nel corpo dei ciclo.

C:
void vet_sort(float vet[], size_t len){
    size_t i, x;
    for(i=0;i<len;i++){
        x=vet_min_index(&vet[i], len-i);
        vet_swap(vet,i,x+i);
    }
}

Quindi in questo caso questa funzione puoi modificarla così:
C:
void vet_sort(float vet[], size_t len){
    for(size_t i=0;i<len;i++){
        size_t x=vet_min_index(&vet[i], len-i);
        vet_swap(vet,i,x+i);
    }
}
Thanks! Quindi, in generale, sempre meglio inizializzare la variabile quando la si usa e non all'inizio?

@Kode certo ma per scrivere dei codici ben fatti anche queste cose sono importanti, dunque non farti scrupoli hahah
 
  • Mi piace
Reactions: Kode
Supporta Inforge con una donazione
Lv.105 - Middleschool - International SV