Domanda Trovare minimo elemento in un vettore di interi

Stefano011

Utente Bronze
10 Dicembre 2020
54
15
2
30
Ultima modifica da un moderatore:
Ciao,qualcuno mi potrebbe suggerire cosa non va?

C:
#include <stdio.h>
int minimo(int v[],int dim);
int main()
{
    int N;

    printf("Inserire lunghezza vettore: ");
    scanf("%d", &N);

    int vet[N];
    int i=0;

    for(;i<N;i++)
    {
        printf("Inserire %d° elemento del vettore: ",i+1);
        scanf("%d", &vet[i]);
    }
    printf("\n");
    printf("%d",minimo(vet,N));
    return 0;
}
int minimo(int v[],int dim)
{
    int n=0;
    int min=v[n];

    if(n==dim)
        return 0;
    else if(v[n+1]<min)
    {
        min=v[n+1];
    }

    else
        return min+=minimo(v,++n);
}

(devo trovare il minimo elemento in un vettore di interi),mi da errore "Segmantation fault core Dumped",e non so come risolvere.Ho già cercato l'errore online ma non capisco come risolvere ugualmente.Grazie in anticipo e scusate per il disturbo
 
Il problema immagino sia alla riga 29. Attento perche' con n scorri l'array (da 0 a dim-1) e dim indica la dimensione dell'array. Gia' questo ti dovrebbe far storcere il naso se dai un occhio al tuo programma.
Posso chiederti come mai questa soluzione per trovare il minimo? Eri obbligato o ti e' venuta in mente questa?
 
Il problema immagino sia alla riga 29. Attento perche' con n scorri l'array (da 0 a dim-1) e dim indica la dimensione dell'array. Gia' questo ti dovrebbe far storcere il naso se dai un occhio al tuo programma.
Posso chiederti come mai questa soluzione per trovare il minimo? Eri obbligato o ti e' venuta in mente questa?
Era un esercizio per imparare la ricorsuone
 
È molto sbagliato. Invece di cercare l'errore, ti consiglio di buttare via tutta la funzione minimo e riscriverla seguendo queste direttive:
  • se il vettore ha un solo elemento, il minimo è il primo ed unico elemento del vettore;
  • altrimenti, il minimo di un vettore con n elementi è il minimo tra l'ultimo elemento e (step ricorsivo) il minimo del vettore con n-1 elementi.
Il minimo tra due elementi è return a < b ? a : b; oppure if (a < b) { return a; } else { return b; }.

Si può fare con esattamente tre linee di codice, quindi non ti complicare la vita e cerca di seguire alla lettera la spiegazione che ti ho dato.
 
  • Mi piace
Reazioni: DispatchCode
È molto sbagliato. Invece di cercare l'errore, ti consiglio di buttare via tutta la funzione minimo e riscriverla seguendo queste direttive:
  • se il vettore ha un solo elemento, il minimo è il primo ed unico elemento del vettore;
  • altrimenti, il minimo di un vettore con n elementi è il minimo tra l'ultimo elemento e (step ricorsivo) il minimo del vettore con n-1 elementi.
Il minimo tra due elementi è return a < b ? a : b; oppure if (a < b) { return a; } else { return b; }.

Si può fare con esattamente tre linee di codice, quindi non ti complicare la vita e cerca di seguire alla lettera la spiegazione che ti ho dato.
Va bene, grazie mille
 
Va bene, grazie mille
Ti consiglio di usare l'allocazione dinamica della memoria qualora tu non conosca a prescindere la dimensione di un determinato array.
Hai usato una notazione non standard, non tutti i compilatori implementano la gestione della lunghezza di un vettore a run-time, il programma così diventa poco portabile, inoltre, il vettore da te dichiarato, rimane di fatto un vettore statico con il quale non è possibile apportare modifiche alla sua dimensione durante l'esecuzione del programma.
Le librerie standard C mettono a disposizione funzioni per la gestione della memoria dinamicamente, chiamata così in quanto si contrappone a quella statica, che ci permettono di allocare un determinato blocco di memoria di data dimensione sulla quale sarà possibile apportare modifiche a tempo di esecuzione.
Ecco un link per apprendere meglio l'argomento, alla fine non è niente di complesso, si tratta solamente di un insieme di funzioni preconfezionate, non ti devi preoccupare di come ciò avvenga, l'implementazione di tale tecnica varia da sistema a sistema:
https://it.wikipedia.org/wiki/Allocazione_dinamica_della_memoria
 
messaggio ancora non chiuso, lo gioco un po' :)

considerando che si tratta di numeri immessi da un utente,
puoi sempre allocare un array statico e bloccare l'input con
un MAX_SIZE e un messaggio.


int vet[N];

non si fa per vati motivi
- standard C90 non consente di allocare variabili
dove vuoi nello scope, come fai in main(), c++ o c99 si.
- in qualsiasi caso di errore di N va tutto facilmente in crash,
quindi come minimo dovresti fare un check su N, lo stack dove
allochi l0array non e' infinito.

Se no appunto come dice mattstack allocazione dinamica, e via.
 
  • Mi piace
Reazioni: mattstack
non si fa per vati motivi
- standard C90 non consente di allocare variabili dove vuoi nello scope, come fai in main(), c++ o c99 si.
Su questo non sono particolarmente d'accordo. È vero che per scrivere codice C89 compliant le variabili vanno dichiarate all'inizio del loro scope, ma è anche vero che quella regola era dettata principalmente dalle limitazioni dei primi compilatori ed è ormai in disuso. È talmente buona pratica definire le variabili il più vicino possibile al loro uso e alla loro inizializzazione che mi pare di ricordare che in alcuni linguaggi moderni sia addirittura vietato fare il contrario. Io la considero una di quelle cose che va fatta anche se vuoi scrivere in C89, tanto GCC e molti altri compilatori ti permettono di rompere questa regola in ogni caso. Probabilmente tu sei più old scool a questo riguardo.

D'accordissimo sul discorso dei VLA: erano parte dello standard (in C11 sono un'estensione opzionale) ma non sarebbero dovuto esserlo e vengono spesso abusati.
 
Intendo dire che e' bene sapere che allocare variabili ovunque nello scope e' una feature aggiunta in c99, e c++.
Chi programma in C puo lavorare anche su un microcontrollore 8 bit con pochissima memoria, e compilatori
che magari non supportano c99, o che se non abiliti c99 danno errore. E' solo "per conoscenza".

È vero che per scrivere codice C89 compliant le variabili vanno dichiarate all'inizio del loro scope, ma è anche vero che quella regola era dettata principalmente dalle limitazioni dei primi compilatori ed è ormai in disuso.

Beh, il concetto non e' propriamente in disuso, prendi il kernel linux, cioe' il progetto C piu popolare e grande al mondo, e trovi le variavbili solo all'inizio di ogni scope, come regola ferrea.
Cosi fanno diversi altri progetti opensource C tipo bootloaders etc.

In questo caso non per portabilita'. Infatti il kernel compila per molteplici archietture, ma usando sempre gcc, c99 e' ben supportato.
E' perche molti progetti stabiliscono come buona regola il non allocare troppe variabili (max da 5 a 10) per funzione sullo stack, perche
si assume che se ne allochi troppe, stai creando una funzione troppo complessa che dovrebbe essere divisa in altre piu semplici.

Io lo trovo anche piu comodo/ordinato, sai che le hai tutte li, ma questo e' solo un mio gusto.
 
  • Mi piace
Reazioni: St3ve
Beh, il concetto non e' propriamente in disuso, prendi il kernel linux, cioe' il progetto C piu popolare e grande al mondo, e trovi le variavbili solo all'inizio di ogni scope, come regola ferrea.
Provando a greppare c'è qualcuno che la viola si trova, ma effettivamente la applicano abbastanza spesso. Sarei curioso di sapere per quale motivo la applicano. Mi pare che il kernel linux si riesca a compilare giusto con GCC (e forse, a malapena, Clang) quindi escluderei sia per questioni di portabilità, ma nelle coding style non ho trovato niente a rigaurdo... in compenso ho notato che anche loro hanno iniziato a censurare master/slave e blacklist/whitelist :oddio:

E' perche molti progetti stabiliscono come buona regola il non allocare troppe variabili (max da 5 a 10) per funzione sullo stack, perche si assume che se ne allochi troppe, stai creando una funzione troppo complessa che dovrebbe essere divisa in altre piu semplici.
In compenso ricordo che nel source di GCC (quindi okay, non proprio roba che vedi tutti i giorni) si trovano cose come if in cui solo il blocco condizionale (per capirci, quello all'interno delle tonde) occupa 30-40 linee di codice :asd:

Che scrivere funzioni piccole sia una buona convenzione non lo metto in dubbio, ma non penso che sia per questa ragione che nel kernel linux ti incoraggiano a definire le variabili a inizio scope.
 
Provando a greppare c'è qualcuno che la viola si trova, ma effettivamente la applicano abbastanza spesso. Sarei curioso di sapere per quale motivo la applicano. Mi pare che il kernel linux si riesca a compilare giusto con GCC (e forse, a malapena, Clang) quindi escluderei sia per questioni di portabilità, ma nelle coding style non ho trovato niente a rigaurdo... in compenso ho notato che anche loro hanno iniziato a censurare master/slave e blacklist/whitelist :oddio:
Si come dicevo sopra, motivo non e' per portabilita' ma per evitare funzioni troppo grosse.


in effetti scripts/checkpatch.pl non segnala il problema ma ti becchi immediatamente un

warning: ISO C90 forbids mixed declarations and code
Se non le ferma il maintainer, in genere questi warning sono segnalati come problema dal build robot.

Se hai trovato qualche caso, hai un buon motivo per inviare qualche patch nel caso :)