Pagina 1 di 1
[C] Matrice ...
Inviato: gio 29 nov 2007, 20:15
da DaD
Non riesco a capire perchè questo codice mi restituisca un warring.
Il codice è questo;
Codice: Seleziona tutto
#include <stdio.h>
#include "matrix.h"
int main(void){
int a[2][3] = {{2, 3, 4},
{3, 4, 5}};
printf("L'elemento massimo è %d\n", max_matrice(a, 2, 3));
getchar();
return 0;
}
/* matrix.h */
int max_matrice(int **a, int n, int m){
int i, j, max = a[0][0];
for(i = 0; i <= n; i++){
for(j = 0; j <= m; j++){
if(a[i][j] > max)
max = a[i][j];
}
}
}
Il warring è questo;
Codice: Seleziona tutto
warning: passing argument 1 of 'max_matrice' from incompatible pointer type
In pratica da quello che ho capito sbaglio a passargli la matrice, ma non riesco a capire l'errore dove sia ...
Re: [C] Matrice ...
Inviato: gio 29 nov 2007, 20:23
da nicop
DaD ha scritto:Non riesco a capire perchè questo codice mi restituisca un warring.
Il codice è questo;
Codice: Seleziona tutto
#include <stdio.h>
#include "matrix.h"
int main(void){
int a[2][3] = {{2, 3, 4},
{3, 4, 5}};
printf("L'elemento massimo è %d\n", max_matrice(a, 2, 3));
getchar();
return 0;
}
/* matrix.h */
int max_matrice(int **a, int n, int m){
int i, j, max = a[0][0];
for(i = 0; i <= n; i++){
for(j = 0; j <= m; j++){
if(a[i][j] > max)
max = a[i][j];
}
}
}
Il warring è questo;
Codice: Seleziona tutto
warning: passing argument 1 of 'max_matrice' from incompatible pointer type
In pratica da quello che ho capito sbaglio a passargli la matrice, ma non riesco a capire l'errore dove sia ...
Dad non ne sono tanto sicuro,ma se non ricordo male usando questo dichiarazione
gli passi come parametro un puntatore ad un puntatore.Prova semplicemte a passare come parametro il puntatore,ovvero così
spero di non aver detto una cavolata...
ciaoo
Inviato: gio 29 nov 2007, 20:33
da gallows
In C non puoi convertire un T[][] in T**, se devi implementare una matrice ti consiglio una struttura opaca, che peraltro ti permette una facile gestione degli errori.
Inviato: gio 29 nov 2007, 20:46
da DaD
gallows ha scritto:In C non puoi convertire un T[][] in T**, se devi implementare una matrice ti consiglio una struttura opaca, che peraltro ti permette una facile gestione degli errori.
Scusa la mia ignoranza gallows ma cosa intendi per
"struttura opaca"?
Intendi dire di inzializzare la matrice in questo modo: a[n][m]?
nicop ha scritto:
Dad non ne sono tanto sicuro,ma se non ricordo male usando questo dichiarazione
gli passi come parametro un puntatore ad un puntatore.Prova semplicemte a passare come parametro il puntatore,ovvero così
spero di non aver detto una cavolata...
ciaoo
Nicop mi sai che hai ragione, infatti ripassando gli appunti ho visto che in pratica in quel modo posso gestire array di array, ma non degli array 2D classici.
Inviato: gio 29 nov 2007, 21:42
da absinthe
devi al minimo allocare dinamicamente la matrice se la vuoi usare così...
roba tipo:
Codice: Seleziona tutto
const int righe=2;
const int colonne=3;
int **a=NULL;
a = (int*) malloc(sizeof(int)*righe);
int r=0;
for (r=0; r<righe; r++)
a[r] = (int) malloc(sizeof(int)*colonne);
a sto punto però non mi ricordo se è più velocepassare l'indirizzo dell'array....
ad ogni modo potresti farti una struttura tipo:
Codice: Seleziona tutto
typedef _matrix {
int r; /*righe*/
int c; /*colonne*/
int **data; /*dati*/
//... altre cose utili
} matrix;
int max_matrice(matrix *prt_to_a_matrix_struct);
int max_matrice (matrix *my_ptr) {
int max =-1 /*scegli un init migliore...*/
int i, j;
for (i=0; i< my_ptr->r; i++)
for (j=0; j< my_ptr->c; j++)
if(my_ptr->data[i][j] > max)
max = my_ptr->data[i][j]
return max;
}
per inciso le librerie industriali implementano le matrici in un unica riga per velocizzare le operazioni di allocazione e calcolo...
M
PS: l'ho fatta a naso potrebbero esserci errori!
Inviato: gio 29 nov 2007, 22:13
da gallows
DaD ha scritto:gallows ha scritto:In C non puoi convertire un T[][] in T**, se devi implementare una matrice ti consiglio una struttura opaca, che peraltro ti permette una facile gestione degli errori.
Scusa la mia ignoranza gallows ma cosa intendi per
"struttura opaca"?
Intendi dire di inzializzare la matrice in questo modo: a[n][m]?
Intendo ad esempio un'implementazione come questa:
Codice: Seleziona tutto
typedef unsigned int uint;
typedef int mx_t;
typedef struct _Matrix Matrix;
struct _Matrix {
mx_t* data;
uint cols;
uint rows;
};
/* con una libreria come la seguente: */
/* (codice non testato) */
Matrix* matrix_init(uint rows, uint cols)
{
Matrix* mx = malloc( sizeof(Matrix) );
if ( rows && cols )
mx->data = malloc( rows * cols * sizeof(mx_t) );
else
mx->data = NULL;
mx->rows = rows;
mx->cols = cols;
return mx;
}
void matrix_destroy(Matrix* mx)
{
free( mx->data );
free( mx );
}
mx_t matrix_get_cell(const Matrix* mx, uint i, uint j)
{
if (i >= mx->rows || j >= mx->cols)
/* gestisci l'errore */
return mx->data[mx->cols * i + j];
}
int matrix_set_cell(Matrix* mx, uint i, uint j, mx_t v)
{
if (i >= mx->rows || j >= mx->cols)
return -1;
mx->data[mx->cols * i + j] = v;
return 0;
}
Un metodo ancora migliore sarebbe usare un void* invece dell'ingenuo mx_t, in modo da poter usare, con la stessa libreria, matrici di tipi diversi (ricorda che void* non si può dereferenziare, devi lavorare direttamente con la memoria).
Inviato: gio 29 nov 2007, 22:47
da DaD
Grazie delle delucidazioni, stavo leggendo proprio ora sul libro che per utilizzare in quel modo una matrice devo per forza di cosa allocare lo spazio in memoria dinamicamente per quest'ultima.
@gallows, vedo di studiarmi il tuo codice che mi sembra abbastanza completo, naturalmente stai parlando con un neofita del c eh

Re: [C] Matrice ...
Inviato: gio 29 nov 2007, 22:53
da corrado
DaD ha scritto:Non riesco a capire perchè questo codice mi restituisca un warring.
Il codice è questo;
Codice: Seleziona tutto
/* matrix.h */
int max_matrice(int **a, int n, int m){
int i, j, max = a[0][0];
for(i = 0; i <= n; i++){
for(j = 0; j <= m; j++){
if(a[i][j] > max)
max = a[i][j];
}
}
}
Una curiosità... ma nella scansione delle righe e delle colonne non dovresti mettere come condizione di uscita solo il "<" (minore)?
Saluti
corrado
Inviato: ven 30 nov 2007, 0:12
da lamarozzo
Sei vuoi passare un array bidimensionale ad una funzione basta fare
Codice: Seleziona tutto
//dichiarazione
void funzione (int *matrice[2]);
int main()
{
int a[3][2];
funzione(a);
}
Ricordati che nella lista di parametri devi sempre dichiarare la grandezza (in questo caso 2) dell'ultima dimensione dell'array.
Gli array multidimensionali sono la soluzione più comoda se ne conosci le dimensioni al tempo di compilazione. Altrimenti devi ricorrere all'allocazione dinamica. Se con la matrice in questione devi fare operazioni intensive (calcoli) devi fare in modo che occupi uno spazio contiguo in memoria.
Ad esempio seguendo il codice di Gallows. Soltanto che io eviterei di implementare le funzioni set e get per accedere alla matrice per non appesantire troppo il programma.
Gallows suggeriva di usare i void* per scrivere codice generico. Il problema di quella soluzione, a mio avviso, è la type safety. C'è un'altra soluzione: usare le macro del preprocessore. I fortunati utilizzatori del c++ hanno invece i potentissimi template.
A presto.
P.S. Corrado ha ragione
Inviato: ven 30 nov 2007, 1:41
da phobos3576
lamarozzo ha scritto:Sei vuoi passare un array bidimensionale ad una funzione basta fare
Codice: Seleziona tutto
//dichiarazione
void funzione (int *matrice[2]);
int main()
{
int a[3][2];
funzione(a);
}
Ricordati che nella lista di parametri devi sempre dichiarare la grandezza (in questo caso 2) dell'ultima dimensione dell'array.
Gli array multidimensionali sono la soluzione più comoda se ne conosci le dimensioni al tempo di compilazione. Altrimenti devi ricorrere all'allocazione dinamica. Se con la matrice in questione devi fare operazioni intensive (calcoli) devi fare in modo che occupi uno spazio contiguo in memoria.
Ad esempio seguendo il codice di Gallows. Soltanto che io eviterei di implementare le funzioni set e get per accedere alla matrice per non appesantire troppo il programma.
Gallows suggeriva di usare i void* per scrivere codice generico. Il problema di quella soluzione, a mio avviso, è la type safety. C'è un'altra soluzione: usare le macro del preprocessore. I fortunati utilizzatori del c++ hanno invece i potentissimi template.
A presto.
P.S. Corrado ha ragione
Lamarozzo ... attenzione alla sintassi ...
Sul passaggio di vettori bidimensionali come argomenti di funzioni hai ragione; un vettore bidimensionale in C è un "vettore di vettori".
Il nome di un vettore bidimensionale è quindi l'indirizzo del suo primo elemento, che è a sua volta un vettore; proprio per questo motivo il C deve conoscere la seconda dimensione del vettore (in sostanza, il C deve per forza conoscere la dimensione di ogni elemento del vettore).
Se io scrivo:
Codice: Seleziona tutto
int myvect[3][4] = {{1, 2, 3, 4}, {3, 2, 0, 1}, {5, 8, 1, 1}};
sto definendo un vettore di 3 elementi dove ogni elemento è un blocco da (4*sizeof(int)) byte.
E' sbagliata invece la sintassi::
(puntatore ad un puntatore ad int)
ed anche:
(vettore di ??? puntatori a int)
ed anche:
Infatti:
significa: "
vettore di 4 puntatori a int
La sintassi corretta è:
che significa: "
puntatore ad un vettore di int
Quindi il prototipo corretto per max_matrice è:
P.S. A parte questo, il codice scritto da DaD per calcolare il valore massimo mi sembra sbagliato; la versione giusta dovrebbe essere:
Codice: Seleziona tutto
/* matrix.h */
int max_matrice(int (*a)[3], int n, int m){
int i, j, max = a[0][0];
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
if(a[i][j] > max)
max = a[i][j];
}
}
return max;
}
Inviato: ven 30 nov 2007, 10:08
da lamarozzo
phobos3576 ha scritto:
Lamarozzo ... attenzione alla sintassi ...
Sì hai ragione, è questione di precedenza dell'operatore di accesso agli array su quello di deferenziazione. E' stata una svista causata dall'ora tarda e dal fatto che quando ho risposto stavo scrivendo uno script Python e non ero tarato sulle sottigliezze del C

Inviato: ven 30 nov 2007, 22:13
da DaD
phobos3576 ha scritto:P.S. A parte questo, il codice scritto da DaD per calcolare il valore massimo mi sembra sbagliato; la versione giusta dovrebbe essere:
Codice: Seleziona tutto
/* matrix.h */
int max_matrice(int (*a)[3], int n, int m){
int i, j, max = a[0][0];
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
if(a[i][j] > max)
max = a[i][j];
}
}
return max;
}
Si ma int m, a questo punto non serve visto che la matrice sarà sempre N X 3, giusto?
Inviato: sab 1 dic 2007, 0:05
da phobos3576
DaD ha scritto:Si ma int m, a questo punto non serve visto che la matrice sarà sempre N X 3, giusto?
Certo, visto che devi gestire un vettore dove ogni suo elemento è un altro vettore da 3 int.
Quindi, all'interno di
max_matrice puoi sostituire
m con il valore
3.
Se, invece, vuoi gestire matrici bidimensionali con numero variabile di righe e colonne, allora ti conviene ricorrere all'allocazione dinamica della memoria, come ti hanno già suggerito altri.