|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
[C] Media numeri dinamica
Sto facendo qualche semplice esercizio sull'allocazione dinamica della memoria, per capire bene come funziona.
Ho già dei problemi a fare l'esercizio proposto: inseriti quanti voti si vogliono inserire, allocare memoria sufficiente per contenerli tutti e calcolarne la media. Ho scritto questo: Codice:
#include <stdio.h>
#include <stdlib.h>
void get_numbers (float array[], int num);
float sum ( float array[], int num);
float average ( float sum, int num);
void print_values ( float array[], float sum, int num, float avg);
int main ()
{
int num=0;
float *array, sumvalue, avg;
printf("Quanti numeri vuoi inserire?\n");
scanf("%d", &num);
if( (array= (float *)calloc(num, sizeof(float)))== NULL)
{
printf("Allocation error\n");
return -1;
}
else {
get_numbers( array, num);
sumvalue = sum ( array, num);
avg = average ( sumvalue, num);
print_values(array, sumvalue, num, avg);
return 0;
}
}
void get_numbers ( float array[], int num)
{
int i;
for ( i=0; i < num; i++)
{
scanf("%f", &array[i]);
}
}
float sum ( float array[], int num)
{
int i;
float sum;
for (i=0; i < num; i++)
sum += array[i];
return sum;
}
float average ( float sum, int num)
{
float average;
average= sum/num;
return average;
}
void print_values ( float array[], float sum, int num, float avg)
{
int i;
printf("You've enter %d numbers\n", num);
printf("These are: ");
for ( i=0; i < num; i++)
printf("%f ", array[i]);
printf("\nThe sum is: %f\n", sum);
printf("The average is: %f\n", avg);
}
Che sto sbagliando? Inoltre, nel programma d'esempio viene usata questa dicitura: v= (float *)calloc(num, sizeof( float )); È indispensabile (float * ) prima di calloc? Perchè? Nei prototipi ho provato a sostituire *array con array[] ma la sostanza non cambia... Grazie, Kwb
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
Ultima modifica di kwb : 13-08-2010 alle 12:03. |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
A me così ad occhio sembra corretta l'allocazione della memoria. Non capisco quale sia il problema...
Quel (*float) è un casting esplicito del valore restituito dalla funzione calloc, ossia un puntatore di tipo void. Ti avverto però che potresti anche trovare codici dove invece il casting è implicito e quindi senza (*float). PS: perchè la funzione sum la chiami nel main, non sarebbe logicamente più corretto chiamarla in average? Poi a funzionare funziona comunque.... |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Col debugger si vede che terminato il primo ciclo for ( stiamo parlando della funzione per acquisire in numeri ) e immagazzinato nel vettore il primo valore inserito, dal secondo in poi gli altri valori non vengono salvati all'interno del vettore ( o almeno il debugger non li fa vedere... ). Per la funzione sum: si hai ragione, ma è un programma che ho fatto alla svelta... EDIT: Ma era impazzito XCode... Ora funziona... Va a sapere... Per quanto riguarda (float *): ho provato a toglierlo e a metterlo e non cambia assolutamente nulla. Se ho ben capito, da quello che hai detto, serve a convertire il risultato della funzione calloc ( che è generalmente void ) in un float, corretto?
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
Ultima modifica di kwb : 13-08-2010 alle 16:39. |
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
Codice:
float sum; for (i=0; i < num; i++) sum += array[i]; |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
A me il programma funziona bene. Nessun errore anche con più numeri.
Codice:
matteo@Moon:~$ ./a.out Quanti numeri vuoi inserire? 10 1 2 3 4 5 6 7 8 9 10 You've enter 10 numbers These are: 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000 9.000000 10.000000 The sum is: 55.000000 The average is: 5.500000 sul fatto che con il debugger non ti ritrovi i numeri nell'array come vorresti è probabilmente, perchè stiamo lavorando con il tipo float (http://en.wikipedia.org/wiki/Floatin...dern_computers) infatti se guardo la memoria all'altezza di dove l'array è allocato non mi trovo i numeri espressi in integer, anzi non si capisce proprio niente.... Codice:
... Breakpoint 1, get_numbers (array=0x804b008, num=5) at test.c:39 39 } (gdb) print array $1 = (float *) 0x804b008 (gdb) x/10x array 0x804b008: 0x3f800000 0x40000000 0x40400000 0x40800000 0x804b018: 0x40a00000 0x00020fe9 0x00000000 0x00000000 0x804b028: 0x00000000 0x00000000 ... mi pare che usi la mantissa il calcolatore. ma può anche essere che mi sia fumato il cervello e non sia così, mi pare... Ultima modifica di Teo@Unix : 13-08-2010 alle 17:26. |
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Fatto sta che non si sa perchè XCode era impazzito e c'era qualcosa hc enon andava... Ora funziona perfettamente il probramma, sia con interi che con numeri con la virgola. Per la visualizzazione nel debugger: Non mi cruccio più di tanto, mi basta che il programma funzioni... Alla fine non poteva essere un problema di caricamento nel vettore perchè tutti i valori venivano caricati correttamente ( infatti venivano stampati giusti ). Domanda, faccio un programma allocando la memoria come questo, quindi: float *v; v= calloc(qta_elementi, grandezza) Poi quando lo devo utilizzare in una funzione secondaria, è indifferente chiamarlo così: void funzione ( float *v ) O così: void funzione ( float v[] ) ? Grazie Kwb
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Mar 2009
Messaggi: 753
|
|
|
|
|
|
|
#8 | |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Quote:
E' indifferente perchè la notazione v[i] sarebbe l'equivalente più elegante di scrivere v+i (aritmetica dei puntatori). |
|
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Un'ultima domanda: quale è l'utilità di convertire un risultato di una funzione void in qualcos'altro?
Nel caso specifico, qual è l'utilità di convertire il void del calloc in float?
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
#10 |
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Più che un utilità la conversione è una necessità che si ha quando il tipo dell'espressione richiesta non è lo stesso tipo dell'espressione passata. Ma non sempre è possibile il casting, infatti i tipi devono essere tra loro compatibili.
Nel tuo caso hai avuto la necessità di fare un casting perchè la calloc ti restituiva un void* ma a te serviva un float* da mettere dentro array. |
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
E poi scusa, che utilità ha dichiarare una variabile di tipo nulla ( a patto che si possa )?
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
|
il tipo void* viene usato per avere una specie di genericità, infatti vedrai che non è possibile dereferenziare un void*, quindi è necessario un cast
se il tuo compilatore non è del paleolitico il cast da void* a float* lo fa implicitamente se scrivi float *f = malloc(sizeof(float)); quindi non serve esplicitarlo |
|
|
|
|
|
#13 | |||
|
Member
Iscritto dal: Apr 2007
Messaggi: 182
|
Quote:
Quote:
Quote:
|
|||
|
|
|
|
|
#14 | |||
|
Senior Member
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
|
Quote:
Quote:
Quote:
( Tanto per dirne una, i miei due professori di programmazione non hanno mai usato il casting sui calloc/malloc ... )
__________________
Dell XPS 13 (9350) :: i5-2500K - HD6870 - AsRock Z68 Pro3 - Corsair Vengeance 8GB (4x2) DDR3 :: Samsung Galaxy S4 GT-i9505
|
|||
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 13:31.




















