Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa
Marvel's Wolverine porta Logan in un'avventura inedita, violenta e fortemente narrativa, costruita attorno alla sua natura di combattente e al difficile rapporto con il proprio passato. Insomniac Games punta su combattimenti spettacolari, progressione e personalizzazione, inserendo l'azione in un mondo segnato dalla persecuzione dei mutanti. Un viaggio intenso, che alterna mattanza, esplorazione e momenti sorprendentemente emotivi.
DJI Romo 2: tante novità lo rendono un robot completo
DJI Romo 2: tante novità lo rendono un robot completo
Romo 2 è la seconda generazione di robot lavapavimenti di DJI, un modello che si caratterizza per la precisione nel sistema di navigazione e per il funzionamento particolarmente silenzioso. Con le modifiche introdotte in questa seconda versione, e un posizionamento di prezzo più allineato alla concorrenza, rappresenta una valida alternativa sul mercato delle soluzioni di pulizia domestica
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED
Il primo Sony con retroilluminazione True RGB alla prova del banco di misura e dei contenuti: luminanza enorme, colori accurati in HDR e un antiriflesso molto efficace. I limiti sono due sole HDMI 2.1 e il blooming fuori asse
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 13-08-2010, 11: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 11:03.
kwb è offline   Rispondi citando il messaggio o parte di esso
Old 13-08-2010, 11: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, 15: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 15:39.
kwb è offline   Rispondi citando il messaggio o parte di esso
Old 13-08-2010, 15: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, 16: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 16:26.
Teo@Unix è offline   Rispondi citando il messaggio o parte di esso
Old 14-08-2010, 09: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, 09: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, 11: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, 09: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, 10: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, 16: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, 16: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, 19: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, 09: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


Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
Sony Bravia 9 II: il True RGB alla prova, dove l'LCD sfida l'OLED Sony Bravia 9 II: il True RGB alla prova, dove l...
Geely EX5, un mese al volante: il SUV elettrico cinese che ci ha sorpreso (quasi) senza riserve Geely EX5, un mese al volante: il SUV elettrico ...
Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare Mova Z70 Ultra Roller Complete: motore potente, ...
La prima missione orbitale del razzo spa...
Servizi in streaming sempre più c...
Anteprima della Leapmotor B03X: inizia l...
Anthropic accusa la Cina: Claude utilizz...
I satelliti Rassvet (Starlink russo) di ...
Un agente IA ha risolto un problema su W...
Cina: la CMSA potrebbe cambiare parte de...
68 mensilità di bonus per i dipen...
Rocket Lab ha fatto ricorso contro la de...
Nutanix rende disponibile Azure Virtual ...
Il padrino del deep learning avverte: gl...
Il finto avviso "iPhone Storage is Full"...
Dietrofront in Cina, addio touchscreen p...
Un piccolo accessorio trasforma lo smart...
Dopo 370 anni il Cyphral Distich non è p...
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: 21:27.


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