Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

array, matrici e puntatori a puntatori

127 views
Skip to first unread message

Kap

unread,
Jul 9, 2008, 3:05:18 PM7/9/08
to
E' una domanda niubba.

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.


Alberto

unread,
Jul 9, 2008, 3:41:02 PM7/9/08
to

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 **.

Andrea Laforgia

unread,
Jul 9, 2008, 4:06:05 PM7/9/08
to
On Wed, 09 Jul 2008 21:05:18 +0200, Kap <aric81...@inwind.it>
wrote:

>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.

Andrea Laforgia

unread,
Jul 9, 2008, 4:07:21 PM7/9/08
to
On Wed, 9 Jul 2008 12:41:02 -0700 (PDT), Alberto <ats...@gmail.com>
wrote:

>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.

Kap

unread,
Jul 10, 2008, 2:09:24 AM7/10/08
to

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?


Andrea Laforgia

unread,
Jul 10, 2008, 5:42:24 AM7/10/08
to
Kap ha scritto:

> 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


Alberto

unread,
Jul 10, 2008, 6:10:45 AM7/10/08
to
On 9 Lug, 22:07, Andrea Laforgia
<a.lafor...@andrealaforgia.it.invalid> wrote:
> On Wed, 9 Jul 2008 12:41:02 -0700 (PDT), Alberto <atsg...@gmail.com>

> wrote:
>
> >Un puntatore a punatori di int e' la tua matrice.
>
> Niente affatto.

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

Andrea Laforgia

unread,
Jul 10, 2008, 6:25:17 AM7/10/08
to
Alberto ha scritto:

> > 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.

Cybertoldo

unread,
Jul 10, 2008, 7:22:04 AM7/10/08
to
Kap ha scritto:
> [...]

>
> quindi se creo dinamicamente n array di n*sizeof(int)
> con una malloc posso poi richiamare gli elementi
> con la sintassi della matrice?

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;
}

Alberto

unread,
Jul 10, 2008, 9:26:01 AM7/10/08
to
On 10 Lug, 12:25, x...@xx.xx (Andrea Laforgia) wrote:
> Alberto ha scritto:
>
> > > 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.

Virtualizzazione!

Andrea Laforgia

unread,
Jul 10, 2008, 9:41:47 AM7/10/08
to
Alberto ha scritto:

> Virtualizzazione!

Questo termine non aiuta a chiarire le idee. Quello che prevale dal tuo
messaggio è il verbo "essere".

Kap

unread,
Jul 10, 2008, 10:30:02 AM7/10/08
to
Andrea Laforgia wrote:
> Kap ha scritto:
>
>> quindi se creo dinamicamente n array di n*sizeof(int)
>> con una malloc posso poi richiamare gli elementi
>> con la sintassi della matrice?
[CUT]

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.

Andrea Laforgia

unread,
Jul 10, 2008, 10:30:51 AM7/10/08
to
Kap ha scritto:

> Posso richiamare il mio singolo char con nome.mat[0][0] ?

Sě.

softwareEngineer

unread,
Jul 10, 2008, 3:50:32 PM7/10/08
to
Un consiglio,
sarebbe opportuno studiare/leggere prima l'argomento e poi magari
postare i dubbi o gli esericzi non chiari :-)
solo come consiglio, nessuno si offenda.

by.


"Kap" <aric81...@inwind.it> ha scritto nel messaggio
news:48750bc3$0$40156$4faf...@reader1.news.tin.it...

0 new messages