Newsgroup: it.comp.os.linux.development
Titolo: dichiarazioni in C

come si definisce (e come si usa) un puntatore ad una tabella?
int x[10];
int (*y)[10];
questi non sono entrambi puntatori ad una tabella di interi?
cosa cambia tra le due dichiarazioni?
perche' non posso fare y = x?

> come si definisce (e come si usa) un puntatore ad una tabella?
non si puo' definire, le tabelle in C non esistono.
puoi provare con openoffice o l'html

 
ok, ma se voglio un puntatore a una tabella di 10 elementi dovrei poter 
fare anche cosi':
int (*y)[10];
y = (int (*)[10]) malloc (sizeof(int) * 10);
printf("%d\n", ((*y)[0] = 123);
e in effetti funziona
pero', pur essendo apparentemente la stessa cosa che hai scritto tu... 
non posso accedere alla variabile y con un semplice y[1] = 234
eppure cosa cambia?
non e' anche in questo caso y un puntatore ad una tabella di int?
non so se mi sopiego... mi pare ci sia un leggera incongruenza... tutto qui
ciao


http://www.youtube.com/watch?v=xwLeHQeI5iw

 
se a qualcuno interessava, ho capito l'inghippo
quando si usano le parentesi quadre, C sottintende un puntatore
int y[10]  rende y un puntatore al primo intero della tabella
int (*y)[10]  non e' quindi un puntatore come sopra, ma un doppio 
puntatore al primo intero della tabella
infatti, mentre nel primo modo si puo' fare *y = 123
nel secondo bisogna fare **y = 123


Vedo in questa domanda e nei successivi sviluppi una certa confusione. Ti 
suggerisco di leggere le FAQs:
http://c-faq.com/
Non so se esistono in Italiano, ma l'Inglese delle FAQs e` comprensibilissimo. 
Leggendole, sono sicuro che ti chiarirai le idee ed eviterai di fare molti 
errori che tanti (me incluso) hanno fatto proprio per non averle lette. Ogni 
tanto mi diverto a ripassarle e, credimi, ogni volta scopro qualcosa di nuovo.
Ciao,
-- 
        Roberto Divia`              Love at first sight is one of the greatest
Dep:PH Bat:53 Mailbox:C02110      labour-saving devices the world has ever seen
Route de Meyrin 385               ---------------------------------------------
Case Postale                                Phone:  
+41-22-767-4994
CH-1211 Geneve 23 CERN                      Fax:    
+41-22-767-9585
Switzerland                                 E-Mail: 
Robert...@cern.ch

e quindi, se non ho capito male (ma non mi sembra)
int a[10][10]
rende "a" un puntatore al primo elemento di una tabella di 10 puntatori, 
ognuno dei quali punta al primo elemento di una tabella di 10 int.
infatti se faccio
**a = 123;
*(*(a+1)+1) = 234;
printf("%d - %d\n", a[0][0], a[1][1]);
printf me li stampa giusti.
ad occhio mi pare di aver capito giusto...

 
per la verita' non mi sembra... sto leggendo K&R e mi sembra un libro 
abbastanza illuminante (pure troppo...)
mi ero fermato un po' sulla sezione dove c'e' un software che descrive 
in parole una dichiarazione... non so se hai presente
e gira gira... mi son trovato un po' di dubbi, che pero' credo di aver 
risolto
ho scritto quella che per me era la soluzione alla faccenda un paio di 
post piu' in su...
a me pare di aver capito giusto... ma mai dire mai.

 ad occhio mi pare di aver capito giusto...
Esattamente.
In C non esistono le matrici solo gli array, e per giunta non terminati.
Nulla ti vieta di scrivere:
a[12] = 0;
a[300][200] = 100;
In entrambi i casi il meglio che ti puo' capitare e' un crash (il peggio 
e' settare un elemento che non vorresti e avere un nightmare in fase di 
debug)


Sbagliato
int * a[10] con successiva mallocazione di ognuno dei dieci elementi
fa quello che dici tu.
dichiarare int a[10][10] fa sì che a punti ad una area di memoria
_contigua_ di dimensione almeno 10*10*sizeof(int)
Occhio al gergo. Dire che "int a[10][10] rende 'a' un puntatore.." non
mi sembra corretto
Lo sarebbe di piu dire che 'a' decade a &a[0][0] in fase di
compilazione.
Ciao
Giacomo

 
poi le finezze sul gergo me le imparero' con calma
ma la sostanza mi pare sia quella che ho detto prima
vedi un po' se ti convince...

 
come lo dici tu non e' proprio vero
int a[10];
a[10][10] = 123;  // non compila.. esce con errore
semmai, al limite, si potrebbe costringere la compilazione scrivendo:
((int **)a)[10][10]) = 123;
ma questo non fa che confermare quello che ho detto prima
e cioe' che una tabella a due dimensioni e' in realta' un doppio puntatore.

comunque, tanto per dire che i due modi di scrivere fanno riferimento 
allo stesso indirizzo in memoria, ho scritto pure i valori dei due indirizzi
------------------------------
#include <stdio.h>
#include <stdlib.h>
int main() {
   int a[10][10];
   int *b[10];
   int i;
   for(i = 0; i < 10; ++i) b[i] = (int *) malloc(sizeof(int) * 10);
   a[0][0] = 123;
   b[1][1] = 234;
   printf("%d - %d\n", a[0][0], b[1][1]);    // output  123 - 234
   printf("%d - %d\n", **a, *(*(b+1)+1));    // output  123 - 234
   printf("\n");
   printf("%d - %d\n", &b[1][1], *(b+1)+1 ); // due indirizzi uguali
   return 0;
}
------------------------------
secondo me non c'e' storia proprio.
una tabella a due dimensioni e' in realta' un puntatore ad una tabella 
di puntatori
o almeno tutto sembra far credere che sia cosi'.

 puntatore.
no. un'array multidimensionale e' solo un'area di memoria contigua di X per
Y per Z per (e via con le dimensioni) con base l'indirizzo rappresentato
dal nome dell'array. poi con i puntatori puoi fare tutti i giochi che vuoi
e magari non ti da errore *in compilazione*, ma cio' non vuol dire che
avvenga quello che credi.
ilSimo
-- 
now playing: 
This is the tale of ELRIC 
before he was called womanslayer 
before the final collapse of MELNIBONE 
this is the tale of the two 
Black Swords 
                                Domine - The Chronichles Of The Black Sword


Un array e` un array, un pointer e` un pointer, cfr comp.lang.c FAQ 6.3 e 6.8:
http://c-faq.com/aryptr/aryptrequiv.html
http://c-faq.com/aryptr/practdiff.html
Arrays e pointers sono *equivalenti* ma non sono la stessa cosa. Un array 
bi-dimensionale non e` un array di puntatori. E` un'entita` *equivalente* ad un 
puntatore ad una regione contigua di memoria, cfr comp.lang.c FAQ 6.8:
http://c-faq.com/aryptr/practdiff.html
Un puntatore singolo con cui il compilatore puo` fare l'aritmetica per trovare 
la giusta referenza. Un "doppio" puntatore in C non esiste. Vedi come esempio 
(ma non come risposta esaustiva) comp.lang.c FAQ 6.18:
http://c-faq.com/aryptr/pass2dary.html
Attenzione: questa discussione sta mescolando le carte in tavola e si comincia a 
fare confusione tra la sintassi C e la rappresentazione degli oggetti in memoria.


 di puntatori
Ti dico di no. E il tuo codice non mi sembri provi nulla visto che il
test sugli indirizzi lo fai su "b" che (siamo daccordo) è un array di
puntatori
Prova questo:
{
    int a[10][10];
    int *b[10];
    int i;
    for(i = 0; i < 10; i++)
        b[i] = malloc(sizeof(int)*10);
    printf("%08x %08x\n", &a[1], a[1], &a[1][0] );
    printf("%08x %08x %08x\n", &b[1], b[1], &b[1][0] );
}
Qui otterrai due linee. La prima ti dice che l'indirizzo di a[1] è
esattamente quello di a[1][0].
Inoltre noti come scrivere a[1] è uguale a scrivere &a[1][0], perché
in fase di compilazione, come ti ho detto, avviene questa
trasformazione.
'a' te la devi immaginare su una area di memoria contigua (è nello
stack come già detto). e, per esempio, la cella successiva a a[0][9] è
proprio a[1][0]..  In linea teorica puoi comunque accederci con a[0]
[10], anche se non sono sicuro che questo sia standard (ad esempio il
compilatore potrebbe paddare per ottenere un allineamento in memoria..
e bla blabla)
La seconda linea ti dice invece che b è sì, un array di puntatori.
Infatti l'indirizzo di b[1], non è uguale all'indirizzo di b[1][0], ma
b[1] rappresenta un'area di memoria che è nello stack, non è
mallocata, ed è di dimensione sizeof(int*). In questa area di memoria
(nello stack) è presente l'indirizzo di b[1][0]... b[1] è quindi un
__puntatore__ ad un array di interi, mallocato.
Sicuramente con un disegno avresti le idee molto piu chiare.
Spero di essermi spiegato
Ciao
M`

 }
l'esempio leva ogni dubbio
l'indirizzo di a[0][0] e' lo stesso di a[0]
mentre l'indirizzo di b[0][0] non e' lo stesso di b[0]
pero' son lo stesso ben lontano da aver capito il meccanismo.
tanto per dire
int a[10];
int *p;
p = a;   // ok
int b[10][10];
p = b;   // errore;
int **pp;
pp = b;  // errore
mi sfugge la logica... ma piano piano ci arrivero'.
grazie per l'imbeccata
ciao

 
e tra l'altro, la discussione mi sembra OT su questo gruppo, sarebbe 
meglio spostarla su it.comp.lang.c.
-- 
SF
"Breaking something which works as intended in order to solve a problem 
existing in delusion-space is not usually called 'a workaround'."

 
discussione conclusa... e magari hai anche ragione, e it.comp.lang.c e' 
l'ng piu' giusto
pero' nel manifesto c'e' scritto che si discute di tutti i linguaggi... 
e cita pure il C/C++
voglio dire... mica parlavamo di quanto e' stronzo Berlusconi no?
comunque senza alzare polemiche, la discussione e' finita
andiamo in pace
bye

 andiamo in pace
lungi da me alzare polemiche: č nel tuo interesse conoscere il posto 
dove piů probabilmente avrai una risposta soddisfacente, no?
