Newsgroup: it.comp.lang.c
Titolo: [help] leggere matrice

ciao a tutti,
ho un dubbio con l'usare i puntatori che google non è riuscito a 
risolvere, quindi lo giro a tutto il newsgroup.
ho un programmino (funzionante! :-) ) che al suo interno legge una 
matrice. il codice preciso è:
====================================
     signed short int ** Samples;
     signed short int    NumCanali;
     signed int        w;
     FILE  * in_wav;
     ...
     for( i=0; i<w; i++)    {
         for( j=0; j<NumCanali ; j++) {
             num_letti = fread( &(Samples[j][i]), sizeof(short int), 1, 
in_wav );
             if(num_letti != 1) {
                 .../* gestisce gli errori */
                 }
             }
         }
     }
====================================
che io vorrei semplificare introducendo una funziona leggi_mat().
Mi (vi) chiedevo se questo svolgerebbe il lavoro desiderato:
====================================
	signed short int ** Samples;
	signed short int    NumCanali;
	signed int	    w;
	FILE  * in_wav;
	...
	esito = leggi_matrice(samples, file, w, NumCanali);
====================================
con
====================================
int
leggi_matrice( signed short int ** matrice, FILE * input, int w, short 
int NumCanali )
{
     ....
     for() {
         num_letti = fread( matrice[j][i], sizeof(short int), 1, input );
         if( num_letti != 1)
             return ERROR_CODE;
         ...
     }
     ...
}
====================================
grazie mille per ogni risposta!
andre

 ====================================
Non ho capito se hai volutamente omesso delle cose.
- le variabile i e j (indici della matrice) non sono inizializzate.
- il for non ha niente dentro le parentesi e dovrebbero esserci 2 for
innestati che incrementano i e j
- manca un "return qualcosa" alla fine della funzione nel caso non ci siano
errori
- ERROC_CODE non è definito
Comunque se ho capito quello che volevi fare, direi che va bene. Cerca di
scrivere meglio il codice la prossima volta.
Poi per non fare confusione e maggiore leggibilità del codice, evita di dare
lo stesso nome all'argomento di una funzione e ad una variabile esterna alla
funzione che viene passata alla funzione come argomento (NumCanali e w). Usa
2 nomi diversi

 ha scritto nel messaggio
news:mnq4h.35553$uv5.2...@twister1.libero.it...

No. Il codice non va bene.
Per fare quello che l'OP intende fare occorre utilizzare l'informazione
(fondamentale) del numero di colonne.
Se si passa ad una funzione un argomento di tipo
(TIPO **s,...)
e poi si usa l'espressione s[i][j]
allora NON si ottiene assolutamente quanto sperato (e cioè
un accesso ad un array "rettangolare" con un
certo numero di righe e colonne (C).
Ricordo che in generale P[i] corrisponde a *(P + i)
e P[i][j]   a  *(*(P + i) + j).
Si potrebbe ovviare con un espediente del tipo:
s[i * C + j] dove 's' ha tipo (T *)
e l'informazione del numero di colonne (C) viene utilizzata.
/*
 * s "punta" ad un array "rettangolare" di C colonne.
 */
void manage_array(TIPO *s,int C)
{
    int i,j;
    /* ... */
    s[i * C + j] = ...; /* accesso all'item [i][j] */
    /* ... */
}
Naturalmente il discorso è ben diverso
se invece di passare un array bidimensionale si
intendeva passare un array di puntatori.
Un pò come avviene per:
int main(int argc,char *argv[]) /* analogo a char **argv */
Qui si accede al carattere 'j' della stringa 'i'
con argv[i][j].
Ma NON è stato passato un array bidimensionale
bensì un array di puntatori.
--
Giorgio Silvestri
DSP/Embedded/Real Time OS   Software Engineer

 2 nomi diversi
ok, provvederò
Grazie!
andre

Giorgio Silvestri ha scritto:

in effetti avevo nascosto il modo in cui inizializzo la 'matrice' Samples:
====================================
if( (Samples = malloc( NumCanali * sizeof(signed short int *) ) ) == 
NULL ) {
     errore_in_malloc( "samples", -1 );
     free( Samples );
     fclose(in_wav);
     ...
     return ;
   }
for( i=0; i < NumCanali ; i++) {
     if((Samples[i] = malloc( w*sizeof(short int) ) ) == NULL) {
         errore_in_malloc( "samples", i );
         for( j=i-1; j>=0; j--) {
             free( Samples[j] );
         }
         free(Samples);
         fclose(in_wav);
         ...
         return ;
     }
}
====================================
in questo modo dovrebbe essere corretto, se ho ben recepito il tuo discorso.
Grazie!
andre

 }
Lo standard C99 permette di fare "strane" cose, un tempo inimmaginabili 
:) Faccio un esempio, magari utile anche all'OP:
===================
/* solo per compilatori standard c99
    (eg. gcc -std=c99 -o prova prova.c)
*/
#include <stdio.h>
#include <string.h>
void manage_array(int (*paa)[], int nColonne, int nRighe)
{	
	/* C99 variable-size array */
         int (*paaMatrice)[nColonne] = paa;
         int i, j;
         /* stampa la matrice senza usare operazioni con puntatori */
         for(j = 0; j < nRighe; j++)
         {       for(i = 0; i < nColonne; i++)
                         printf("%2d ", paaMatrice[j][i]); /* <=== */
                 printf("\n");
         }
}
int main(void)
{
         int nRighe = 10;
         int nColonne = 20;
         int aaMatrice[nRighe][nColonne]; /* C99 variable-size array */
         memset(aaMatrice, 0, sizeof(aaMatrice)); /* tutti gli int a 0 */
         /* assegniamo, per prova, 3 numeri alla matrice */
         aaMatrice[1][3] = 33;
         aaMatrice[5][5] = 11;
         aaMatrice[8][12] = 77;
	/* stampiamo la matrice */
         manage_array(aaMatrice, nColonne, nRighe);
         return 0;
}
=======================
Ciao
-- 
Cybertoldo
Per rispondermi via email, sostituisci moc.liamg con 
gmail.com

     int (*pa)[80];
Questo non è il puntatore alla matrice.  E' semplicemente un puntatore a
un array di 80 int.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 un array di 80 int. 
vero: un puntatore ad un array di 80 int (stiamo cercando un puntatore 
di tipo adatto, non di clonare la matrice 'a').
Quindi (se pa = a) pa[3][2] indichera' lo stesso elemento di a[3][2].
(e si e' gia' detto che la matrice di interi e' contigua in memoria)


 Quindi (se pa = a) 
pa ha un tipo incompatibile con a, viste le tue definizioni di prima.


 pa ha un tipo incompatibile con a, viste le tue definizioni di prima.
...fai un po' di prove e, se ti va, spiegami che vuoi dire:
#include <stdio.h>
#include <string.h>
int main(void)
{
         int a[10][20];
         int (*pa)[20];
         int i,j;
         pa = a;
         memset(a, 0, sizeof(a)); /* tutti gli int a 0 */
         a[3][2] = 11;
         pa[4][1] = 22;
         for(i = 0; i < 10; i++) /* righe */
         {       for(j = 0; j < 20; j++) /* colonne */
                         printf("%2d ", pa[i][j]);
                 printf("\n");
         }
  /* verifichiamo anche che: */
  /*  ... P[i] corrisponde a *(P + i) e P[i][j]  a  *(*(P + i) + j). */
         i = 2; j = 4;
         *(*(pa + i) + j) = 77; /* *(*(P + i) + j) */
         printf("con pa: *(*(P + i) + j) = %d\n", *(*(pa + i) + j));
         printf("con a: *(*(P + i) + j) = %d\n", *(*(a + i) + j));
         printf("pa: pa[i][j] = %d\n", pa[i][j]);
         printf("a: a[i][j] = %d\n", a[i][j]);
	return(0);


 ....fai un po' di prove e, se ti va, spiegami che vuoi dire:
Un po' di prove ? naaa... thanks.
Sono io che ti ho chiesto che volevi dire ;-)


 Sono io che ti ho chiesto che volevi dire ;-)
...allora, per completezza faccio anche un altro esempio ;-)
E' simile al primo che ho postato, ma con una malloc() e (eventualmente) 
una typedef (hint: ISO/IEC 9899:1999, eg. esempio 4 in 6.7.5.2).
==============================
/* solo per compilatori standard c99
    (eg. gcc -std=c99 -o prova prova.c)
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void stampa(int (*ppa)[], int nColonne, int nRighe)
{
         int i,j;
         typedef int (*PVLA_MATRICE)[nColonne];
         PVLA_MATRICE paaMatrice = ppa;
         /* oppure: int (*paaMatrice)[nColonne] = ppa; */
         for(i = 0; i < nRighe; i++)
         {       for(j = 0; j < nColonne; j++)
                         printf("%2d ", paaMatrice[i][j]);
                 printf("\n");
         }
}
int main(void)
{
         int nDim;
         void *p;
         int nRighe = 40;
         int nColonne = 30;
         nDim = sizeof(int) * nRighe * nColonne;
/* creiamo dinam. qualcosa di simile a:matrice[nRighe][nColonne] */
         if(!(p = malloc(nDim)))
                 return -1;
         memset(p, 0, nDim);
/* dichiariamo semplicemente cosi': */
         int (*paaMatrice)[nColonne] = p;
/* ...oppure:
         typedef int (*PVLA_MATRICE)[nColonne];
         PVLA_MATRICE paaMatrice = p;
*/
         paaMatrice[3][2] = 11;
         paaMatrice[4][1] = 22;
         stampa(paaMatrice, nColonne, nRighe);
         free(p);
         return(0);
}
Ciao


 discorso.
Si', se ho capito bene, "concettualmente" dovrebbe essere corretto.
Per costruirti la "matrice" non usi un array bidimensionale ma un array 
di puntatori.
Pensando possa essere utile, ho riscritto velocemente il solito esempio 
(compreso il passaggio argomenti a funzione) usando questa volta un 
array di puntatori (praticamente come hai fatto tu).
Confrontalo, se vuoi, con gli altri esempi (in questo thread) che ho 
postato ieri basati, invece, su un array bidimensionale.
Ciao
===================================================
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void stampa(short int **apMatrice, int nColonne, int nRighe)
{
	int i,j;
	for(i = 0; i < nRighe; i++)
	{	for(j = 0; j < nColonne; j++)
			printf("%2d ", apMatrice[i][j]);
		printf("\n");
	}
}
int main(void)
{
	int i;
	int nRighe = 40;
	int nColonne = 30;
	int nRet = -1;
	short int **apMatrice = NULL;
	/* nb. la calloc() inizializza a 0 la memoria richiesta */
	if(!(apMatrice = calloc(nRighe, sizeof(*apMatrice))))
		goto clean_exit;
	for(i = 0; i < nRighe; i++)
		if(!(apMatrice[i] = calloc(nColonne, sizeof(**apMatrice))))
			goto clean_exit;
	apMatrice[3][2] = 11;
	apMatrice[4][1] = 22;
	stampa(apMatrice, nColonne, nRighe);
	nRet = 0;
clean_exit:  /* ah, il buon goto :) */
	if(apMatrice)
	{	for(i = 0; i < nRighe; i++)
			if(apMatrice[i])
				free(apMatrice[i]);
		free(apMatrice);
	}
	return(nRet);


 2 nomi diversi
?? perche' crea confusione?


 Ciao
grazie mille!
adesso posso dire di capirne molto di più.
andre