View Full Version : [C] Esercizio Vettore -principiante
amicoalbi
13-01-2014, 21:53
Salve ragazzi ho bisogno di una mano con un programmino. Vi riporto la traccia:
Acquisire da tastiera elementi non nulli che compongono il vettore V (il valore nullo blocca l'acquisizione e non il programma e non appartiene al vettore acquisito). Ricercare, in un unico ciclo, la media dei soli valori pari (non di posto pari) presenti nel vettore.
#include "stdio.h"
void input_vett (int x,int V[])
{
int i;
do
{
printf("inserire dimensione del vettore V\nDimensione Vettore =");
scanf("%d",&x);
}
while (x<2);
for (i=0;i<x;i++)
{
printf("V[%d]=",i);
scanf("%d",&V[i]);
}
}
void media_numeri_pari (int x, int V[])
{
int i,n=0,c=0;
for(i=0;i<x-1;i++)
if (V[i]%2==0);
{
n=V[i]+n;
c++;
}
//media aritmetica//
float m; m=(n/c);
printf("La media dei numeri pari inseriti è %f",m);
}
void main()
{
int x,V;float m;
void input_vett(int x, int V[]);
void media_numeri_pari(int x, int V[]);
}
Il programma non funge e credo che i problemi siano nel passaggio delle variabili alle procedure del main ma purtroppo non ne sono venuto a capo.
PS idee su come bloccare l'acquisizione dei valori all'immissione di un valore nullo?
Vi ringrazio in anticipo :D
amicoalbi
14-01-2014, 05:51
aprire un libro di C e studiare il concetto di funzione, cosa sono i parametri attuali e i parametri formali, e come avviene il passaggio dei parametri.
Ahia è davvero così grave?
Ho cercato di scrivere qualcosa basandomi sugli appunti presi in aula.
sottovento
14-01-2014, 07:31
Ahia è davvero così grave?
Ho cercato di scrivere qualcosa basandomi sugli appunti presi in aula.
No, non credo che sia cosi' grave, anzi mi sembra che abbia lavorato bene. Sei sulla buona strada.
Alcuni dettagli:
void input_vett (int x,int V[])
In questo modo, il valore di x puo' essere solo letto da input_vett(): le modifiche che fai al suo interno, verranno perse in uscita da questa funzione.
Dovrai quindi cambiare questo "prototipo" di funzione e specificare che il valore x sara' modificato dalla funzione. Non so se hai bisogno che te lo scriva o se vuoi far da solo (per ora non lo scrivo, fammi sapere se hai bisogno che invece lo faccia)
for (i=0;i<x;i++)
{
printf("V[%d]=",i);
scanf("%d",&V[i]);
}
E' corretto e funziona, ma ci sono due problemi:
1 - l'utente potrebbe continuare ad inserire fino a superare la dimensione del vettore;
2 - la traccia, se ho capito bene, diceva che l'acquisizione termina quando viene inserito uno zero (il quale non deve far parte della sequenza) e non c'e' traccia di questa cosa.
Il mio suggerimento e' quello di modificare questo ciclo, magari utilizzando un ciclo while, in modo da rispettare la condizione di uscita all'introduzione di uno zero ed in modo che non sia possibile inserire elementi una volta che il vettore e' riempito correttamente;
void media_numeri_pari (int x, int V[])
{
int i,n=0,c=0;
for(i=0;i<x-1;i++)
if (V[i]%2==0);
{
n=V[i]+n;
c++;
}
//media aritmetica//
float m; m=(n/c);
printf("La media dei numeri pari inseriti è %f",m);
}
Va benissimo, a parte quell' i < x-1: non ti piace l'ultimo elemento inserito? ;)
(devi arrivare fino a x, cioe' i < x)
void main()
{
int x,V;float m;
void input_vett(int x, int V[]);
void media_numeri_pari(int x, int V[]);
}
Non si compila, vero?
Hai dichiarato V come un intero, non come un vettore di interi. Lo sai come si fa?
Una volta sistemate le dichiarazioni, devi sistemare le chiamate alle funzioni che hai definito. Ti ricordi come si chiamano? La chiamata di una funzione e' stata disegnata in modo che risulti "naturale", come se fosse un qualsiasi altro comando del linguaggio, quindi non hai bisogno di passare il tipo delle variabili e specificare il tipo del valore di ritorno (i.e. void).
Spero di esserti stato utile
bancodeipugni
14-01-2014, 14:12
poi l'esame lo passi quest'altr'anno :O
cmq la dichiarazione di dimensioni va fatta sulla main: le funzioni per un programmino cosi' puoi anche evitarle visto che le metti in fila una dopo l'altra
per dimensionare l'array ci vorrebbe la malloc() con parametro gli inserimenti moltiplicati per sizeof
tuttavia se già troppo avanti puoi limitarti per adesso a fare un array di massima a 1000 elementi
amicoalbi
14-01-2014, 15:08
Prima di tutto grazie a tutti.
Mi metto a lavoro manuale alla mano. Posterò i risultati più tardi :D
amicoalbi
16-01-2014, 15:36
Mi sono dedicato allo studio in questo tempo.
Non mi è però ben chiaro come passare per indirizzo la variabile m. In questo caso rimane nel blocco dopo l'if e non ritorna niente nel main?
Questo codice viene compilato ma l'eseguibile si blocca appena dopo l'inserimento del primo elemento del vettore.
PS sono "obbligato" ad usare le funzioni nonostante il programma sia oggettivamente semplice perché nell'esame il prof vuole vedere i passaggi, le chiamate ecc...
Grazie a chi risponderà :D
#include "stdio.h"
#define MAX 100
void input_vett (int V[])
{
int i;
for (i=0;i<MAX;i++)
do
{
printf("Inserire elementi vettore\nV[%d]=",i);
scanf("%d",&V[i]);
}
while (V[i]!=0);
}
float media_numeri_pari (int V[])
{
int i,n=0,c=0;float m;
for(i=0;i<MAX;i++)
if (V[i]%2==0);
{
n+=V[i];
c++;
m=(n/c);
}
return m;
}
main ()
{
int V[MAX]; float p;
input_vett(V[MAX]);
p=media_numeri_pari(V[MAX]);
printf("La media dei numeri pari è %f,p");
}
bancodeipugni
16-01-2014, 17:44
si ma V nella main è sciolto... non è assegnato a niente
invece di void input_vett fai int* input_vett()
e ritorna il puntatore al vettore interi
quindi nella main fai V=input_vett(V);
amicoalbi
16-01-2014, 18:10
si ma V nella main è sciolto... non è assegnato a niente
invece di void input_vett fai int* input_vett()
e ritorna il puntatore al vettore interi
quindi nella main fai V=input_vett(V);
#include "stdio.h"
#define MAX 100
int* input_vett (int V[])
{
int i;
for (i=0;i<MAX;i++)
do
{
printf("Inserire elementi vettore\nV[%d]=",i);
scanf("%d",&V[i]);
}
while (V[i]!=0);
return &V;
}
float media_numeri_pari (int V[])
{
int i,n=0,c=0;float m;
for(i=0;i<MAX;i++)
if (V[i]%2==0);
{
n+=V[i];
c++;
m=(n/c);
}
return m;
}
main ()
{
int V[MAX]; float p;
V=*input_vett(V);
p=media_numeri_pari(V);
printf("La media dei numeri pari è %f",p);
}
Così? Sbaglio sicuro perché non compila.
Definendo int* input_vett (int V[]) sto dicendo che input_vett è puntatore al vettore di interi. Devo fare ritornare l'indirizzo del primo elemento del vettore? Come?
alla riga V=*input_vett(V); ho un bel error: incompatible types when assigning to type 'int[100]' from type 'int'|
Scusate l'incompetenza :help:
amicoalbi
16-01-2014, 18:32
media_numeri_pari() ha bisogno di ricevere in ingresso un puntatore al primo elemento dell'array, mentre tu gli passi l'elemento numero 100 dell'array stesso e lo stesso vale per input_vett()
cosa vuol dire non e' assegnato a niente? nel main definisce un vettore allocato nello stack MAX int che chiama V e lo vuole passare alla funzione per farlo riempire..
In effetti l'idea è proprio questa, far riempire il vettore. Non ho capito però come definire un puntatore al primo elemento dell'array. Qualcosa del tipo int *V[0]? Mi pare troppo brutto :eek:
amicoalbi
16-01-2014, 18:37
puoi usare benissimo il programma originale passando semplicemente V invece che V[MAX]
In effetti adesso non crasha al primo elemento :D
Però non blocca l'acquisizione degli elementi quando inserisco zero. Come mai?
vendettaaaaa
16-01-2014, 18:44
#include "stdio.h"
#define MAX 100
int* input_vett (int V[])
{
int i;
for (i=0;i<MAX;i++)
do
{
printf("Inserire elementi vettore\nV[%d]=",i);
scanf("%d",&V[i]);
}
while (V[i]!=0);
return &V;
}
float media_numeri_pari (int V[])
{
int i,n=0,c=0;float m;
for(i=0;i<MAX;i++)
if (V[i]%2==0);
{
n+=V[i];
c++;
m=(n/c);
}
return m;
}
main ()
{
int V[MAX]; float p;
V=*input_vett(V);
p=media_numeri_pari(V);
printf("La media dei numeri pari è %f",p);
}
Così? Sbaglio sicuro perché non compila.
Definendo int* input_vett (int V[]) sto dicendo che input_vett è puntatore al vettore di interi. Devo fare ritornare l'indirizzo del primo elemento del vettore? Come?
alla riga V=*input_vett(V); ho un bel error: incompatible types when assigning to type 'int[100]' from type 'int'|
Scusate l'incompetenza :help:
Errore madornale: input_vett non è un puntatore ad un vettore di interi, è una funzione che restituisce un puntatore ad interi e prende in argomento un vettore di interi.
Errore davvero grave questo, devi distinguere funzioni da variabili...
amicoalbi
16-01-2014, 18:55
Errore madornale: input_vett non è un puntatore ad un vettore di interi, è una funzione che restituisce un puntatore ad interi e prende in argomento un vettore di interi.
Errore davvero grave questo, devi distinguere funzioni da variabili...
Me lo segno. Stavo cercando di interpretare quanto suggeritomi da un altro utente :)
ti conviene stampare di volta in volta il carattere che hai effettivamente salvato dopo ogni acquisizione dentro V[i], la newline che aggiungi quando premi invio ma non leggi esplicitamente puo' creare problemi.
per definire un puntatore basta semplicemente una cosa di questo tipo:
int * pInt = &V[0];
Allora sì, se stampo i valori effettivamente li prende.
Ho capito anche qual è la logica: acquisisce sempre il valore dell'elemento i-esimo sostituendolo col precedente e termina l'acquisizione dei dati da tastiera per l'elemento i-esimo soltanto se inserisco 0 fino a riempire tutto il vettore.
Cioè all'avvio se continuo a scrivere valori questi diventano ogni volta il valore di V[0] a meno che non inserisca 0. Così passa a V[1] fino a V[MAX].
La traccia richiede invece che l'acquisizione si fermi proprio al primo valore nullo inserito. Ma in quel caso varierebbe anche la dimensione del vettore in base al numero di valori inseriti fino a quel momento. Consigli su come risolvere questo problema? Cerco di farlo da solo :)
bancodeipugni
16-01-2014, 19:31
[CODE]
alla riga V=*input_vett(V); ho un bel error: incompatible types when assigning to type 'int[100]' from type 'int'|
Scusate l'incompetenza :help:
V = input....
per dirla in parole poverem assegnando l'asterisco, assegni a un vettore un solo valore
invece devi assegnare a vettore un vettore cioè puntatore a puntatore
vendettaaaaa
16-01-2014, 19:31
Me lo segno. Stavo cercando di interpretare quanto suggeritomi da un altro utente :)
Scrivere poi
V = *input_vett(V);
significa:
1) Chiamo la funzione input_vett passandogli V come argomento
2) Prendo il suo valore di ritorno (un int*) e lo dereferenzio usando *
3) Assegno l'int (quando dereferenzi un puntatore, ottieni il valore puntato) a V. E qua c'è l'errore: V è di tipo int[] (cioè int*, ma per ora non chiedere perchè), quindi non puoi assegnargli un int.
Ricapitolando, il tuo codice equivale a:
int* valoreDiRitorno = input_vett(V);
int valorePuntatoDalValoreDiRitorno = *valoreDiRitorno; // Passo da int* a int usando *
// Notare che questo equivale a:
int valorePuntatoDalValoreDiRitorno = operator*(valoreDiRitorno);
// Poichè gli operatori sono alla fin fine delle funzioni (unarie, come in questo caso, o binarie, come il +)
V = valorePuntatoDalValoreDiRitorno; // Errore: assegno un int ad un int[]
Ti consiglio di usare, almeno all'inizio quando devi ancora capire come funziona tutto, di scrivere i passaggi uno ad uno, di modo che capisci bene cosa succede e non fai due operazioni nella stessa riga.
amicoalbi
18-01-2014, 00:26
Grazie vendettaaaaa e bancodeipugni per il vostro intervento: è davvero più chiaro adesso. :cool:
Chiaro tanto che mi sono ingegnato per cercare di soddisfare la richiesta in maniera più precisa (acquisizione si ferma al primo 0 e questo 0 non fa parte del vettore) e ci sono riuscito... purtroppo solo in parte.
Mi spiego
#include "stdio.h"
#define MAX 10
void input_vett (int V[])
{int i,t;
for(i=0;i<MAX;i++)
{
printf("Inserire elementi del vettore V\n V[%d]=",i);
scanf("%d",&t);
if(t!=0) V[i]=t; else break;
}
}
main()
{ int V[MAX],i;
input_vett(V);
for(i=0;i<MAX;i++) printf("V[%d]=%d\n",i,V[i]);
}
Inserendo anche la funzione media mi vengono fuori valori strani così ho verificato con delle stampe (PS sono già soddisfatto perché ciò che scrivo venga compilato quasi al primo colpo :yeah: ).
Ciò che voglio è che il vettore abbia dimensione pari al valore della i dell'ultimo elemento inserito. Il codice che ho scritto non risponde evidentemente alla mia volontà perché il programma riempie il vettore fino a i=MAX con dei valori random (?) o mi mostra gli indirizzi di ogni elemento (?). D'altro canto non specificare la dimensione dell'array vettore nel main vuol dire veder comparire un bel errore...
Qualche dritta anche su questo punto?
PS sto imparando più grazie a voi che alle lezioni in aula praticamente :D
Birra pagata se passate dalle mie parti ;)
Oceans11
18-01-2014, 09:20
Ciò che voglio è che il vettore abbia dimensione pari al valore della i dell'ultimo elemento inserito. Il codice che ho scritto non risponde evidentemente alla mia volontà perché il programma riempie il vettore fino a i=MAX con dei valori random (?) o mi mostra gli indirizzi di ogni elemento (?). D'altro canto non specificare la dimensione dell'array vettore nel main vuol dire veder comparire un bel errore...
qui o usi l'allocazione dinamica della memoria (vedi malloc e affini), oppure dopo aver riempito il primo vettore (grande a sufficienza ma più del necessario) ne copi il contenuto in uno grande il giusto e butti il primo.
bancodeipugni
18-01-2014, 10:05
questo perché non sono probabilmente settati a 0
o usi calloc() o memset() e poi interrompi la stampa al primo NULL che incontra
vendettaaaaa
18-01-2014, 11:21
Grazie vendettaaaaa e bancodeipugni per il vostro intervento: è davvero più chiaro adesso. :cool:
Chiaro tanto che mi sono ingegnato per cercare di soddisfare la richiesta in maniera più precisa (acquisizione si ferma al primo 0 e questo 0 non fa parte del vettore) e ci sono riuscito... purtroppo solo in parte.
Mi spiego
#include "stdio.h"
#define MAX 10
void input_vett (int V[])
{int i,t;
for(i=0;i<MAX;i++)
{
printf("Inserire elementi del vettore V\n V[%d]=",i);
scanf("%d",&t);
if(t!=0) V[i]=t; else break;
}
}
main()
{ int V[MAX],i;
input_vett(V);
for(i=0;i<MAX;i++) printf("V[%d]=%d\n",i,V[i]);
}
Inserendo anche la funzione media mi vengono fuori valori strani così ho verificato con delle stampe (PS sono già soddisfatto perché ciò che scrivo venga compilato quasi al primo colpo :yeah: ).
Ciò che voglio è che il vettore abbia dimensione pari al valore della i dell'ultimo elemento inserito. Il codice che ho scritto non risponde evidentemente alla mia volontà perché il programma riempie il vettore fino a i=MAX con dei valori random (?) o mi mostra gli indirizzi di ogni elemento (?). D'altro canto non specificare la dimensione dell'array vettore nel main vuol dire veder comparire un bel errore...
Qualche dritta anche su questo punto?
PS sto imparando più grazie a voi che alle lezioni in aula praticamente :D
Birra pagata se passate dalle mie parti ;)
#include "stdio.h"
#define MAX 10
void input_vett(int V[])
{
int i, t;
for (i = 0; i < MAX; ++i)
{
printf("Inserire elementi del vettore V\n V[%d] = ", i);
scanf("%d", &t);
if (t != 0)
V[i] = t;
else
break;
}
}
void main()
{
int V[MAX] = { 0 };
int i;
input_vett(V);
for (i = 0; i < MAX; ++i)
printf("V[%d] = %d\n", i, V[i]);
}
Come dice bancodeipugni, il valore dei MAX elementi del vettore è casuale e non settato ad uno specifico valore iniziale.
Questo perchè ogni volta che in C e C++ si alloca spazio in memoria per una variabile di tipo built-in, tale variabile viene inizializzata con un valore casuale (o quasi casuale), ma non a 0 come ci si potrebbe aspettare.
Che la variabile sia una o più (un array) il risultato non cambia, quindi se aggiungi la parte che ti ho messo in rosso tutti i MAX valori saranno inizializzati a 0.
Questo però non risponde alla tua domanda: tu vuoi che nella stampa dopo la chiamata ad input_vett vengano visualizzati solo 6 numeri se ne hai inseriti 6.
Di certo la tua frase "voglio che il vettore abbia dimensione pari all'ultimo numero inserito" contrasta col codice scritto finora: tu dimensioni l'array in modo statico (avrà sempre dimensione MAX: gli array built-in hanno dimensione decisa a compile-time, non puoi cambiarla a runtime; cioè fare
int main()
{
int n;
// Leggi n da console
int V[n] = { 0 };
}
non compila: n dev'essere conosciuto in fase di compilazione). Hai allora due opzioni:
- Fai come ti dice Oceans11, e devi cmq usare malloc per allocare a runtime un vettore del giusto numero di elementi
- Il vettore rimane di dimensione MAX ma lo inizializzi (parte in rosso) con un valore "improbabile", tipo -987654321, e in fase di stampa, dopo input_vett, se V[i] == -987654321 (perchè, in lettura, l'utente aveva inserito uno 0 all'iterazione i-esima) interrompi.
amicoalbi
18-01-2014, 11:32
Sì infatti mi sono tirato fuori dall'inghippo in una maniera simile.
#include "stdio.h"
#define MAX 10
main()
{int i,n,t,V[MAX],N=0; float media=0.; //N è contatore//
for(i=0;i<MAX;i++)
{
printf("Inserire elementi del vettore V\n V[%d]=",i);
scanf("%d",&t);
if(t!=0) V[i]=t; else break;
}
for(n=0;n<i;n++)
{
if((V[n]%2==0) && (V[n]!=0))
{
media+=V[n];
N ++;
}
}
printf("La media dei numeri pari inseriti = %f",media/N);
}
Semplicemente faccio in questo modo che credo sia l'unico alla mia portata.
Grazie a tutti :D
vendettaaaaa
18-01-2014, 11:37
Indentazione orribile cmq :D
Ma ne cambierai un po' prima di arrivare a quella che più ti aggrada...
bancodeipugni
18-01-2014, 13:30
cmq manca un controllo senza il quale potrebbe andarti in crash tutto
la divisione per zero della media :D :sofico:
sono quelle cazzate che come tali il professore ti puo' cavare voti interi, come la mancanza degli #include :fagiano:
amicoalbi
18-01-2014, 16:03
Ahahah banco :D ho fatto provare il programma a mia sorella e casualmente non ha inserito nessun valore pari -> crash! Ho sistemato :)
Parlando con altri ragazzi si è capito che per lui interrompere l'immissione vuol dire considerare di un vettore sono gli elementi inseriti da tastiera nonostante siano allocati elementi fino a riempirlo di valori random (come pensavo :D ).
Sto portando l'ultima sequenza ad una struttura modulare. La posto più tardi e sparisco giuro :P
amicoalbi
18-01-2014, 17:34
Facciamo le cose in grande :sofico:
#include "stdio.h"
#define MAX 100
void input_vett(int V[], int i)
{
int t;
for(i=0;i<MAX;i++)
{
printf("Inserire elementi del vettore\n V[%d]=",i);
scanf("%d",&t);
if(t!=0) V[i]=t; else break;
}
}
float media (int V[], int i)
{
int x,somma=0,N=0;float m=0;
for(x=0;x<i;x++)
if(V[x]%2==0 && V[x]!=0)
{somma+=V[x];
N++;
}
if(N!=0) m=(somma/N);
else m==-1.0;
return m;
}
main()
{int Vett[MAX],i=0; float m;
input_vett(Vett,&i);
m=media(Vett,&i);
{
if (m>=0)
{ printf("Media dei numeri pari=%f\n",m);
system("PAUSE");
}
else
{ printf("Non è stato inserito alcun numero pari");
system("PAUSE");
}
}
}
Che ha che con va?? :doh: ho passato la i per indirizzo in entrambi i casi in modo tale che, lavorando sulla stessa locazione di memoria, la i dell'input_vett avesse lo stesso valore della i in media... Tra l'altro sono convinto che nella media basta passarla per valore tanto non viene modificata e non mi serve che ritorna nella main.
Compilazione a buon fine ma non funge! :muro: :muro: Quando pensi di aver capito come funzionano le cose...
Aggiungo che se passo la i per valore nella media il programma eseguito mi restituisce media pari a 0 sempre :(
EDIT:
Indentazione orribile cmq :D
Ma ne cambierai un po' prima di arrivare a quella che più ti aggrada...
Effettivamente è un po' brutta :P migliorerà migliorerà
vendettaaaaa
18-01-2014, 17:57
Non decidi tu se una funzione deve accettare una variabile per indirizzo o per valore, non ci sarebbe una certezza sull'interfaccia. Lo decide la funzione. Quindi tu gli passi l'indirizzo di i ma la funzione prende quell'indirizzo e lo copia dentro di sè, pensando sia un intero.
Compila lo stesso perchè l'indirizzo di memoria alla fine è un numero intero e in questo viene convertito silenziosamente. Per fare come dici tu, le due funzioni devono prendere come secondo argomento int* i, e poi nel corpo delle funzioni dovrai scrivere *i anzichè i.
In realtà basta che lo fai per input_vett, visto che quella funzione modifica i; media invece legge quel valore senza modificarlo, quindi lasciala com'è.
amicoalbi
18-01-2014, 18:11
Non decidi tu se una funzione deve accettare una variabile per indirizzo o per valore, non ci sarebbe una certezza sull'interfaccia. Lo decide la funzione. Quindi tu gli passi l'indirizzo di i ma la funzione prende quell'indirizzo e lo copia dentro di sè, pensando sia un intero.
Compila lo stesso perchè l'indirizzo di memoria alla fine è un numero intero e in questo viene convertito silenziosamente. Per fare come dici tu, le due funzioni devono prendere come secondo argomento int* i, e poi nel corpo delle funzioni dovrai scrivere *i anzichè i.
In realtà basta che lo fai per input_vett, visto che quella funzione modifica i; media invece legge quel valore senza modificarlo, quindi lasciala com'è.
#include "stdio.h"
#define MAX 100
void input_vett(int V[], int* i)
{
int t,m;
for(m=0;m<MAX;m++)
{
printf("Inserire elementi del vettore\n V[%d]=\n",m);
scanf("%d",&t);
if(t!=0)
{ V[m]=t;
*i=m;
}
else break;
}
}
float media (int V[], int *i)
{
int x,somma=0,N=0;float media=0;
for(x=0;x<*i;x++)
if(V[x]%2==0 && V[x]!=0)
{somma+=V[x];
N++;
}
if(N!=0) media=(somma/N);
else media==-1;
return media;
}
main()
{int V[MAX],i=0; float m;
input_vett(V,&i);
m=media(V,&i);
{
if (m>=0)
{ printf("Media dei numeri pari=%f\n",m);
system("PAUSE");
}
else
{ printf("Non è stato inserito alcun numero pari");
system("PAUSE");
}
}
}
Sento che manca poco.
Mi vedo strano *i=m... Perché così nel puntatore ad i va m. Allora ho pensato di fare i=m ma ugualmente niente
EDIT ops mi sono perso l'ultima riga.
EDIT2: ugualmente non va. Sbaglio qualcosa prima
EDIT3: OK ho letto che invece è giusto proprio *i=m. In questo caso m va nella variabile puntata da i
vendettaaaaa
18-01-2014, 18:27
Primo suggerimento: divisione tra interi;
Secondo suggerimento: errore logico in input_vett.
Sistema seguendo i suggerimenti in ordine e arriverai alla soluzione :D
E usa il debugger! Così puoi controllare il valore delle variabili in ogni momento :)
amicoalbi
18-01-2014, 18:37
Primo suggerimento: divisione tra interi;
Secondo suggerimento: errore logico in input_vett.
Sistema seguendo i suggerimenti in ordine e arriverai alla soluzione :D
E usa il debugger! Così puoi controllare il valore delle variabili in ogni momento :)
Ho capito il secondo immagino: tirato fuori *i=m dal loop.
Per il primo... divisione tra interi... mmm cast?
Ho direttamente dichiarato float somma ma non va...
EDIT: solo con questa modifica funziona in tutti i casi tranne che quando inserisco soli valori dispari (mi restituisce media uguale a 0)
amicoalbi
18-01-2014, 19:15
OK gente ahahah
Definitivo e funzionante!!!
#include "stdio.h"
#define MAX 100
void input_vett(int V[], int* i)
{
int t,m;
for(m=0;m<MAX;m++)
{
printf("Inserire elementi del vettore\n V[%d]=",m);
scanf("%d",&t);
if(t!=0) V[m]=t;
else break;
}
*i=m;
}
float media (int V[], int i)
{
int x,N=0,somma=1; float media=0;
for(x=0;x<i;x++)
if(V[x]%2==0 && V[x]!=0)
{somma+=V[x];
N++;
}
if(N!=0) media=((somma-1)/N);
else media=-1;
return media;
}
main()
{int V[MAX],i=0; float m;
input_vett(V,&i);
m=media(V,i);
{
if (m!=-1)
{ printf("Media dei numeri pari=%f\n",m);
system("PAUSE");
}
else
{ printf("Non è stato inserito alcun numero pari\n");
system("PAUSE");
}
}
}
L'errore era in media==-1. E' corretto invece media=-1.
Che parto ragazzi :D
vendettaaaaa
18-01-2014, 19:18
Ho capito il secondo immagino: tirato fuori *i=m dal loop.
Per il primo... divisione tra interi... mmm cast?
Ho direttamente dichiarato float somma ma non va...
EDIT: solo con questa modifica funziona in tutti i casi tranne che quando inserisco soli valori dispari (mi restituisce media uguale a 0)
Giusto il secondo: io ho scritto
*i = m + 1;
ma aver tirato *i = m fuori dal loop è equivalente. Il mio metodo però è molto più esplicito, perchè nel tuo caso devi ricordarti che sei uscito dal loop perchè l'utente ha inserito uno 0 e m è stato incrementato di uno (oppure perchè hai letto 10 numeri, quindi m = 10 e m < MAX fallisce, uscendo dal loop). Il codice con side effect impliciti è sempre da evitare.
Se nel main scrivi if (m >= 0) per forza non vedrai mai il messaggio giusto...
Già che ci siamo, nella funzione media scriverei
if (N != 0)
return somma / N;
else
return -1;
così ti risparmi una dichiarazione di variabile inutile.
Ma cosa usi come IDE/compilatore?
vendettaaaaa
18-01-2014, 19:22
OK gente ahahah
Definitivo e funzionante!!!
#include "stdio.h"
#define MAX 100
void input_vett(int V[], int* i)
{
int t,m;
for(m=0;m<MAX;m++)
{
printf("Inserire elementi del vettore\n V[%d]=",m);
scanf("%d",&t);
if(t!=0) V[m]=t;
else break;
}
*i=m;
}
float media (int V[], int i)
{
int x,N=0,somma=1; float media=0;
for(x=0;x<i;x++)
if(V[x]%2==0 && V[x]!=0)
{somma+=V[x];
N++;
}
if(N!=0) media=((somma-1)/N);
else media=-1;
return media;
}
main()
{int V[MAX],i=0; float m;
input_vett(V,&i);
m=media(V,i);
{
if (m!=-1)
{ printf("Media dei numeri pari=%f\n",m);
system("PAUSE");
}
else
{ printf("Non è stato inserito alcun numero pari\n");
system("PAUSE");
}
}
}
L'errore era in media==-1. E' corretto invece media=-1.
Che parto ragazzi :D
Sbagliato: divisione tra interi!!
amicoalbi
18-01-2014, 19:26
Sbagliato: divisione tra interi!!
Così è sbagliato?? O.O
EDIT mi sono informato. Devo evitare un overflow dichiarando float numeratore e denominatore?
amicoalbi
18-01-2014, 19:48
Già che ci siamo, nella funzione media scriverei
if (N != 0)
return somma / N;
else
return -1;
così ti risparmi una dichiarazione di variabile inutile.
Ma cosa usi come IDE/compilatore?
Mi piace questa soluzione :D (mi perdo ciò che scrivi a volte :mbe: )
Uso code::blocks
vendettaaaaa
18-01-2014, 19:49
Così è sbagliato?? O.O
EDIT mi sono informato. Devo evitare un overflow dichiarando float numeratore e denominatore?
Non c'entra l'overflow. Una divisione tra interi restituisce la parte intera del risultato che ti aspetti, troncandolo.
float a = 9 / 5; // a vale 1
float b = (float)9 / 5; // b vale 1.8
float c = 9 / (float)5; // c vale 1.8
float d = 9. / 5 // d vale 1.8, perchè 9. (abbreviazione di 9.0) è un float (in realtà un double, ma vabbè)
float e = 9 / 5. // indovina quanto vale e...
Più in generale, se applichi un operatore binario a due operandi di tipo diverso, ma convertibile (int a float, o float a double), uno dei tipi viene convertito all'altro secondo una certa precedenza (praticamente il tipo con meno precisione viene promosso a tipo più preciso). Per questo castare 9 a float causa che anche 5 sia castato a float e b (e tutti quelli dopo) sia il risultato di una divisione tra numeri con la virgola.
amicoalbi
18-01-2014, 19:53
{
int x,somma=0,N=0; float media=0;
for(x=0;x<i;x++)
if(V[x]%2==0 && V[x]!=0)
{somma+=V[x];
N++;
}
if(N!=0) media=(float)somma/N);
else media=-1;
return media;
}
Quindi così :)
vendettaaaaa
18-01-2014, 19:56
{
int x,somma=0,N=0; float media=0;
for(x=0;x<i;x++)
if(V[x]%2==0 && V[x]!=0)
{somma+=V[x];
N++;
}
if(N!=0) media=(float)somma/N);
else media=-1;
return media;
}
Quindi così :)
O così:
{
int x,N=0; float media=0, somma=0;
for(x=0;x<i;x++)
if(V[x]%2==0 && V[x]!=0)
{somma+=V[x];
N++;
}
if(N!=0) media=somma/N);
else media=-1;
return media;
}
Non cambia niente :)
amicoalbi
18-01-2014, 19:58
Posso dire che è finito allora :D
Grazie mille per l'aiuto. Fondamentale :D
Al prossimo esercizio :bsod:
vendettaaaaa
18-01-2014, 20:22
Ciao, scrivi tanto codice, mi raccomando :D
amicoalbi
29-01-2014, 20:11
Ciao, scrivi tanto codice, mi raccomando :D
Il vostro alunno si è beccato un 30 all'esame di fondamenti di informatica :sofico:
vendettaaaaa
29-01-2014, 23:14
Bravo, sono belle soddisfazioni per noi insegnanti :cool:
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.