Newsgroup: it.comp.lang.c
Titolo: Re: generazione numeri casuali e matrice

 Sono incasinatissima, qualcuno mi sa dire come implementare il codice?
Un paio di dritte ci sono. Poi prova a postare quello che hai 
fatto.
Ciao.

>
grazie per le tue dritte, ma ho molta difficoltà a tradurre in c queste cose che sono molto semplici...sono alle prime armi, spero di migliorare col tempo! ho provato a fare pezzi di codice. Questo dà valori che nn corrispondono alla formula che gli dico di calcolare. ecco il frammento.genero 5 coppie ascissa-ordinata.
è giusto a livello logico e sintattico? grazie!!!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 5
#define MIN 0
#define MASS 6.28//(2*pi)
#define R 1.0
float rand_flat();
float rand_uniform(float min, float mass);
double ascissa();
double ordinata();
int main(){
int i;
for(i=0;i<N;i++)
{
printf("%f,%f\n,%f,%f\n", rand_flat(),rand_uniform(MIN,MASS),ascissa(), ordinata()); 
}
}
double ascissa()
{
double e;
return R*cos(rand_uniform(MIN,MASS));
}
double ordinata()
{
double z;
return R*sin(rand_uniform(MIN, MASS));
}
float rand_flat()
	{
    float x=0;
    x=(float)rand()/(float)RAND_MAX;   
    return x;
	}
float rand_uniform(float min, float mass)
	{
            float theta;
	     return rand_flat()*(mass-min)+min;
 
	}
-- 
Questo articolo e` stato inviato dal sito web 
http://www.nonsolonews.it

 rand_flat(),rand_uniform(MIN,MASS),ascissa(), ordinata());
Sono sbagliate le funzioni ascissa e ordinata, dato che queste devono 
lavorare sullo stesso numero per essere correlate. Passagli un argomento 
comune. Cioè generi un numero pseudo-casuale, lo salvi in una variabile e 
poi la usi per calcolare ascissa e ordinata.
-- 
Costantino Grana 

poi la usi per calcolare ascissa e ordinata.
grazie!
ho provato ma nn funziona...e in questi casi...quando niente funziona...vuol dire che c'è qualche puntatore di troppo o in meno...come vedi sono messa bene!!ora ci penso un pò su!!grazie ancora!!!
sophos


poi la usi per calcolare ascissa e ordinata.
Così il compilatore mi dà "nan":
ho fatto una prova.dov'è il problema? nn so proprio riconoscerlo...
int main()
{
double a=1;
printf("%f\n", ascissa(a,&a)); 
}
double ascissa(double theta,double *p)
{
*p=cos(theta);


 }
Ma che necessità c'è di usare i puntatori? Comunque l'errore è 
che ascissa() non ritorna niente e tu fai stampare il valore 
di ritorno di ascissa().
Ciao.

printf("%f\n", ascissa(a,&a)); 
il valore di ritorno della funzione "ascissa". Purtroppo essa non
ritorna nulla...
Cosi' va meglio:
void ascissa (double theta,double *p)
{
*p = cos (theta);
}
int main ()
{
double a=1.0;
ascissa (a,&a);
printf ("%f\n",a); 
return 0;
}
PS. Ma che compilatore usi?

 PS. Ma che compilatore usi?
gcc con linux. perchè?
grazie, ora va bene...però la faccenda si complica un pochino, perchè
l'angolo di cui voglio calcolare il coseno (per trovare l'ascissa di
un punto su un cerchio...farò poi anche col seno per l'ordinata) devo
generarlo a caso tra 0 e 2pi. ecco qua...ma non funziona (mi dà due
numeri non compatibili!):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 3
#define MIN 0
#define MASS 6.28
#define R 1.0
double rand_uniform(float min, float mass);
double ascissa(double theta, double *p);
int main()
{
double a= rand_uniform(MIN,MASS);
ascissa(a,&a);
printf("%f\n %f\n",rand_uniform(MIN,MASS),a);
return 0;
}
double ascissa(double theta,double *p)
{
*p=R*cos(theta);
}
 double rand_uniform(float min, float mass)
	{
            double alpha=0;
	     alpha= ((float)rand()/(float)RAND_MAX)*6.28;
              return alpha;
	}

 numeri non compatibili!):
Scusa, ma a te serve un medesimo angolo per calcolare ascissa 
e ordinata. Rileggi il tuo codice e noterai che ne stai 
generando due. E, tra l'altro, la funzione ascissa() è nefasta 
a meno che non sia intenzionale. Le passi a (angolo) e &a e 
dentro modifichi il valore di a, che non è più l'angolo, ma 
R*cos(a).
La cosa più ovvia è generare l'angolo una sola volta e 
passarlo come unico argomento alle funzioni ascissa() e 
ordinata() le quali restituiranno valori che opportunamente ti 
salverai.
Ciao.

 Ciao.
ok! credo di esserci...finalmente!
ecco il frammento...Grazie a tutti!!! ora devo assegnare i numeri così
ottenuti ad elementi di una matrice di dim a scelta...
suggerimenti??
#define MIN 0
#define MASS 6.28
#define R 1.0
float rand_flat();
int main(){
srand(time(NULL));
int i;
double asc,ord,theta;
    for(i=0;i<N;i++)
{
     theta=rand_flat()*6.28;
     asc=R*cos(theta);
     ord=R*sin(theta);
    printf("%f\%f\%f\n",theta,asc,ord);
}
return 0;


 suggerimenti??
"A scelta" cosa significa? Che le dimensioni sono libere, ma 
fissate a compile time o che vengono specificate dall'utente 
di volta in volta a run time?
Nel primo caso dichiari una matrice normalmente, nel secondo 
devi usare l'allocazione dinamica (puoi farti un'idea leggendo 
qui: 
http://c-faq.com/aryptr/dynmuldimary.html
 ).
Ciao.

 Ciao.
Ciao..grazie per i preziosi consigli. ho provato come dicevi tu,il
codice compila ma mi dà il messaggio di errore su un controllo dello
spazio che gli faccio fare...e nn capisco il perchè!
"Non ho abbastanza spazio per allocare la riga 0 di una matrice"(la
riga 0 non dovrebbe esistere!)
questo l'ho fatto per capire come si riempie una matrice, ma il mio
probl è che nel file di output che mi serve ci sono due elementi per
riga e 100 colonne! (100 coordinate x,y). io voglio che il codice
legga ad esempio la coordinata x1,y1 dal file e riempia l'elemento
corrispondente. come si potrebbe fare? la cosa si complica... grazie!!
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef double elemento;
typedef elemento ** Matrice;
Matrice CreaMatrice(const int nrighe, const int ncol);
Matrice RiempiMatrice(FILE *ifp,const int nrighe,const int ncol);
int main(int argc, char *argv[])
{
  int n=0;
  FILE *ifp;
  Matrice M;
  ifp=fopen(argv[1],"r");
  if(ifp == NULL){
	fprintf(stderr,"Impossibile aprire il file %s \n",argv[1]);
	exit(1);
  }
  printf("Inserisci la dimensione della matrice\n");
  scanf("%d",&n);/*QUI DICHIARO DIM MATRICE*/
  /* Riempie la matrice M con i punti letti dal file in input;
     la matrice viene allocata e inizializzata in RiempiMatrice
   */
  const int nrighe, ncol;
  M = RiempiMatrice(ifp,n,n);
  fclose(ifp);
 printf("la matrice riempita è %d,%d
\t",RiempiMatrice(ifp,nrighe,ncol));
  return(0);
}
Matrice CreaMatrice(const int nrighe,const int ncol){
  Matrice p;
  int i;
  /* Alloca il puntatore alla matrice, cioe' ad un vettore di
puntatori, uno per ciascuna riga */
  p=(Matrice)malloc(nrighe*sizeof(elemento*));
  /* Controlla che l'allocazione abbia avuto successo */
  if(p==NULL) {
    fprintf(stderr,"Non ho abbastanza spazio per allocare una matrice
\n");
    exit(1);
  }
  for(i=0; i<nrighe;i++){
    /* Per ogni riga alloc spazio per gli elementi della matrice,
inizializzandoli a zero */
    p[i]=(elemento*)calloc(ncol,sizeof(elemento));
    /*controllo spazio. E' QUI L'ERRORE!*/
    if(p[i]==NULL) {
      fprintf(stderr,"Non ho abbastanza spazio per allocare la riga %d
di una matrice\n",i);
      exit(1);
    }
  }
  return(p);
}
Matrice RiempiMatrice(FILE *ifp,const int nrighe,const int ncol){
  int i,j;
  Matrice ma;
  /* Allocazione dinamica della matrice */
  ma=CreaMatrice(nrighe,ncol);
  /* Copia dati dai file */
  for(i=0;i<nrighe;i++)
    {
      for(j=0;j<ncol;j++)
	{
	  fscanf(ifp,"%lf", &ma[i][j]);
	  if(feof(ifp)){
	    fprintf(stderr,"Il file non contiene abbastanza elementi !\n");
	    exit(1);
	  }
	}
    }
  }

 questo l'ho fatto per capire come si riempie una matrice, ma il mio
il codice non va bene... ma posso farti una domanda: per caso usi il 
compilatore gcc, o cmq capace di supportare i VLA del C99?
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

   }
Questa funzione deve restituire "ma". E comunque le letture da
file saranno diverse in funzione di quello che ho scritto
prima. Ovvero dovrai leggere 2 valori e fare gli opportuni
calcoli per conoscere la posizione del punto in matrice.
Ciao.

 compilatore gcc, o cmq capace di supportare i VLA del C99?
uhm... non vorrei averti sconcertata con questa domanda... :)
La riformulo: Che compilatore usi?
Ciao


 Ciao
Ciao, credevo di averti risposto..prova a guardare qualche post fa...
cmq uso gcc...perchè?

 codice compila ma mi dą il messaggio di errore...
Ok, usi il gcc. Quindi hai piu' di un metodo per creare matrici con 
numero di righe/colonne impostabili in run-time.
Ti scrivo 3 esempi (A, B e C) per creare e popolare una matrice come 
vuoi tu (ne avevo gia' postati di simili in passato).
Considerali esempi di complemento alla faq sopra 
http://c-faq.com/aryptr/dynmuldimary.html
Spero che intanto ti siano di aiuto per definire la tua struttura dati...
....poi passiamo al tuo prossimo problema :)
Ciao
================================================
====== esempio A ===============================
================================================
/*  Versione con semplice matrice a dim. variabili (VLA)
     Solo per compilatori standard c99
     (eg. gcc -std=c99 -o mtrA mtrA.c)
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
la funzione sotto puo' essere dichiarata anche come:
void doPrint(int nCols, int nRows, double (*pa)[nCols]);
void doPrint(int nCols, int nRows, double pa[][nCols]);
void doPrint(int nCols, int nRows, double pa[nRows][nCols]);
L'ordine dei parametri e' importante: 'int nCols, int nRows'
deve venire prima di 'double pa[nRows][nCols]'
*/
void doPrint(int nCols, int nRows, double pa[nRows][nCols])
{
	int x, y;
	for(y = 0; y < nRows; y++)
	{	for(x = 0; x < nCols; x++)
			printf("%.2f ", pa[y][x]);
		printf("\n");
	}
}
int main(void)
{
	/* imposta qui il numero di righe e di colonne a piacere */
	int nCols = 10, nRows = 20;
	int x, y;
	double aMatrix[nRows][nCols]; /* normalmente allocata sullo stack del 
programma */
         /* Inizializza a 0 la memoria. Metodo rapido ma NON portabile 
con i double:
	memset(aMatrix, 0, sizeof(aMatrix));
	*/
         /* Inizializza a 0 la memoria. Metodo portabile con i double: */
	for(y = 0; y < nRows; y++)
		for(x = 0; x < nCols; x++)
			aMatrix[y][x] = 0.0;
	/* -------- */
	/* inserisce x prova alcuni valori */
	aMatrix[1][1] = 1.11;
	aMatrix[2][2] = 2.22;
	aMatrix[3][3] = 3.33;
	aMatrix[4][4] = 4.44;
	/* stampa i valori */
	doPrint(nCols, nRows, aMatrix);
         return EXIT_SUCCESS;
}
================================================
====== esempio B ===============================
================================================
/*  Versione dinamica con puntatore ad array di n double.
     Solo per compilatori standard c99
     (eg. gcc -std=c99 -o mtrB mtrB.c)
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/*
la funzione sotto puo' essere dichiarata anche come:
void doPrint(int nCols, int nRows, double (*pa)[nCols]);
void doPrint(int nCols, int nRows, double pa[][nCols]);
void doPrint(int nCols, int nRows, double pa[nRows][nCols]);
L'ordine dei parametri e' importante: 'int nCols, int nRows'
deve venire prima di 'double pa[nRows][nCols]'
*/
void doPrint(int nCols, int nRows, double pa[nRows][nCols])
{
	int x, y;
	for(y = 0; y < nRows; y++)
	{	for(x = 0; x < nCols; x++)
			printf("%.2f ", pa[y][x]);
		printf("\n");
	}
}
int main(void)
{
	/* imposta qui il numero di righe e di colonne a piacere */
	int nCols = 10, nRows = 20;
	int x, y;
	/* creiamo dinam. qualcosa di simile a: matrice[nRows][nCols] */
	double (*paMatrix)[nCols] = NULL; /* punt. ad array di nCols double */
         /* Alloca e inizializza a 0 la memoria. Metodo rapido ma NON 
portabile con i double:
	if(!(paMatrix = calloc(nRows, sizeof(*paMatrix))))
		return EXIT_FAILURE;
	*/
	/* Alloca ed inizializza la memoria. Metodo portabile per i double: */
	if(!(paMatrix = malloc(nRows * sizeof(*paMatrix))))
		return EXIT_FAILURE;
	for(y = 0; y < nRows; y++)
		for(x = 0; x < nCols; x++)
			paMatrix[y][x] = 0.0;
	/* -------- */
	/* inserisce x prova alcuni valori */
	paMatrix[1][1] = 1.11;
	paMatrix[2][2] = 2.22;
	paMatrix[3][3] = 3.33;
	paMatrix[4][4] = 4.44;
	/* stampa i valori */
	doPrint(nCols, nRows, paMatrix);
	free(paMatrix);
	return EXIT_SUCCESS;
}
================================================
====== esempio C ===============================
================================================
/*  Versione con array dinamico di puntatori
     Compilatori standard c90/ansi-c
     (eg. gcc -ansi -o mtrC mtrC.c)
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void doPrint(int nCols, int nRows, double **ap)
{
	int x, y;
	for(y = 0; y < nRows; y++)
	{	for(x = 0; x < nCols; x++)
			printf("%.2f ", ap[y][x]);
		printf("\n");
	}
}
int main(void)
{
	/* imposta qui il numero di righe e di colonne a piacere */
	int nCols = 10, nRows = 20;
	int x, y;
	int nRet = EXIT_FAILURE;
	double **apMatrix = NULL; /* ci costruiremo dimam. un array di 
puntatori... */
	/* allochiamo l'array di puntatori */
	if(!(apMatrix = malloc(nRows * sizeof(*apMatrix))))
		goto clean_exit; /* uso il goto per rendere il codice + leggibile */
	/* inizializiamo l'array a NULL in modo portabile (eg. senza memset) */
	for(y = 0; y < nRows; y++)
		apMatrix[y] = NULL;
	for(y = 0; y < nRows; y++)
         {	if(!(apMatrix[y] = malloc(nCols * sizeof(**apMatrix))))
			goto clean_exit;
		for(x = 0; x < nCols; x++)
			apMatrix[y][x] = 0.0;
	}
	/* -------- */
	/* inserisce x prova alcuni valori */
	apMatrix[1][1] = 1.11;
	apMatrix[2][2] = 2.22;
	apMatrix[3][3] = 3.33;
	apMatrix[4][4] = 4.44;
	/* stampa i valori */
	doPrint(nCols, nRows, apMatrix);
	nRet = EXIT_SUCCESS;
clean_exit:
	/* libera memoria (e solo quella che e' riuscito ad allocare, se c'e' 
stato un errore) */
	if(apMatrix)
	{	for(y = 0; y < nRows; y++)
			if(apMatrix[y])
				free(apMatrix[y]);
		free(apMatrix);
	}
	return(nRet);



 Grazie mille..credo che avrò pane per i miei denti per il weekend!
spero di imparare queste tecniche che mi hai illustrato! intanto ecco
il mio codice "terra-terra": cmq sono contenta perchè ho iniziato da
poco, ma mi sento molto imbranata lo stesso! ma quanto ci vuole ad
imparare decentemente?!?! questo funziona se i dati nel file
"dati.out" sono interi, altrimenti fa cose strane, tronca cifre, mette
0 al posto di numeri...perchè?
inoltre mi piacerebbe migliorare la scansione della matrice.ho provato
con 2 cicli for annidati ma mi dà segmentation fault...
#include <stdio.h>
#include <stdlib.h>
void stampa_matrice(double[4][4]);
	int main () {
	  FILE *fp;
	  char buf[256];
	  double mat[4][4];
          int riga=0;
	 if((fp=fopen("dati.out","r+"))==NULL)
	  {
	 printf("impossibile aprire il file");
	 return;
}
	else
{
		do
	{
    fgets(buf,256,fp);
    sscanf(buf,"%d%d%d%d",&mat[riga][0],&mat[riga][1],&mat[riga]
[2],&mat[riga][3]);
   	riga ++;
	}
	while(!feof(fp));
	fclose(fp);
	}
	stampa_matrice(mat);
	}
void stampa_matrice(double val[4][4])
{
 int i,j;
  for(i=0;i<4;i++)
{
 printf("\n");
 for(j=0;j<4;j++)
 printf("%d\t", val[i][j]);
}
printf("\n\n\n");
}


