Newsgroup: it.comp.lang.c++
Titolo: matrici

Ho visto che in c++ le matrici, quando vengono passate ad altre funzioni, la
prima dimensione non viene passata mentre viene passata solo la seconda.
    Perchè questo?
Saluti, Andrea.

 wrote in message 8dii6n$4ik$2...@nslave2.tin.it...


     Perchè questo?
Perché in realtà non vengono passate le matrici ma i puntatori. Es.:
char array[ 80 ];
pippo( array );
a pippo() viene passato un tipo char * che punta al primo elemento
dell'array.
char matrice[ 10 ][ 20 ];
pluto( matrice );
a pluto() viene passato un tipo char (*)[ 20 ] che punta alla prima riga
della matrice. Infatti le dichiarazioni delle funzioni di cui sopra sono
void pippo( char *p );
void pluto( char (*p)[ 20 ] );
oppure
void pippo( char p[] );
void pluto( char p[][ 20 ] );
che sono perfettamente equivalenti.
EMG

    Perchè questo?
Per dare modo al compilatore di compiere l'aritmetica sui puntatori.
Ti spiego :
Scrivere :
  func( int a[] ) ;
equivale a scrivere :
  func( int *a ) ;
Cosi' come scrivere :
  func( int a[][10] ) ;
equivale a scrivere :
  func( int *a[10] ) ;
E' illegale, invece, una forma del tipo :
 
  func( int a[][] ) ;
perche' non si da' modo al compilatore di compiere l'aritmetica sui
puntatori, cioe' di capire quanto e' grande il tipo puntato.

   func( int *a[10] ) ;
Tempo fa mi sembra che mi avevi corretto tu per la stessa cosa. Ora è il
mio turno: :-)
func( int (*a)[10] ) ;
EMG

func( int (*a)[10] ) ;
No, stai attento.
Scrivere:
int *a[10] 
(forma in cui "int a[][10]" decade nella dichiarazione dei parametri
formali)
e' ben diverso dallo scrivere
int (*a)[10]
Il primo e' un vettore di 10 puntatori a interi (e quindi si puo'
interpretare come un vettore di 10 array di interi).
Il secondo invece e' un puntatore ad array di 10 interi.
La dichiarazione giusta e' la prima.

void pluto( char p[][ 20 ] );
Queste due forme non sono affatto equivalenti.

you wrote:

Cazzata, vedere altro msg.

>mio turno: :-)
Hai ragione.
Ho detto una cazzata ;)
Tutti sti vector mi stanno dando alla testa.
In effetti scrivere 
func( int a[][10] ) ;
e
func( int (*a)[10] ) ;
e' equivalente.
Per rendersene conto, bisogna considerare la "decadenza" dei vettori
in puntatori al primo elemento.
Sto perdendo colpi, che ci vuoi fare ? ;)


Attenzione, la 3a e la 4a dichiarano un'array di puntatori, non delle
matrici. Infatti quando dichiariamo
int a[5][20];
noi NON riserviamo un'area ai puntatori. Mentre un vettore e un puntatore
sono equivalenti, una matrice ed un vettore di puntatori sono diversi.
La risposta alla domanda iniziale è molto piu' semplice : il primo indice
dell'array non e' passato perche' non serve.
infatti se dichiariamo un array del tipo
int a[d1][d2]
l'indirizzo della cella a[i][j] e' pari a
 
&(a[0][0])+i*d2+j
( nota: compare solo d2 ).
se dichiariamo un'array del tipo
int b[d1][d2][d3];
l'indirizzo della cella b[i][j][k] e' pari a 
&(b[0][0][0]) + i * ( d2 * d3 ) + j * d3;
Come si vede d1 ancora NON serve.
Se vuoi una riprova ecco:
[ghigo@sphera:/tmp]$ cat t.c
#include <stdio.h> 
char    a[3][4];
char	b[4]; 
void main( ){       
	printf("a[0]=%p; b=%p\n",a[0],b);        
	a[0]=b;
	printf("a[0]=%p\n",a[0]);
}  
[ghigo@sphera:/tmp]$ g++ -Wall -o t t.c
t.c:6:	warning: return type for 'main' changed to 'int'
[ghigo@sphera:/tmp]$ ./t
a[0]=0x8049980; b=0x804998c
a[0]=0x8049980
[ghigo@sphera:/tmp]$ g++ -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
[ghigo@sphera:/tmp]$
In effeti non si capisce come venga "compilata" l'istruzione "a[0]=b;".
Secondo me dovrebbe essere segnalata come errore !!

Poi qualcuno si stupisce del fatto che Alex Martelli risponda a domande
su puntatori ed array suggerendo di usare STL...
Ciao,
Nicola

 Sto perdendo colpi, che ci vuoi fare ? ;)
Ma va. E' proprio per questi casini che il C++ offre come standard
metodi alternativi e molto più sicuri di gestire la memoria e le
strutture di dati.
EMG

su puntatori ed array suggerendo di usare STL...
Eh gia' ! ;)
Infatti bisogna sostituire tutto il vecchiume...

 matrici.
No, solo la seconda dichiara un array di puntatori. La prima dichiara un
puntatore ad array che č ben diverso. La differenza si nota, ad esempio,
nell'aritmetica che č la seguente:
1. int a[][10] o int (*a)[10]
   a++ significa che a punta ad una locazione che sta piů avanti di
sizeof( int [10] )
2. int *a[10]
   a++ significa che a punta ad una locazione che sta piů avanti di
sizeof( int * )
EMG

void main( ){       
int main()