Newsgroup: it.comp.lang.c
Titolo: passaggio di vettori a più dimensioni.

ciao, qualcuno mi sa dire perché il seguente codice non compila?
/* inizio */
#include <stdio.h>
void funz(int*);
int main(void)
{
	int a[3][2];
	funz(a);
	return 0;
}
void funz(int a[])
{
	scanf("%d", &a[0][0]);
}
/* fine*/
grazie per l'attenzione.

 ciao, qualcuno mi sa dire perché il seguente codice non compila?
che errore ti da?
ke ambiente di lavoro usi?
ciao!

}
Tu puoi fare 2 cose:
- passargli il puntatore al primo elemento oppure
- passargli "l'array bidimensionale" (che decade al puntatore al primo
elemento), ma devi indicargli tutte le dimensioni coinvolte meno la
prima che e' opzionale:
funz(a[][2]);
Sarebbe comunque indicato passare come parametro a parte le dimensioni
della matrice.
void funz(int a[][2], int dim1, int dim2);
oppure
void funz (int **a, int dim1, int dim2);
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 }
provo ad aiutarti anche se di sicuro c'è chi potrebbe farlo meglio!
ho provato a dare in pasto il tuo codice al compilatore e mi da errore! uso
VC++ 6 :( e in totale mi da 3 errori:
il primo è che funz(a) non può convertire parametri da 'int [3][2]' a 'int
*' . Ho provato a sostituire funz(a) con funz(&a[0][0]) e il problema non
c'era +!il secondo errore era causato da:
scanf("%d", &a[0][0])
ossia: tu hai dichiarato un array:
void funz(int a[])
e poi gli hai chiesto di eseguire un input da tastiera in una matrice non
dichiarata!
per risolvere devi cambiare in:
void funz(int a[][])
mi da ancora un errore ma non so che pesci prendere!
spero di esserti stato utile!
sciaooo


mi da ancora un errore ma non so che pesci prendere!
Forse perche' e:
void funz(int a[][2]);
void funz(int a[3][2]);
Rif. Pag 142 del K&R versione italiana.


 Rif. Pag 142 del K&R versione italiana.
i don't have! :((((((((((((((
the money...

 void funz (int **a, int dim1, int dim2);
why int **a ?

"gabri__" <a...@me.com.invalid> ha scritto nel messaggio
news:3cm5cukhvj8jn9kql...@4ax.com...

--------------------------------------------------
    /* inizio */
#include <stdio.h>
void funz(int a[][]);
int main(void)
{
char carattere;
int a[3][2];
funz(a);
scanf("\n%c",&carattere);
return 0;
}
void funz(int a[][2]) /*la seconda dimensione e' obbligatoria passarla*/
{
scanf("%d", &a[0][0]);
printf("\n%d",a[0][0]);
}
/* fine*/
--
Iscriviti al gruppo yahoo Linguaggio_C  con chat vocale per i soli iscritti
http://it.groups.yahoo.com/group/Linguaggio_C

why int **a ?
Per definizione:
int[] == int *
int[][] == int **
E cosi' via.
Se hai:
int a[N][M];
E cerchi di accedere all'elemento <i, j>, con i<N e j<M ovviamente, tu
hai vari modi equivalenti dovuti al fatto che il rapporto tra
puntatori e vettori e' molto stretto:
a[i][j]
*(*(a+i)+j)
Ora potresti anche mischiare le 2 sintassi (ci ho pensato e mi sembra
giusto, speriamo):
*(a[i]+j)
(*(a+i))[j]
Questo perche' difatto la sintassi puntatore[indice] si traduce in
*(puntatore+indice).


 *(puntatore+indice).
ossia: segmento+offsett?
concludendo: ho detto qlche boiata???

in una matrice ci sono 2 indirizzi di memoria
La definizione esatta e' che una matrice e' un array bidimensionale,
ovvero un array di array. Quindi hai un array di puntatori e poi per
ogni puntatore un'altro array e cosi' via :)


On Sun, 21 Apr 2002 17:31:38 +0200, gabri__ <a...@me.com.invalid>
wrote:
[cut]
ringrazio tutti x le risposte: siete stati molto chiari.
però mi chiedo: poiché bisogna passare per forza i numeri delle
colonne della matrice, come si fa a fare una funzione che prende una
generica matrice e, per esempio, ne fa la trasposta? c'è un qualche
trucco?
ciao
-- 
g.

 ogni puntatore un'altro array e cosi' via :)
esatto! ce lo dice anche il nostro prof!
ma una cosa: un array è (a grandi linee) un puntatore in cui fissiamo dell
dimensioni giusto?
ora, quando io dichiaro un puntatore:
char *str
ho un puntatore che ha un inizio ma non una fine giusto?
non è sbagliato, ovvero, così facendo non rischio di andare a sovrascrivere
delle parti di memoria che sto usando?
ad es:
...
*(str+10000) = 'e';
...
non è rischioso?
ps:
le altre cose che ho detto nel post sono giuste?

gabri__ <a...@me.com.invalid>:

Leggi il mio post: puoi solo passare solo un int ** come primo
parametro e poi le due dimensioni come parametri a parte.
Dopo di che nella funzione puoi usare tranquillamente la sintassi per
le matrici:
matrice[i][j]


void funz (int **a, int dim1, int dim2);
se ho ben capito, questo secondo prototipo è meglio, perché non deve
essere noto a priori il numero di colonne della matrice.
tuttavia mi da un warning, e durante l'esecuzione crasha:
/* inizio */
#include <stdio.h>
void funz(int**);
int main(void)
{
	int a[3][2];
	funz(a);
	return 0;
}
void funz(int **a)
{
	scanf("%d", &a[0][0]);
}
/* fine*/
dove ho sbagliato??
-- 
g.

parametro e poi le due dimensioni come parametri a parte.
non mi funziona :\

non č rischioso?
Si, e' rischioso, ma un controllo del negenere sarebbe molto difficile
e comunque molto costoso: il C ti lascia fare, si spera che tu non ti
tagli (leggi: che scrivi solo dove puoi o cumunque ti allochi
abbastanza memoria per farlo).


 abbastanza memoria per farlo).
ultima frase? non capisco proprio il significato!

ultima frase? non capisco proprio il significato!
è questa la frase di Mox che non hai capito?
scrivi dove puoi = conosci le locazioni di memoria in cui
scrivi (ie. sai che li c'è una variabile di cui conosci la
dimensione ecc...)
ti allochi... = malloc() :)
--
Lawrence Oluyede
rhy...@myself.com

 dimensione ecc...)
esatto! quindi non è una "contraddizione" che il C mi metta a disposizione
dei mezzi che vanno contro i suoi "principii"??
se l'unico modo per ottenere strutture dati dinamiche sono liste,alberi... e
poi posso usare delle stringhe"dinamiche"...
mah...
sarò un principiante!

poi posso usare delle stringhe"dinamiche"...
non ho capito...
--
Lawrence Oluyede
rhy...@myself.com

 non ho capito...
ti racconto una storia: una volta chiesi al mio prof: "prof ma se a me serve
un array senza un limite, cioè con limite ma settabile dall'utente, come
faccio?" e lui disse "questo argomento sono le liste"
da quel giorno capii che per ottenere una struttura dati dinamica dovevo
imparare le liste!!!
nel frattempo scoprii che char *stringa è una stringa senza fine(macchina
permettendo;) )!
quindi, ci sono rimasto male...
quindi volevo avere qualche parere a riguardo.
it's all!
ciauzzz

non mi funziona :\
Allora, pare che, sebbene tu possa accedere agli elementi della
matrice anche considerandola un puntatore a puntatore, ci sia un
problema quando voglio passare una matrice a una funzione e non ne
conosca (o non si voglia specificare) la dimensione.
Puoi fare tre cose a quanto ho capito
1) rassegnarti e indicare espressamente le dimensioni richieste
2) allocare il vettore dinamicamente
3) leggere le FAQ a questi link, vedere se ti orienti e provare ad
applicarne uno.
1) [RASSEGNAZIONE]
Beh, mi pare non ci sia nulla da dire, devi indicare tutte le
dimensioni del vettore, tranne la prima che e' opzionale.
2) [AGGIRARE L'OSTACOLO]
Prima di tutto un modo per risolvere il tutto aggirando l'ostacolo.
prima dichiari:
int **a;
E poi lo inizializzi cosi':
a = malloc(2 * sizeof(int*));
a[0] = malloc (2 * sizeof(int));
a[1] = malloc (2 * sizeof(int));
Hai allocato dinamicamente una matrice di interi di 2x2 (per matrici
piu' grandi si usa un for, comuque per spiegarmi va benissimo una 2x2
senza usare cicli).
Ora dichiariamo:
void f1(int **a);
void f2(int *a[]);
In entrambi i casi funziona perfettamente.
NON funziona se dichiaro (vedi il punto 3)
void f3(int a[][2]);
3) [USARE LA MATRICE COME SE FOSSE UN ARRAY]
Dopo che ti ho risposto mi e' venuto in mente di guardare la FAQ e mi
sono accorto di una cosa... non e' un problema cosi' facile :P
http://www.eskimo.com/~scs/C-faq/q6.18.html
http://www.eskimo.com/~scs/C-faq/q6.19.html
http://www.eskimo.com/~scs/C-faq/q6.20.html
(e tutti i link da questi agli altri punti delle FAQ)
Quarda le varie soluzioni adottate e i limiti di queste e vedi quale
metodo ti torna piu' comoda.
Scusa ancora per il disguido, ma non ci ho proprio pensato prima a
questo inconveniente. Per tua sfortuna nessuno piu' esperto ha potuto
postare prima di me :)


quindi volevo avere qualche parere a riguardo.
leggi la documentazione sulle funzioni malloc(), calloc() e
realloc()
--
Lawrence Oluyede
rhy...@myself.com

quindi volevo avere qualche parere a riguardo.
Primo errore, la stringa e' limitata dalla memoria che io gli assegno,
non e' senza fine e non dipende solo dalla capacita' della macchina.
Devo aver prima allocato lo spazio necessario, o staticamente o
dinamicamente.
Che tu usi una lista, un array o una lista di array o cosa preferisci
devi sempre prima allocare lo spazio, staticamente o dinamicamente.



rhy...@myself.com
Ciao, Pietro.
--
ICQ: 113394011, Il FeSToso: 88
I will build myself a copper tower
With four ways out and no way in
But mine the glory, mine the power
(So I bought an Amiga)


grazie per la difesa ;)

 void funz (int **a, int dim1, int dim2);
Attento Mox, non sono la stessa cosa, lo sarebbero se io avessi una funzione
del tipo:
void funz(int* array[]);
che è equivalente a
void funz(int** array);
Nel caso in questione la funzione dovrebbe avere un prototipo simile a:
void funz(int (*a)[2]);
Inoltre, se valutiamo la decadenza di un vettore, abbiamo:
int [n] = int*
int [n][m] = int(*)[m]
int [n][m][h] =int(*) [m][h]
int*[n] =  int**
int**[n] = int***
Ciao.

 void funz(int a[3][2]);
Questa è giusta in quanto entrambe le dichiarazioni vengono sostituite dal
compilatore come
void funz(int(*a)[2]);
Ciao.

Chiedo scusa pubblicamente a Mox per averlo corretto quando l'aveva già
fatto da solo indicando i link ai post consoni all'argomento.
Purtroppo ho postato prima di leggere tutto il thread.
Ciao.

Purtroppo ho postato prima di leggere tutto il thread.
Nope :)
Tra l'altro il post sulla decadenza corretta da vettore a puntatore mi
interessava.
