Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi
Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi
Mate X7 rinnova la sfida nel segmento dei pieghevoli premium puntando su un design ancora più sottile e resistente, unito al ritorno dei processori proprietari della serie Kirin. L'assenza dei servizi Google e del 5G pesa ancora sull'esperienza utente, ma il comparto fotografico e la qualità costruttiva cercano di compensare queste mancanze strutturali con soluzioni ingegneristiche di altissimo livello
Nioh 3: souls-like punitivo e Action RPG
Nioh 3: souls-like punitivo e Action RPG
Nioh 3 aggiorna la formula Team NINJA con aree esplorabili più grandi, due stili di combattimento intercambiabili al volo (Samurai e Ninja) e un sistema di progressione pieno di attività, basi nemiche e sfide legate al Crogiolo. La recensione entra nel dettaglio su combattimento, build, progressione e requisiti PC
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti
La facilità di installazione e la completa automazione di tutte le fasi di utilizzo, rendono questo prodotto l'ideale per molti clienti. Ecco com'è andata la nostra prova in anteprima
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 13-08-2010, 12:01   #1
kwb
Senior Member
 
L'Avatar di kwb
 
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);
	
}
Ma sembra ci sia qualche problema nell'allocazione della memoria perchè dal debug vedo che quello che creo non prende la forma di un vettore quando vado ad allocargli la memoria ( si dovrebbe vedere il nome dell'array con x indici in base al numero di elementi da inserire... ).
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.
kwb è offline   Rispondi citando il messaggio o parte di esso
Old 13-08-2010, 12:32   #2
oNaSsIs
Member
 
L'Avatar di oNaSsIs
 
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....
oNaSsIs è offline   Rispondi citando il messaggio o parte di esso
Old 13-08-2010, 16:31   #3
kwb
Senior Member
 
L'Avatar di kwb
 
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
Quote:
Originariamente inviato da oNaSsIs Guarda i messaggi
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....
Il fatto è che se fai girare il programma, i numeri inseriti vengono stampati correttamente, mentre media e somma sono errati ( prova con più di due numeri, finchè ne usi due funziona ) e non ne riesco a venire a capo...
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.
kwb è offline   Rispondi citando il messaggio o parte di esso
Old 13-08-2010, 16:44   #4
tuccio`
Senior Member
 
Iscritto dal: Apr 2010
Città: Frosinone
Messaggi: 416
Codice:
	float sum;
	for (i=0; i < num; i++)
		sum += array[i];
le variabili in C vanno sempre inizializzate, se vuoi che sum parta da 0 devi scriverlo esplicitamente, l'errore che riportavi probabilmente dipende da questo
tuccio` è offline   Rispondi citando il messaggio o parte di esso
Old 13-08-2010, 17:22   #5
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
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
se non mi ricordo male,
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
...
EDIT:
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.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 14-08-2010, 10:20   #6
kwb
Senior Member
 
L'Avatar di kwb
 
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
Quote:
Originariamente inviato da tuccio` Guarda i messaggi
Codice:
	float sum;
	for (i=0; i < num; i++)
		sum += array[i];
le variabili in C vanno sempre inizializzate, se vuoi che sum parta da 0 devi scriverlo esplicitamente, l'errore che riportavi probabilmente dipende da questo
Si a volte il problema è per quello... L'ho imparato a mie spese...
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
kwb è offline   Rispondi citando il messaggio o parte di esso
Old 14-08-2010, 10:35   #7
Teo@Unix
Senior Member
 
L'Avatar di Teo@Unix
 
Iscritto dal: Mar 2009
Messaggi: 753
Quote:
Originariamente inviato da kwb Guarda i messaggi
Poi quando lo devo utilizzare in una funzione secondaria, è indifferente chiamarlo così:
void funzione ( float *v )
O così:
void funzione ( float v[] )

?

Grazie
Kwb
direi di si.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 16-08-2010, 12:49   #8
oNaSsIs
Member
 
L'Avatar di oNaSsIs
 
Iscritto dal: Apr 2007
Messaggi: 182
Quote:
Originariamente inviato da kwb Guarda i messaggi
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?
Esatto, si tratta di una conversione, generalmente detta casting, ma nel tuo caso se si vuol essere più precisi si parla di coercizione, perchè sei stato tu programmatore ad esplicitare questa conversione, mentre se è il compilatore ad applicarla automaticamente allora si parla di casting, ed è il caso che ti dicevo prima di codici dove quel (float*) viene omesso.

Quote:
Originariamente inviato da kwb Guarda i messaggi
Poi quando lo devo utilizzare in una funzione secondaria, è indifferente chiamarlo così:
void funzione ( float *v )
O così:
void funzione ( float v[] )
E' indifferente perchè la notazione v[i] sarebbe l'equivalente più elegante di scrivere v+i (aritmetica dei puntatori).
oNaSsIs è offline   Rispondi citando il messaggio o parte di esso
Old 17-08-2010, 10:44   #9
kwb
Senior Member
 
L'Avatar di kwb
 
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
kwb è offline   Rispondi citando il messaggio o parte di esso
Old 17-08-2010, 11:27   #10
oNaSsIs
Member
 
L'Avatar di oNaSsIs
 
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.
oNaSsIs è offline   Rispondi citando il messaggio o parte di esso
Old 17-08-2010, 17:14   #11
kwb
Senior Member
 
L'Avatar di kwb
 
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
Quote:
Originariamente inviato da oNaSsIs Guarda i messaggi
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.
Ma in realtà io il ( float * ) davanti a calloc non c'è l'ho messo e funziona uguale
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
kwb è offline   Rispondi citando il messaggio o parte di esso
Old 17-08-2010, 17:54   #12
tuccio`
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
tuccio` è offline   Rispondi citando il messaggio o parte di esso
Old 17-08-2010, 20:24   #13
oNaSsIs
Member
 
L'Avatar di oNaSsIs
 
Iscritto dal: Apr 2007
Messaggi: 182
Quote:
Originariamente inviato da kwb Guarda i messaggi
Ma in realtà io il ( float * ) davanti a calloc non c'è l'ho messo e funziona uguale
In un precedente post avevo scritto
Quote:
Originariamente inviato da oNaSsIs
Ti avverto però che potresti anche trovare codici dove invece il casting è implicito e quindi senza (*float).
Se tu non espliciti il cast in quel caso lo fa il compilatore per te durante la compilazione. Questo però non avviene sempre, quindi è buona abitudine esplicitarlo, così si rende anche il codice più leggibile.
Quote:
Originariamente inviato da kwb
E poi scusa, che utilità ha dichiarare una variabile di tipo nulla ( a patto che si possa )?
Come ti ha detto tuccio restituire un void ti permette di usare la medesima funzione nei più svariati contesti senza dover tener conto del tipo di puntatore che si sta utilizzando, altrimenti sarebbe stato necessario scrivere una calloc per ogni tipo di puntatore.
oNaSsIs è offline   Rispondi citando il messaggio o parte di esso
Old 18-08-2010, 10:32   #14
kwb
Senior Member
 
L'Avatar di kwb
 
Iscritto dal: Jul 2003
Città: Alessandria
Messaggi: 10167
Quote:
Originariamente inviato da tuccio` Guarda i messaggi
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
Quote:
Originariamente inviato da oNaSsIs Guarda i messaggi
In un precedente post avevo scritto

Se tu non espliciti il cast in quel caso lo fa il compilatore per te durante la compilazione. Questo però non avviene sempre, quindi è buona abitudine esplicitarlo, così si rende anche il codice più leggibile.
Ah si, ecco mi era sfuggito, non avevo colto il senso dell'implicito

Quote:
Originariamente inviato da oNaSsIs Guarda i messaggi
Come ti ha detto tuccio restituire un void ti permette di usare la medesima funzione nei più svariati contesti senza dover tener conto del tipo di puntatore che si sta utilizzando, altrimenti sarebbe stato necessario scrivere una calloc per ogni tipo di puntatore.
Si è vero, ci ho pensato ora, grazie di queste delucidazioni che non vengono mai dette dai professori
( 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
kwb è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Recensione HUAWEI Mate X7: un foldable ottimo, ma restano i soliti problemi Recensione HUAWEI Mate X7: un foldable ottimo, m...
Nioh 3: souls-like punitivo e Action RPG Nioh 3: souls-like punitivo e Action RPG
Test in super anteprima di Navimow i220 LiDAR: il robot tagliaerba per tutti Test in super anteprima di Navimow i220 LiDAR: i...
Dark Perk Ergo e Sym provati tra wireless, software via browser e peso ridotto Dark Perk Ergo e Sym provati tra wireless, softw...
DJI RS 5: stabilizzazione e tracking intelligente per ogni videomaker DJI RS 5: stabilizzazione e tracking intelligent...
I produttori non faranno sconti sulle me...
Ubisoft potrebbe cedere pezzi se il pian...
Qualcomm potrebbe utilizzare una tecnolo...
Starfield per Nintendo Switch 2 potrebbe...
Un MacBook Pro a -300€, i MacBook Air M4...
Amazon abbassa i prezzi sugli iPhone: sc...
Amazon, ancora sconti sugli smartphone A...
iPhone Air 2 'riciclerà' alcuni c...
Offerta Amazon da non perdere: lo speake...
Nioh 3 debutta alla grande su Steam: pri...
Al centro della Via Lattea ci potrebbe e...
Elon Musk ora guarda alla Luna: SpaceX p...
La Cina ha lanciato nuovamente lo spazio...
Blue Origin potrebbe realizzare il lande...
Artemis II: il prossimo Wet Dress Rehear...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 13:31.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v