Forse il subject non calza poi molto ma non sapevo cosa mettere...
Comunque, arriviamo al sodo:
In un programma (chiamarlo in effetti programma e' un offesa) che sto facendo
ho dichiarato in main un vettore
int vec[MAX]
tra l'altro ho una funzione calc che deve risistemare gli elementi dentro
vec...
Per ora il suo prototipo e'
void calcola(int *vec,int dim)
dove dim e' un parametro passato per esigenze ricorsive, che in questo
momento non interessa...
Quello che non ho capito e' xche' non posso chiamare la funzione con
calcola(&vec,MAX);
passando cioe' il puntetore al puntatore al primo intero contenuto in vec
(scrivere *vec == vec[0] no?!)
e riscrivendo il prototipo (e quindi la funzione)
void calcola(int **vec,int dim)
se faccio cosi' il compilatore dice
warning: passing arg 1 of calcola from incompatible pointer type
Lo so che non c'e' alcun bisogno di scomodare ** dato che il tutto funziona
anche cosi', tuttavia vorrei capire xche' passando alla funzione
&vec
che quindi deovrebbe essere un int **
e scrivendo la funzione stessa in modo da ricevere proprio un dato di questo
tipo il compilatore si sfava.
Mi sa che non ho chiaro qualcosa q questo punto:-((
grazie a tutti per la pazienza...
...e scusate se soo stato poco chiaro
Vi][oZ
--
Per rispondere togliere NONSCASSA da reply-to.
Per indicare l'indirizzo di un array (ovvero l'indirizzo del primo elemento)
basta usare il nome dell'array. Scrivere &vec equivale a scrivere qualcosa
del tipo &<indirizzo>, che non va evidentemente bene.
Per passare una variabile ad una funzione che accetta un puntatore la si
passa preceduta da &, per passare un puntatore si mette solo il nome, e lo
stesso per un array, dato che, appunto, l'indirizzo del primo elemento
array[0] può essere inteso come un puntatore (array).(altrimenti si potrebbe
passare &array[0], nel tuo case &vec[0]).
PS. se avessi detto qualche c*****a, è perché ho iniziato a studiare i
puntatori 2-3 giorni fa...
Marco
Allora facciamo un esempio:
qui abbiamo un'array vec di 10 int;
vec = array di MAX int;
Osserviamo che:
IndirizzoVec = indirizzo di (array di MAX int) = int (*)[MAX] = puntatore
ad array, che e' diverso da (int**) puntatore di puntatori a int.
Se definisci funzione come: int funzione( int **,int ),il compilatore
ti dara' una warning poiche' vedra' che :
funzione(&vec,i) = funzione( (int (*)[10])&vec,int i )
e' diverso da
funzione( int **vec,int pos);
quindi dovremo trasformare : funzione( (int (*)[10])&vec,int i ) in funzione(
(int **)&vec,int i);
ora se noi facessimo : return *(vec+pos) ; abbiamo che:
vec č di tipo (int **) quindi *(vec+pos) = *(int**) = int *;
ma noi dobbiamo far tornare un (int) non un (int *), quindi la cosa da fare e'
castare vec a (int*)
e lo possiamo fare senza stravolgere l'area di memoria puntata data la propieta'
dgli array che fa
si che &vec = vec = (int *)
#include<stdio.h>
#define MAX 10
int funzione ( int **, int );
void main()
{
int vec [ MAX ] = { 1,2,3,4,5,6,7,8,9,0 };
int i = 0;
for ( i = 0;i < MAX; i++ )
printf( "L'elemento e': %d\n", funzione ( (int **)&vec, i ) );
}
int funzione ( int **vec, int pos )
{
return *((int*)vec+pos) ;
}
Ivan Molella
--
Posted from mta10-acc.tin.it [212.216.176.41]
via Mailgate.ORG Server - http://www.mailgate.org
"Vi][oZ" wrote:
>
> Quello che non ho capito e' xche' non posso chiamare la funzione con
>
> calcola(&vec,MAX);
> passando cioe' il puntetore al puntatore al primo intero contenuto in vec
> (scrivere *vec == vec[0] no?!)
> e riscrivendo il prototipo (e quindi la funzione)
>
> void calcola(int **vec,int dim)
Perché la funzione richiede un puntatore a puntatore ad intero mentre tu
gli passi un puntatore ad array di MAX elementi. I due tipi sono quindi
differenti.
EMG
Se vieni dal Pascal, questa sembrerebbe una sintassi accettabile, ma in C
funziona diversamente.
Il nome del vettore è già un puntatore al primo elemento, dato che quando
definisci un vettore non definisci un tipo ma solo un suo modificatore (in
Pascal invece, definisci proprio un tipo).
A vedere bene, scrivere
calcola (vec, ...)
non dovrebbe significare niente, mentre per motivi oscuri si intende invece,
proprio &vec[0]
Sta a te decidere quale sintassi ti è più gradita.
--
Alessandro Monti
Alessandro Monti wrote:
>
> Il nome del vettore è già un puntatore al primo elemento, dato che quando
> definisci un vettore non definisci un tipo ma solo un suo modificatore
E questa da dove è uscita fuori? In C _esiste_ il tipo array e il nome
di un array non è un puntatore al suo primo elemento ma vi decade solo
quando, ad esempio, si passa ad una funzione.
EMG
Scusa puoi spiegarti meglio quando dici che il nome di un array ' non è ' il
puntatore al suo primo elemento?
cioe' dici che dato:
int vec [10]
allora:
*(&vec[0]) != *vec
vec effettivamente non identifica un puntatore,ma tutta l'area di memoria dell'
array,(infatti abbiamo vec = inizio area memoria,e &vec = indirizzodi (inizio
area memoria) e non indirizzo di(puntatore a (inizio area memoria) ),in quanto
vec non esiste come puntatore,ma come array),pero' il nome di un'array equivale
al puntatore al suo primo elemento,e possiamo farci tutte le operazioni
previste con un puntatore,tranne assegnargli un nuovo valore, in quanto non
indirizzabbile.
Quindi:
( void* ) (&vec[0]) == ( void* ) vec
Ivan Molella
--
Posted from mta09-acc.tin.it [212.216.176.40]
Spiegazione :
1. L'indirizzo di un array E' l'indirizzo del primo elemento, ma il
puntatore al primo elemento ha tipo diverso dal puntatore all'array,
quindi, usando il nome dell'array, non necessariamente si intende un
puntatore al primo elemento. Nella maggiorparte dei casi e' cosi', ma
ci sono tre eccezioni specifiche.
2. Scrivere &vec non equivale a scrivere &<indirizzo>, difatti
questo caso corrisponde ad una delle tre eccezioni suddette e cioe'
quei casi in cui, contrariamente alla maggior parte delle volte, il
nome dell'array NON DECADE a puntatore al suo primo elemento, ma
rimane tale (cioe' un oggetto composto di una certa lunghezza).
In parole povere :
Dato
char vec[100] ;
scrivere semplicemente
"vec" equivale a scrivere il puntatore al primo elemento di vec, cioe'
&vec[100], con tipo (char*), tranne che in uno dei seguenti casi :
1. &vec che restituisce una costante puntatore con tipo char(*)[] ;
2. sizeof vec che restituisce una costante intera con valore 100 *
sizeof( char ) ;
3. char vec[100] = "andrea" ; cioe' un'inizializzazione mediante un
literal di tipo stringa.
--
Andrea Laforgia
andrea_...@bigfoot.com
>Se vieni dal Pascal, questa sembrerebbe una sintassi accettabile, ma in C
>funziona diversamente.
Peccato che se dai in pasto quelle righe ad un compilatore Pascal,
vengono fuori una marea d'errori ! ;)))
>Il nome del vettore è già un puntatore al primo elemento, dato che quando
>definisci un vettore non definisci un tipo ma solo un suo modificatore (in
>Pascal invece, definisci proprio un tipo).
Urgh !!!
E dove sta scritto ?
Quando definisci una variabile non definisci affatto un tipo !
In C (come in Pascal) quando definisci un array, definisci uno spazio
di memoria indirizzabile.
Scrivere
int vettore[100] ;
equivale nel modo piu' assoluto a :
var vettore : array [1..100] of integer ;
Vorrei sapere, poi, che intendi con "modificatore".
Il nome di un array e' definito dallo standard come "lvalue non
modificabile".
>A vedere bene, scrivere
>calcola (vec, ...)
>non dovrebbe significare niente, mentre per motivi oscuri si intende invece,
>proprio &vec[0]
"Per motivi oscuri" ? :)
Scrivere :
void calcola( char vec[], ... ) ;
equivale a scrivere
void calcola( char * vec, ... ) ;
in quanto in entrambi i casi viene passato un puntatore, ma non e'
vero che in tutte le circostanze sia cosi' (difatti questa e' una
*dichiarazione*, non una *definizione*).
Se scrivo invece :
void calcola ( char (*)[], ... )
e' ben diverso dallo scrivere :
void calcola( char * , ... ) ;
--
Andrea Laforgia
andrea_...@bigfoot.com
>Scusa puoi spiegarti meglio quando dici che il nome di un array ' non è ' il
>puntatore al suo primo elemento?
Attento, EMG non vuol affermare questo, ma ha detto, giustamente, che
il nome di un array *decade* nel puntatore al suo primo elemento,
nella maggiorparte dei casi, non in tutti.
>cioe' dici che dato:
> int vec [10]
>allora:
> *(&vec[0]) != *vec
Niente affatto. I due valori puntati sono uguali.
Il fatto e' che in entrambe le espressioni sia a sinistra che a destra
del segno di uguale, il nome del vettore DECADE nel puntatore al suo
primo elemento.
>pero' il nome di un'array equivale al puntatore al suo primo elemento,
>e possiamo farci tutte le operazioni previste con un puntatore,
Il nome di un array, secondo l'ANSI C, NON E' GENERALMENTE il
puntatore al suo primo elemento, ma DECADE nel puntatore al suo primo
elemento e ci sono tre circostanze in cui non succede.
1.
Se provi a scrivere :
int p[100], k ;
k = sizeof p ;
noterai che in k c'e' il valore 100*sizeof(int) e non sizeof(int*).
Se il nome di un array fosse SEMPRE un puntatore al primo elemento,
sarebbe vero il contrario.
2.
Se provi a scrivere :
int p[100], *k;
L'operazione &p restituisce una costante indirizzo con tipo (int(*)[])
e non (int *).
Scrivere pertanto :
k = &p ;
comporta un warning per "type-mismatch" da parte di un compilatore non
troppo addormentato.
3.
Quando scrivi :
char s[100] = "andrea" ;
ti sembra forse che si stia assegnando il valore literal stringa
"andrea" al puntatore s ? sarebbe perlomeno una incongruenza di tipi.
---
Queste sono le sole tre eccezioni specifiche in cui il nome di un
array NON decade nel puntatore al suo primo elemento.
--
Andrea Laforgia
andrea_...@bigfoot.com
sono sicuro che intendessi &vec[0]...
Ciao
Marco
Ivan Molella wrote:
>
> Scusa puoi spiegarti meglio quando dici che il nome di un array ' non è ' il
> puntatore al suo primo elemento?
Conviene che ti vai a leggere le FAQ. Questa bisognerà metterla (se non
è stato già fatto) anche nelle nostre.
> pero' il nome di un'array equivale al puntatore al suo primo elemento
Il nome in sé non equivale al puntatore al suo primo elemento ma viene
solo convertito ad esso utilizzandolo in espressioni. Ci sono però delle
eccezioni (sizeof(), & come address_of e string literals).
EMG
>> "vec" equivale a scrivere il puntatore al primo elemento di vec, cioe'
>> &vec[100], con tipo (char*), tranne che in uno dei seguenti casi :
>
>sono sicuro che intendessi &vec[0]...
certo ;) grazie della correzione...
--
Andrea Laforgia
andrea_...@bigfoot.com
Chiarezza e' fatta!
Ho capito il mio errore, grazie a tutti...
Se il nome viene automaticamente convertito a puntatore , senza perdere la
corretta referenziazione ai suoi elementi,allora i due tipi sono "equivalenti",
il che significa che non "sono uguali" , ma che "valgono uguale".
--
Posted from mta10-acc.tin.it [212.216.176.41]
[...]
>
> Conviene che ti vai a leggere le FAQ. Questa bisognerà metterla (se non
> è stato già fatto) anche nelle nostre.
[...]
Mi devo essere perso qualcosa... per "nostre FAQ" intendi le faq in
italiano di it.comp.lang.c ???? Vuoi dire che sono complete? Pensavo
che la cosa fosse morta per mancanza di partecipazione...
Ciao, Luca.
Reply to luca....@tiscalinet.it
> int p[100], *k;
> L'operazione &p restituisce una costante indirizzo con tipo (int(*)[])
> e non (int *).
Per essere precisi il tipo è (int (*)[100]).
Ciao ciao,
Andrea
--
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and
the Ugly)."
(by Matt Welsh)
> >calcola (vec, ...)
> >non dovrebbe significare niente, mentre per motivi oscuri si intende
invece,
> >proprio &vec[0]
> "Per motivi oscuri" ? :)
I motivi oscuri derivano dal fatto che, avendo definito vec come un vettore,
mi aspetterei che
calcola (vec...)
significhi un passaggio alla funzione di tutto il vettore.
Che ci siano dei motivi validi per accettare questa sintassi e darle un
significato diverso, non lo metto in dubbio. Mi sembra però una piccola
"forzatura" delle regole. Del resto, il fatto che il nome di un array decade
nel suo puntatore, dove opportuno, in letteratura è sempre ben spiegato,
data la sua poca intuitività.
--
Alessandro Monti
>Intendevo per il controllo dei tipi. Mi risulta che in Pascal un puntatore
>sia diverso dall'array, ma è tanto tempo che non uso Pascal.
Certo, e' cosi' in Pascal, ma lo e' anche in C.
Anche in C, cioe', definire un array non vuol dire definire un
puntatore.
>I motivi oscuri derivano dal fatto che, avendo definito vec come un vettore,
>mi aspetterei che calcola (vec...)
>significhi un passaggio alla funzione di tutto il vettore.
>Che ci siano dei motivi validi per accettare questa sintassi e darle un
>significato diverso, non lo metto in dubbio. Mi sembra però una piccola
>"forzatura" delle regole.
Si', e' comunque una forzatura di una regola intuitiva, ma che non
conviene applicare. Il pascal in questo differisce e cioe' esegue una
copia dell'oggetto vettore nello stack, sempre che non si dichiari il
vettore nei parametri, per riferimento mediante "var".
Il C, per un principio di semplicita' e convenienza, implementa tutti
i passaggi per copia, rendendo poi necessario l'uso di un puntatore
per simulare il riferimento.
Talvolta la semplicita' e' molto difficile da spiegare ! :)
>Del resto, il fatto che il nome di un array decade
>nel suo puntatore, dove opportuno, in letteratura è sempre ben spiegato,
>data la sua poca intuitività.
Nella _buona_ letteratura e' sempre spiegato ! :)
--
Andrea Laforgia
andrea_...@bigfoot.com
>Se il nome viene automaticamente convertito a puntatore , senza perdere la
>corretta referenziazione ai suoi elementi,allora i due tipi sono "equivalenti",
>il che significa che non "sono uguali" , ma che "valgono uguale".
INIZIO della sezione 6 delle FAQ in italiano (non sono disponibili in
versione integrale).
Sezione 6 - Vettori e puntatori.
6.1
---
D: Ho definito in un mio file sorgente "char a[6]" e in un
altro "extern char *a".
Perche' non funziona ?
R: In un file hai definito un vettore di caratteri, mentre
nell'altro hai semplicemente dichiarato un puntatore a
caratteri.
Il motivo del malfunzionamento e' semplice : la
dichiarazione "extern char *a" non corrisponde all'attuale
definizione di "a".
Il tipo "puntatore-a-T" non e' uguale a "vettore-di-T".
Usa "extern char a[]".
Riferimenti:
ISO Sec. 6.5.4.2; CT&P Sec. 3.3 pp. 33-4, Sec. 4.5 pp. 64-5.
6.2
---
D: Ma io ho sentito dire che char a[] e' identico a char * a.
R: Non proprio (cio' che hai sentito riguarda i parametri
formali delle funzioni ; vedi 6.4).
I vettori, pero', non sono puntatori.
La dichiarazione char a[6] richiede che venga riservato
spazio per 6 caratteri, a cui accedere con il nome "a".
Cio' significa che esiste una locazione di memoria chiamata
"a" alla quale trovano posto in via sequenziale 6 caratteri.
La dichiarazione char *p, invece, richiede solo spazio per
contenere il puntatore, chiamato "p".
Questo puntatore puo' puntare praticamente ovunque, a
qualsiasi carattere o qualsiasi sequenza di caratteri
contigui, o da nessuna parte (vedi 5.1 e 1.30).
Le dichiarazioni :
char a[] = "hello";
char *p = "world";
inizializzano le strutture dati nel modo seguente :
+---+---+---+---+---+---+
a: | h | e | l | l | o |\0 |
+---+---+---+---+---+---+
+-----+ +---+---+---+---+---+---+
p: | *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
E' importante rendersi conto che un riferimento come x[3]
genera un codice diverso a seconda se x sia un vettore o un
puntatore.
Date le dichiarazioni di cui sopra, quando il compilatore
incontra l'espressione a[3], genera codice per partire
dalla locazione "a", muoversi tre locazioni in avanti e
prelevare il valore contenuto.
Quando invece incontra l'espressione p[3], genera codice
per partire dalla locazione "p", prelevare il valore del
puntatore, aggiungere 3 ad esso e prelevare il carattere
puntato.
In altre parole, a[3] si trova tre posti dopo l'inizio
dell'oggetto *chiamato* "a", mentre p[3] si trova tre posti
dopo l'oggetto *puntato* da p.
Nell'esempio precedente, sia a[3] che p[3] finiscono col
contenere il carattere 'l', ma il compilatore lo ottiene in
modo diverso.
La differenza essenziale e' che i valori di un vettore come
"a" e un puntatore come "p" sono calcolati diversamente
quando essi appaiono nelle espressioni, a seconda o meno
che si usi l'indicizzazione.
Riferimenti:
K&R2 Sec. 5.5 p. 104; CT&P Sec. 4.5 pp. 64-5.
6.3
---
D: Che significa quindi in C "equivalenza tra puntatori e
vettori" ?
R: Una certa confusione circa vettori e puntatori in C e'
dovuta sicuramente ad un fraintendimento di questa
espressione.
Dire che vettori e puntatori sono "equivalenti" non
significa che essi siano identici o intercambiabili.
Questo vuol dire che un puntatore e l'aritmetica definita
per esso consentono di accedere in modo conveniente agli
elementi di un vettore o di simularlo.
La chiave per capire questo tipo di equivalenza e' la
seguente :
Un lvalue di tipo vettore-di-T che compare in una
espressione decade (con tre eccezioni) in un puntatore al
suo primo elemento ;
Il tipo di questo puntatore risultante e' puntatore-a-T.
Questo significa che laddove il nome di un vettore compaia
in una espressione, il compilatore traduce implicitamente
questo riferimento nel puntatore al suo primo elemento,
come se il programmatore avesse scritto &a[0].
Le eccezioni capitano quando il nome del vettore e'
argomento di sizeof o dell'operatore &, o se esso (nel caso
fosse char []) viene inizializzato con una stringa in fase
di dichiarazione.
Come conseguenza di questa definizione il compilatore non
applica diversamente tra vettori e puntatori
l'indicizzazione mediante [].
In una espressione della forma a[i], a decade in puntatore,
seguendo la regola, e viene pertanto trattato come se fosse
una variabile puntatore della forma p[i] (eventualmente,
l'accesso alla memoria differisce, come spiegato alla 6.2).
Se si compisse un'assegnazione del tipo :
p = a;
allora p[3] e a[3] conterrebbero lo stesso elemento.
Vedi anche la 6.8 e la 6.14.
Riferimenti:
K&R1 Sec. 5.3 pp. 93-6; K&R2 Sec. 5.3 p. 99; ISO Sec.
6.2.2.1, Sec. 6.3.2.1, Sec. 6.3.6; H&S Sec. 5.4.1 p. 124.
6.4
---
D: Perche' allora si possono intercambiare le dichiarazioni
vettore e puntatore per i parametri formali di una funzione
?
R: Si suppone per convenienza.
Dato che i vettori decadono immediatamente in puntatori,
non viene mai passato realmente un vettore alla funzione.
Consentire a un parametro puntatore di essere dichiarato
come vettore e' solo un modo semplice per dare
l'impressione che venga passato un vettore, forse perche'
all'interno della funzione esso verra' trattato come se
fosse tale.
In particolare, qualsiasi dichiarazione di parametri in cui
figuri un vettore, es.:
void f(char a[])
{ ... }
viene trattata dal compilatore come se si riferisse a un
puntatore, in quanto proprio questo e' cio' che riceve la
funzione al momento del passaggio di un vettore :
void f(char *a)
{ ... }
Questa conversione, pero', riguarda soltanto le
dichiarazioni dei parametri formali di funzioni e nessun
altro caso.
Vedi anche la 6.21.
Riferimenti :
K&R1 Sec. 5.3 p. 95, Sec. A10.1 p. 205; K&R2 Sec. 5.3 p.
100, Sec. A8.6.3 p. 218, Sec. A10.1 p. 226; ISO Sec.
6.5.4.3, Sec. 6.7.1, Sec. 6.9.6; H&S Sec. 9.3 p. 271; CT&P
Sec. 3.3 pp. 33-4.
6.7
---
D: In che modo un vettore puo' essere un lvalue, se non si
puo' compiere alcuna assegnazione su esso ?
R: Lo Standard ANSI C definisce un "lvalue modificabile" che
un vettore non e'.
Riferimenti :
ISO Sec. 6.2.2.1; Rationale Sec. 3.2.2.1; H&S Sec. 7.1 p.
179.
6.8
---
D: In parole povere qual'e' la differenza tra vettori e
puntatori ?
R: Per i vettori viene riservato spazio in modo automatico, ma
essi non possono essere ne' riposizionati in memoria, ne'
ridimensionati.
Ai puntatori deve essere assegnato esplicitamente un
valore, perche' puntino allo spazio di memoria riservato
per i dati (per es. con malloc), ma ad essi e' possibile
assegnare un nuovo valore (il che significa puntare a
oggetti differenti).
In base alla cosiddetta equivalenza tra vettori e puntatori
(v. 6.3), essi sembrano spesso intercambiabili e, in
particolare, un blocco di memoria assegnato da malloc e'
spesso trattato come se fosse un vero e proprio vettore (v.
6.14 e 6.16). (Attenzione comunque a "sizeof").
Vedi anche 1.32 e 20.14.
6.9
---
D: Qualcuno mi ha spiegato che i vettori non sono altro che
puntatori costanti.
R: Questa e' una semplificazione troppo forte.
Il nome di un vettore e' una costante nel senso che non
puo' subire assegnazioni, ma un vettore *non* e' un
puntatore.
Vedi anche 6.2, 6.3, 6.8.
--
Andrea Laforgia
andrea_...@bigfoot.com
E ti pare la traduzione di: "...or is a string literal initializer for a
character array.)" ?
Per chi fosse interessato: la FAQ originale (in inglese) si trova a
http://www.eskimo.com/~scs/C-faq/top.html
>> ....o se esso (nel caso fosse char []) viene inizializzato
>> con una stringa in fase di dichiarazione.
>
>E ti pare la traduzione di: "...or is a string literal initializer for a
>character array.)" ?
Non vedo che cosa ci sia di sbagliato, sinceramente, "string literal"
o "stringa" rappresentano la stessa cosa, non essendoci in C, il tipo
stringa predefinito, ma essendo, comunque, un insieme di caratteri
racchiuso tra due apici, una stringa.
>Per chi fosse interessato: la FAQ originale (in inglese) si trova a
Non vedo, sinceramente, che cosa speri di ottenere con questi
comportamenti. Se una persona ha sbagliato, la si aiuta a comprendere
la correzione. Mi piacerebbe che ci fosse uno spirito di
collaborazione maggiore in questo ng. In fondo il gruppo ha il fine di
discutere sugli aspetti del linguaggio ed eventualmente aiutare gli
altri a capire. Che bella collaborazione ! se hai da ridire su una
traduzione, perche' non offri quella corretta, in modo da modificare
le FAQ in italiano ? Nel caso non fossi intenzionato a farlo,
complimenti, continua cosi'...
--
Andrea Laforgia
andrea_...@bigfoot.com
Ivan Molella wrote:
>
> Se il nome viene automaticamente convertito a puntatore , senza perdere la
> corretta referenziazione ai suoi elementi,allora i due tipi sono "equivalenti",
> il che significa che non "sono uguali" , ma che "valgono uguale".
Diresti che un int è equivalente ad un double solo perché in certi casi
viene convertito automaticamente ad esso (nelle conversioni implicite)?
EMG
Bianco wrote:
>
> Mi devo essere perso qualcosa... per "nostre FAQ" intendi le faq in
> italiano di it.comp.lang.c ???? Vuoi dire che sono complete? Pensavo
> che la cosa fosse morta per mancanza di partecipazione...
No, non sono morte ma non sono purtroppo neanche ancora complete.
Aspettiamo che Paolo Marotta si decida ad organizzare il materiale...
aspetta... sai che non ricordo più se queste di cui parlo riguardano il
C o il C++? Sto confondendo i due gruppi...
EMG
Alessandro Monti wrote:
>
> Del resto, il fatto che il nome di un array decade
> nel suo puntatore, dove opportuno, in letteratura è sempre ben spiegato,
> data la sua poca intuitività.
Evidentemente non abbastanza. :-)
EMG
>No, non sono morte ma non sono purtroppo neanche ancora complete.
>Aspettiamo che Paolo Marotta si decida ad organizzare il materiale...
>aspetta... sai che non ricordo più se queste di cui parlo riguardano il
>C o il C++? Sto confondendo i due gruppi...
Paolo Marotta ??? forse stai confondendo col C++... :)
--
Andrea Laforgia
andrea_...@bigfoot.com
Non intendo assolutamente mettere in discussione, il fatto che si tratti di 2 tipi di
dato diversi, ma volevo soltanto specificare che siccome nell' uso di array,la
decadenza a puntatore e' molto frequente (piu' di quanto non capiti tra un double e
un int ),li possiamo
in qualche modo "assimilare", e con questo spero di chiudere questa discussione durata
anche troppo secondo me.
--
Posted from mta14-acc.tin.it [212.216.176.45]
>li possiamo in qualche modo "assimilare"
Non sono d'accordo e ti spiego il perche'.
Capisco che nella maggioranza dei casi gli array decadono, ma e'
sempre bene evitare di assimilarli e mantenere viva la differenza.
Molti testi che trattano il C non affrontano neanche da lontano questo
aspetto e chi studia da questi libri, vuoi perche' ancora fermi al C
pre-ANSI, vuoi perche' l'autore reputa giusto "assimilare", non sono a
conoscenza di cio' che l'ANSI stabilisce. E' un peccato, perche' con
l'ANSI C sono stati apportati dei grossi miglioramenti al linguaggio.
Molta gente, per esempio, e' ancora ferma all'idea che dato int a[10],
scrivere &a sia concettualmente errato (perche' considerato come il
calcolo dell'indirizzo di un indirizzo), cosa vera nel C pre-ANSI
(quello trattato sul K&R I versione) ma non vera nel C ANSI (quello
trattato sul K&R II versione).
--
Andrea Laforgia
andrea_...@bigfoot.com
>Conviene che ti vai a leggere le FAQ. Questa bisognerà metterla (se non
>è stato già fatto) anche nelle nostre.
dove si trovano queste FAQ?
Aranar
e-mail: ro...@geocities.com
http://www.nettaxi.com/citizens/Aranar/ (above all VgaPlanets)
http://www.tempolibero.com/user/aranar (sopratutto VgaPlanets)
> Riferimenti:
> K&R2 Sec. 5.5 p. 104; CT&P Sec. 4.5 pp. 64-5.
queste sigle a cosa si riferiscono?
>Quello che non ho capito e' xche' non posso chiamare la funzione con
>
>calcola(&vec,MAX);
>passando cioe' il puntetore al puntatore al primo intero contenuto in vec
>(scrivere *vec == vec[0] no?!)
>e riscrivendo il prototipo (e quindi la funzione)
>
>void calcola(int **vec,int dim)
>
>se faccio cosi' il compilatore dice
> warning: passing arg 1 of calcola from incompatible pointer type
Io interpreterei l'errore cosi': e' come se tu stessi facendo
lvalue = &(x + y);
oppure
lvalue = &(&x);
ossia richiedi il puntatore ad una cosa che non c'e', nel senso che "vec[]"
e' un array, con "vec" puoi indicare un puntatore al suo primo elemento, ma
a questo puntatore non e' assegnata nessuna zona di memoria [conosciuta],
per cui chiederne l'indirizzo non avrebbe molto senso.
Potresti fare
int vec[100];
int *pvec;
pvec = vec;
Calcola(&pvec, dim);
Spero di essere stato chiaro, anche se la frase della dal compilatore
(passing arg 1 of calcola from incompatible pointer type) non mi e' del
tutto chiara.
Era questo che voleva dire Marco Iannaccone, vero?
>
>Vi][oZ
Saluti,
Mardy
IMHO la frase dovrebbe suonare più o meno "oppure è la stringa
che inizializza un vettore di caratteri".
[ snip ]
> Non vedo, sinceramente, che cosa speri di ottenere con questi
> comportamenti.
Do le indicazioni che tu hai tralasciato di fornire: ti vorrei
far notare che tu hai postato la tua parziale traduzione della
C-FAQ senza dire cos'era, nè da dove veniva, nè chi è l'autore
e così via.
Magari qualcuno era interessato a vedere anche tutto il resto,
non ti pare ?
Inoltre non è chiaro che è un lavoro di traduzione: quelli che
non lo sanno potrebbero erroneamente pensare che siano davvero
una raccolta di domande e risposte tratte da questo NG.
A proposito, l'autore originale è stato contattato oppure stai
facendo la tua traduzione (di un testo coperto da copyright) a
sua insaputa ?
Tralascio il resto che non merita commenti.
Aranar wrote:
>
> > Conviene che ti vai a leggere le FAQ. Questa bisognerà metterla (se non
> > è stato già fatto) anche nelle nostre.
>
> dove si trovano queste FAQ?
Non sono ancora pronte. E forse non lo saranno mai in quanto abbiamo
scoperto poi che la traduzione era un'operazione non corretta. Allora,
mi chiedevo, perché non fare qualcosa di simile a ciò che stiamo facendo
in it.comp.lang.c++ e cioè lasciare le FAQ ufficiali come riferimento e
farne una versione ridotta con le domande più frequenti che compaiono in
questo newsgroup?
Se qualcuno si occupasse di raccogliere le domande/risposte (passate o
future) potremmo, in poco tempo e con poca fatica, averne un cospicuo
numero.
EMG
Aranar wrote:
>
> > Riferimenti:
> > K&R2 Sec. 5.5 p. 104; CT&P Sec. 4.5 pp. 64-5.
>
> queste sigle a cosa si riferiscono?
K&R2 è il famoso libro di Kernighan e Ritchie "Il linguaggio C", seconda
edizione. L'altra sigla non mi sovviene...
EMG
Andrea Foco wrote:
>
> A proposito, l'autore originale è stato contattato oppure stai
> facendo la tua traduzione (di un testo coperto da copyright) a
> sua insaputa ?
Vorrei solo precisare che non era solo la "sua" traduzione. Avevamo
iniziato a farla in gruppo quando qualcuno ci ha avvisati che non si
poteva. A quel punto abbiamo smesso. Ora io propongo di farne una
nostra.
EMG
>IMHO la frase dovrebbe suonare più o meno "oppure è la stringa
>che inizializza un vettore di caratteri".
Quindi riferendosi all'oggetto che compare alla destra del segno di
uguale ?
cioe' in
char vettore[] = "ciao" ;
ci si sta riferendo a "ciao" e non a vettore ?
E' questo il senso ?
Cioe' e' da interpretare "ciao" come l'array citato e non vettore ?
>Do le indicazioni che tu hai tralasciato di fornire: ti vorrei
>far notare che tu hai postato la tua parziale traduzione della
>C-FAQ senza dire cos'era, nè da dove veniva, nè chi è l'autore
>e così via.
Foco, leggi i messaggi con piu' attenzione :
"INIZIO della sezione 6 delle FAQ in italiano (non sono disponibili in
versione integrale)."
In una nota cosi' informale non credo sia importante specificare
l'autore.
>Magari qualcuno era interessato a vedere anche tutto il resto,
>non ti pare ?
Per l'argomento in discussione era sufficiente solo quel brano.
>Inoltre non è chiaro che è un lavoro di traduzione: quelli che
>non lo sanno potrebbero erroneamente pensare che siano davvero
>una raccolta di domande e risposte tratte da questo NG.
Ripeto : per l'argomento in discussione non era necessario specificare
che si tratta di FAQ tradotte (tra l'altro c'e' scritto "in italiano"
il che fa comunque pensare che non siano originali).
>A proposito, l'autore originale è stato contattato oppure stai
>facendo la tua traduzione (di un testo coperto da copyright) a
>sua insaputa ?
E questo che cosa significa ?
Anche quando si cita lo standard o una frase del Kernighan & Ritchie
si sta riprendendo un brano da un testo che e' sotto copyright.
Nessuno si e' accollato la proprieta' del testo in questione.
Ti ripeto che all'inizio del messaggio c'e' scritto che la versione
integrale del documento non e' disponibile, in quanto non e' stata mai
pubblicata. Se e' per questo, poi, e' da considerare illegale anche
riportare brani del testo originale.
>Tralascio il resto che non merita commenti.
Eh...la verita' fa male.... ;)
--
Andrea Laforgia
andrea_...@bigfoot.com
--
Alessandro Monti
[root@fokhouse /root]# tail -200 /usr/doc/FAQ/txt/C.FAQ |
> grep -B 2 "K&R2\|CT&P"
Brian W. Kernighan and Dennis M. Ritchie, _The C Programming Language_,
Second Edition, Prentice Hall, 1988, ISBN 0-13-110362-8, 0-13-110370-9.
(See also question 18.10.) [K&R2]
---
Andrew Koenig, _C Traps and Pitfalls_, Addison-Wesley, 1989, ISBN 0-201-
17928-8. [CT&P]
[root@fokhouse /root]#
>Si, ma si deve citare l'originale, altrimenti può sembrare farina del tuo
>sacco (l'originale o la traduzione no autorizzata, non importa) e ledi il
>copyright.
Va bene, ma tante volte qui dentro, anche tra gli ultimi messaggi, si
sono citati brani di testi dei quali non e' stato citato l'autore.
Comunque, tagliamo questa discussione. A me sembra che ci si voglia
arrampicare sugli specchi per non affrontare il problema reale e cioe'
che ogni qual volta si presenta un errore da parte di qualcuno, si e'
piu' interessati a far bella figura criticandolo in malo modo, piu'
che aiutare a comprendere il misfatto. Questo vale un po' per tutti i
gruppi di discussione e sarebbe meglio, in questo, aiutare gli altri a
comprendere l'errore. Chi giudica questa cosa non degna di commenti,
sa di essere nel torto pieno.
>Su questo ti do' torto: dovevi citare l'originale.
Come avrebbero dovuto fare tutti gli altri, allora.
Cosa che non sempre e' stata fatta, visto che un po' tutti giudicano
il ng un ambiente informale di discussione.
--
Andrea Laforgia
andrea_...@bigfoot.com
--
Alessandro Monti
> char vettore[] = "ciao" ;
> ci si sta riferendo a "ciao" e non a vettore ?
[ snip ]
Si, nel senso che quanto sopra scritto è del tutto equivalente a
char vettore[] = { 'c', 'i', 'a', 'o', '\0' };
e non si ha l'usuale decadenza come nel caso di
char *ptr = "ciao";
Però toglimi una curiosità: ti ho sentito citare le tre eccezioni
alcune volte, e stai dicendo che non avevi la più pallida idea di
che cosa volesse dire la terza ?
Come mai non hai mai chiesto chiarimenti al NG ?
Io ti ho ripreso senza tante spiegazioni perchè pensavo ad un tuo
errore di traduzione dettato dalla fretta.
[ snip ]
> In una nota cosi' informale non credo sia importante specificare
> l'autore.
Qualcuno potrebbe pensare che sei tu, ad esempio...
Ma non è questo il nocciolo della faccenda: io ho postato l'indirizzo
della C-faq per il banale motivo che ritengo sia molto utile, e penso
che sia il caso di diffonderlo il più possibile, anche per evitare le
ripetizioni delle solite domande.
Per quanto riguarda la traduzione, era un'ottima idea, ma se come dice
EMG (mi pare) non è possibile, potrebbe essere il caso di fare una FAQ
del NG.
[ snip ]
> Eh...la verita' fa male.... ;)
Più che altro, non credo che tu possa dare lezioni ad alcuno. ;)
>Però toglimi una curiosità: ti ho sentito citare le tre eccezioni
>alcune volte, e stai dicendo che non avevi la più pallida idea di
>che cosa volesse dire la terza ?
>Come mai non hai mai chiesto chiarimenti al NG ?
Non ne ho bisogno. Questo conferma i miei sospetti.
A confronto con lo standard, le C-FAQ non sono molto chiare.
Il problema e' che in una espressione del tipo :
char vec[] = "valorestringa" ;
Sia vec che "valorestringa" hanno tipo "array of char".
In entrambi i casi si sta parlando di vettori che non decadono.
--
Andrea Laforgia
andrea_...@bigfoot.com
Andrea Foco wrote:
>
> Piů che altro, non credo che tu possa dare lezioni ad alcuno. ;)
Ma che significa? Preferiresti che non ci fosse un Andrea Laforgia che
si sforza di spiegare tante cose a chi le chiede solo perché, forse, ha
avuto un lapsus? Siamo tutti qui per imparare e la forza del dibattito č
proprio questa: vedere le cose da diversi punti di vista, sentirle
ripetere in tutte le salse, venire a contatto con argomenti che magari
si sono trascurati e... sentire le "lezioni" di Alex Martelli. :-)
EMG
>Ma che significa? Preferiresti che non ci fosse un Andrea Laforgia che
<snip>
lasciamo perdere, per carita', non voglio che si aprano dei flame per
colpa mia...
--
Andrea Laforgia
andrea_...@bigfoot.com
Che tu _ora_ non ne abbia bisogno, è lapalissiano 8)
> Questo conferma i miei sospetti.
> A confronto con lo standard, le C-FAQ non sono molto chiare.
> Il problema e' che in una espressione del tipo :
> char vec[] = "valorestringa" ;
> Sia vec che "valorestringa" hanno tipo "array of char".
> In entrambi i casi si sta parlando di vettori che non decadono.
Ma che stai dicendo ? Ti riporto il pezzo della C-Faq
"...or is a string literal initializer for a character array.)"
Non c'è nessuna ambiguità, a meno che tu non pensi che vec possa
essere definito come 'string literal' 8)
Trovo irritante il modo in cui eviti di ammettere i tuoi evidenti
errori, comunque siamo a Natale, chiudo qui e Buone Feste a tutti.
> Andrea Foco wrote:
>>
>> Più che altro, non credo che tu possa dare lezioni ad alcuno. ;)
> Ma che significa? Preferiresti che non ci fosse un Andrea Laforgia che
[ snip ]
> si sono trascurati e... sentire le "lezioni" di Alex Martelli. :-)
Be' vedi, mentre mi dispiace di non 'sentire' da un pezzo A. Martelli, di
A. Laforgia posso tranquillamente fare a meno.
Io comunque parlavo di lezioni di comportamento. Giusto a puntino: io gli
ho spiegato, mi pare chiaramente, una cosa che lui non aveva capito e...
hai visto un 'grazie' tu nella sua risposta ?
>"...or is a string literal initializer for a character array.)"
Giusto a titolo informativo, mi chiedo, dato che nell'espressione :
char vec[] = "literal" ;
"literal" non decade in puntatore, se sia sbagliato riferirsi anche a
vec come array che non decade. E' ovvio che non decada neanche vec, in
quanto c'e' corrispondenza tra lo stesso tipo di dato (array-of-char
l'uno e array-of-char l'altro). Ma e' ovvio che dovro' discuterne con
qualcun altro ;)
>Trovo irritante il modo in cui eviti di ammettere i tuoi evidenti
>errori
ROTFL ;)
Ma se e' da un po' di messaggi a questa parte che sto ribadendo che se
qualcuno commette un errore, bisogna aiutare a capire !
Da parte mia, io trovo irritanti le tue rispostine acrimoniose e piene
di superbia. Ma che hai difficolta' a socializzare ? ;)
Comunque, giusto per tagliare corto, su una cosa ti do' ragione : e'
Natale, lasciamo perdere e auguri.
--
Andrea Laforgia
andrea_...@bigfoot.com
>Be' vedi, mentre mi dispiace di non 'sentire' da un pezzo A. Martelli, di
>A. Laforgia posso tranquillamente fare a meno.
...
>Io comunque parlavo di lezioni di comportamento. Giusto a puntino: io gli
>ho spiegato, mi pare chiaramente, una cosa che lui non aveva capito e...
>hai visto un 'grazie' tu nella sua risposta ?
ROTFL !
Ma per favore ! ;)
Buon Natale !
--
Andrea Laforgia
andrea_...@bigfoot.com
Ho provato un po' con il TCC a compilare il seguente codice.......
#include <stdio.h>
void main(){
char vett[]="gatto";
char *p;
p=&vett;
printf("%s",p);
getchar;
}
e mi da warning proprio come avete detto.
Ora sostituendo
...
p=vett;
...
se ho capito bene non da nessun warning perchè vett, in questo caso decade
nel puntatore al suo primo elemento.
--
________________________________
Togliete NoSpaM per rispondermi
Buone Feste
bye Brain
Attenzione, assegnare p = &vett non ti assegna a p il puntatore alla
stringa "gatto"
ma il puntatore alla variabile vett ( che è un puntatore )
Se vuoi assegnare ad un puntatore l'indirizzo di un array devi fare p =
&vett[0] o p=vett
Spero di aver risposto alla tua domanda
Stefano
Fante Stefano wrote:
> > Ho provato un po' con il TCC a compilare il seguente codice.......
> >
> > #include <stdio.h>
> > void main(){
> > char vett[]="gatto";
> > char *p;
> > p=&vett;
> > printf("%s",p);
> > getchar;
> > }
> >
>
> Attenzione, assegnare p = &vett non ti assegna a p il puntatore alla
> stringa "gatto"
> ma il puntatore alla variabile vett ( che è un puntatore )
>
Attento:vett = array = area di memoria identificata da vett;
&vett = indirizzo di (area di memoria)
quindi &vett e' si un puntatore,ma corrdisponde a vett,anche se formalmente
sono 2 tipi diversi:
vett = array
&vett = (*)[] = puntatore ad array.