Newsgroup: it.comp.lang.c
Titolo: Passare una matrice n*n ad una funzione...

Ho dei problemi nel passaggio di una matrice bidimensionale ad una 
funzione. Il programma funziona così: l'utente immette un numero n in 
base al quale viene costruita una matrice di ordine n*n e 
successivamente viene passata ad una funzione. Quando dichiaro il 
prototipo di questa, sono costretto a specificare il secondo indice che 
non posso conoscere a priori perchè quello sarà il valore che inserirà 
l'utente.
Qualcuno di voi, ha già affrontato il problema? :-)
Luca

Luca ha scritto:

la butto li ...
hai provato a passare un puntatore e poi la dimensione n?
ciao

fabio z tessitore ha scritto:

E' quello che ho pensato...
------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
/* Prototipi di funzioni */
int aa(int **m);
int main(){
    int *s;
    int a[3][3] = { 0 };
    s = &a;
    aa(s);
}
int aa(int **m){
    printf("%d", *m[0][0]);
}
------------------------------------------------------------------------
Quando compilo il compilatore mi da questo errore:
error: invalid type argument of 'unary *'


possono esserci vari modi. potresti postare il prototipo 
della funzione e il codice che alloca la matrice?
grazie, ciao.

cane ha scritto:

L'ho già fatto :-)
Grazie a te

 L'ho già fatto :-)
dunque, a questo punto non so se ho capito bene il problema 
anche perché il codice che hai riportato non mi sembra che 
faccia quello che hai descritto (anzi mi pare che non 
funzioni proprio).
se mi attengo alla tua descrizione, tu vorresti passare una 
matrice quadrata n x n (con n immesso dall'utente) ad una 
funzione. il modo più semplice per farlo è usare una matrice 
"flat" (ovvero un array di n x n elementi) ed usare un 
indicizzamento "indiretto" per prendere gli elementi.
--------------------
#include <stdio.h>
#include <stdlib.h>
void f(int *m, int n) {
    int i,j;
    for (i=0;i<n;i++) {
       for(j=0;j<n;j++)
          printf("%08X  ",m[i*n+j]);
       printf("\n");
    }
}
int main() {
    int *m;
    int n;
    scanf("%d",&n);
    m=(int*)malloc(sizeof(int)*n*n);
    f(m,n);
    free(m);
    return 0;
}
--------------------
avvertenza: il codice sopra stampa i valori che sono già 
nell'area di memoria puntata da m.
naturalmente questo approccio (matrice flat) potrebbe anche 
essere inadeguato per quello che hai intenzione di fare in 
seguito.
spero di aver capito il problema, altrimenti chiarisci un po' :)
ciao.

cane ha scritto:

Ho notato che nel codice hai utilizzato un vettore unidimensionale 
facendolo sembrare bidimensionale attraverso l'uso del cicli for 
nidificati. Il problema è ok!
Il mio problema era quello di passare alla funzione f una matrice 
bidimensionale e non un vettore unidimensionale :-)
Il modo con cui hai risolto il problema non è male; ho apprezzato molto 
la matrice flat che fai apparire come se fosse un vettore bidimensionale 
(se non ho capito male)...
Grazie, Luca

 bidimensionale e non un vettore unidimensionale :-)
se la matrice viene allocata dinamicamente (array di 
puntatori) puoi farlo con un puntatore a puntatore. esempio:
--------------------
#include <stdio.h>
#include <stdlib.h>
void f(int **m, int n) {
    int i,j;
    for (i=0;i<n;i++) {
       for(j=0;j<n;j++)
          printf("%08X  ",m[i][j]);
       printf("\n");
    }
}
int main() {
    int **m;
    int i,n;
    scanf("%d",&n);
    m=(int**)malloc(sizeof(int*)*n);
    for (i=0;i<n;i++)
       m[i]=(int*)malloc(sizeof(int)*n);
    f(m,n);
    for (i=0;i<n;i++)
       free(m[i]);
    free(m);
    return 0;
}
--------------------
ciao.

cane ha scritto:

Ok!
int **m è un puntatore ad un puntatore... quindi quando usi 
malloc(sizeof(int)*n); dichiari un vettore di puntatori che poi 
conterranno il riferimento ai vettori allocati successivamente: 
m[i]=(int*)malloc(sizeof(int)*n);
ciao, Luca

>       m[i]=(int*)malloc(sizeof(int)*n);
Via il cast dal valore di ritorno di malloc()

Andrea Laforgia ha scritto:

La funzione malloc restituisce un puntatore void che nel nostro caso 
punta ad un intero e quindi concorda con il tipo di dato puntato da m 
che è: int *m;
Effettivamente è una cosa superflua...
Luca

 Effettivamente è una cosa superflua...
Il cast del valore di ritorno di malloc() infatti è da evitare, in 
C.  Il passaggio da void* a qualsiasi altro tipo puntatore 
specializzato è automatico.

Andrea Laforgia ha scritto:

Un puntatore generico può essere assegnato ad un qualsiasi puntatore 
rispettando sempre il tipo.
Se il puntatore generico punta ad un char e noi lo assegnamo ad un int, 
allora, serve il cast.

 allora, serve il cast.
Il puntatore generico è generico e basta, non punta ad un char. 
Se punta a char, non è un puntatore generico, ma è un puntatore a 
char.  Il cast, su un puntatore generico, non serve.

Andrea Laforgia ha scritto:

Ok :-)

<snip>
Ma questo non mette a zero solo a[0][0] ?
int a[3][3] = { 0,0,0,0,0,0,0,0,0 }
mi sembra piu' corretto.
-- 
Andrea Rimicci
Deltasys S.r.l.
Email andrea(d0t)rimicci(at)deltasys(d0t)it

Ma questo non mette a zero solo a[0][0] ?
No.

Andrea Laforgia ha scritto:

Cosa fa? A me sembra sbagliato.
-- 
Devaraja (Xdevaraja87^gmail^c0mX)
Linux Registerd User #338167
http://counter.li.org

Cosa fa? A me sembra sbagliato.
Non lo č; inizializza a zero tutti gli elementi.



Da quello che so, il C inizializza a zero solo le variabili extern e
quelle static.
Se sono auto o registry, il valore e' indefinito.
Magari quello che dici e' vero per il C++, ma di C++ non ne so molto e
non posso pronunciarmi.
Andrea


Se sono auto o registry, il valore e' indefinito.
quasi errata corrige.
Tralasciavo il fatto che se in un array metti meno inizializzatori, il
resto viene messo a zero...


 quelle static.
Stiamo parlando di una cosa diversa (che vale sia in C che in 
C++).  Se scrivi:
int a[10] = {0};
_Tutti_ gli elementi dell'array vengono inizializzati a zero.