Da quel che so, vettori e matrici in realtà
sono la stessa cosa, nel senso che la matrice
come seconda quadra accetta un intero,
che è in pratica quello che lo fa andare
a capo ogni riga dell'array in cui è memorizzato
giusto?
Se dichiaro int mat[5][] lui sa che ogni
5*sizeof(int) deve "scendere alla riga"
successiva? Cioè puntare a quel valore
con il puntatore nascosto di mat?
E se invece creo dinamicamente un puntatore
a puntatori a int? come si comporta?
Grazie a tutti.
Ciao.
Un puntatore a punatori di int e' la tua matrice. Il fatto di andare a
capo e' solo una virtualizzazione. Una matrice di interi e' appunto un
int **.
>Da quel che so, vettori e matrici in realtà
>sono la stessa cosa,
In C esistono gli array. Ed esistono, legittimamente, array di array,
array di array di array, e così via...
>Se dichiaro int mat[5][] lui sa che ogni
>5*sizeof(int) deve "scendere alla riga"
>successiva?
Quella dichiarazione non è legale. Forse intendevi scrivere:
int mat[][5]
E comunque è valida solo come argomento di funzione o accompagnata da
un'inizializzazione. Se vuoi vedere com'è fatto l'array in memoria,
basta stamparlo:
#include <stdio.h>
#define N 5
int main()
{
int mat[][N] = {{10,20,30,40,50},
{60,70,80,90,94},
{95,96,97,98,99}};
size_t matcnt = sizeof mat / sizeof mat[0][0];
size_t i;
for (i=0; i<matcnt; i++) {
if (i%N == 0) printf("\nmat[%d] = ", i/N);
printf("%3d [%3d] ", mat[i/N][i%N], i);
}
return 0;
}
>Cioè puntare a quel valore
>con il puntatore nascosto di mat?
Stai attento a parlare di puntatori quando ci sono di mezzo gli array.
Array e puntatori *non* sono la stessa cosa. In un array non c'è
nessun puntatore nascosto ma si dice che un array "decade" in
puntatore al primo elemento in circostanze specifiche.
>E se invece creo dinamicamente un puntatore
>a puntatori a int? come si comporta?
che allocherai presumibilmente un array di puntatori, ognuno dei quali
punterà a zone specifiche contenenti gli elementi, in maniera
contigua. In sostanza, la struttura in memoria sarà più sparsa che nel
caso degli array. Guai a confondere array di array con array di
puntatori.
>Un puntatore a punatori di int e' la tua matrice.
Niente affatto.
>Una matrice di interi e' appunto un int **.
Per nulla. Questo era proprio il pericolo che scongiuravo e cioè che
qualcuno dicesse (è successo tante volte) che array e puntatori si
equivalgono. Non è così. Una matrice (intesa come array di array) è un
conto; un puntatore a puntatori è *TUTT'ALTRA* storia.
quindi se creo dinamicamente n array di n*sizeof(int)
con una malloc posso poi richiamare gli elementi
con la sintassi della matrice?
E nel caso di un array di n puntatori a n*sizeof(int)
array non posso quindi, li dovrò richiamare con
(*riga[0])[0] per sempio? esiste un sintassi simile?
> quindi se creo dinamicamente n array di n*sizeof(int)
> con una malloc posso poi richiamare gli elementi
> con la sintassi della matrice?
Sì. La notazione con parentesi quadre si applica sia ad array che a
puntatori, per comodità.
> E nel caso di un array di n puntatori a n*sizeof(int)
> array
Stai complicando troppo le cose. Per allocare dinamicamente una matrice
(ma sarebbe corretto dire: una struttura dati indirizzabile come una
matrice, perché di fatto non allocheresti un monolite) devi scrivere
qualcosa del tipo:
int **p;
/* allochi sequenzialmente 5 puntatori a intero */
p = malloc(5 * sizeof(int*));
for (i=0; i<5; i++)
p[i] = malloc(3 * sizeof(int));
e poi puoi accedere tranquillamente a p[0][2], per esempio.
Quello che fai con la prima malloc() è di costruire una sequenza di
puntatori. Supponendo che un puntatore occupi 4 byte e che un int occupi 2
byte:
p[0]: | indirizzo 0 |
p[1]: | indirizzo di p[0] + sizeof(int*) = 0 + 4 = 4 |
p[2]: | indirizzo di p[1] + 4 = 8 |
p[3]: | indirizzo 8 + 4 = 12 |
p[4]: | 16 |
Con il ciclo, invece, fai in modo di allocare memoria per ciascun
puntatore:
p[0]: | indirizzo 0 | --> |indirizzo 100 |
|indirizzo 100 + sizeof(int) = 100 + 2 = 102 |
|indirizzo 102 + sizeof(int) = 102 + 2 = 104 |
p[1]: | indirizzo 4 | --> |indirizzo 200 |
|indirizzo 200 + sizeof(int) = 200 + 2 = 202 |
|indirizzo 202 + sizeof(int) = 202 + 2 = 204 |
p[2]: | indirizzo 8 | --> |indirizzo 310 |
|indirizzo 312 |
|indirizzo 314 |
p[3]: | indirizzo 12 | --> |indirizzo 900 |
|indirizzo 902 |
|indirizzo 904 |
p[4]: | indirizzo 16 | --> |indirizzo 250 |
|indirizzo 252 |
|indirizzo 254 |
I valori 100, 200, 310, 900, 250 li ho scelti a caso, ovviamente, perché
l'allocazione su heap non deve necessariamente seguire sequenze specifiche.
Come vedi, con un'allocazione dinamica non riservi un unico blocco
contiguo (come è di fatto una matrice), ma allochi memoria sparsa nel
sistema (gli indirizzi 100, 200, 310, 900, 250 sono "distanti" tra loro ed
anche da quegli 0, 4, 8, 12, 16), a cui puoi accedere utilizzando la
stessa notazione di matrice in tempo comunque O(1). Devi per questo stare
molto attento a non confondere array di array e array di puntatori.
--
questo articolo e` stato inviato via web dal servizio gratuito
http://www.newsland.it/news segnala gli abusi ad ab...@newsland.it
Con int ** puoi creare una matrice.
>
> >Una matrice di interi e' appunto un int **.
>
> Per nulla. Questo era proprio il pericolo che scongiuravo e cioè che
> qualcuno dicesse (è successo tante volte) che array e puntatori si
> equivalgono. Non è così. Una matrice (intesa come array di array) è un
> conto; un puntatore a puntatori è *TUTT'ALTRA* storia.
Mai scritto che array a e ptr si equivalgono
> > Niente affatto.
> Con int ** puoi creare una matrice.
No, con int** crei una struttura dati accessibile alla stregua di una
matrice. NON stai creando una matrice. Una matrice è un blocco monolitico.
Con un doppio puntatore, invece, non hai un blocco monolitico. Non
confondere la notazione con la disposizione in memoria.
> Mai scritto che array a e ptr si equivalgono
Lo implichi quando scrivi "una matrice di interi e' appunto un int **".
E' sbagliato. Una matrice di interi è, appunto, una matrice, cioè un array
di array in C.
tu intendevi fare qualcosa del genere?
~~~~~~~
#include <stdio.h>
#include <stdlib.h>
#define COLONNE 20
int main(void)
{
int y, x;
int nRighe = 10;
int (*pA)[COLONNE]; /* in C99, invece della '#define COLONNE',
puoi qui usare una semplice variabile */
pA = calloc(nRighe, sizeof(pA[0])); /* sizeof(pA[0]) == COLONNE
* sizeof(int) */
if(!pA)
return EXIT_FAILURE;
/* assegnazione valori in matrice */
pA[1][1] = 11;
pA[2][2] = 22;
pA[3][3] = 33;
pA[4][4] = 44;
/* stampa matrice */
for(y = 0; y < nRighe; y++)
{ for(x = 0; x < COLONNE; x++)
printf("%2d ", pA[y][x]);
printf("\n");
}
free(pA);
return EXIT_SUCCESS;
}
Virtualizzazione!
> Virtualizzazione!
Questo termine non aiuta a chiarire le idee. Quello che prevale dal tuo
messaggio è il verbo "essere".
Quindi a livello di codice la sintassi va bene
in ogni caso giusto?
Perchè poi il mio problema si complica (problema
sintattico puro), se invece di int si parlasse
di strutture.
Quindi un campo della struttura è un puntatore
che punta ad un array di puntatori a char per
esempio, creandomi una matrice di char a questo
punto.
Posso richiamare il mio singolo char con nome.mat[0][0] ?
Perchè il campo della struttura sarebbe dichiarato
come **nome.mat, come nel tuo esempio.
> Posso richiamare il mio singolo char con nome.mat[0][0] ?
Sě.
by.
"Kap" <aric81...@inwind.it> ha scritto nel messaggio
news:48750bc3$0$40156$4faf...@reader1.news.tin.it...