Newsgroup: it.comp.lang.c
Titolo: Problemino coi puntatori!

#include <stdio.h>
char *string = "Rosso\n";
void main(void)
{
    printf(string);
    *(string+3) = 'p';
    printf(string);
}
Chi mi sa spiegare perchč in fase di esecuzione questo programmino mi da un'
"operazione non valida". A me sembra tutto OK.
La versione equivalente (facente uso di un array) funziona perfettamente.
#include <stdio.h>
char string[] = "Rosso\n";
void main(void)
{
    printf(string);
    *(string+3) = 'p';
    printf(string);
}
Ma array e puntatori non dovrebbero essere piů o meno la stessa cosa?
(Almeno cosě č scritto in tutti i manuali)
#include <stdio.h>
char string[] = "Rosso\n";
void main(void)
{
 char *str;
 str=string;
    printf(str);
    *(str+3) = 'p';
    printf(str);
}
Anche questa terza versione funziona perfettamente (pur facendo con un
puntatore la stessa cosa che veniva fatta nella prima versione)
Gli errori avvengono in fase di esecuzione (non in fase di compilazione o di
linkaggio), evidentemente il compilatore genera file eseguibili diversi
(particolarmente nei primi due casi). Dunque in C array e puntatori sono
cose diverse? Gli array non vengono in fase di compilazione trattati come
puntatori? O forse qiesto č ciň che fa il visual C? Non ho avuto occasione
di provare a compilare sotto UNIX. Cosa ne pensate?
Grazie.
Ciao.
Luca.

di provare a compilare sotto UNIX. Cosa ne pensate?
In C un array e' qualcosa di completamente diverso da un puntatore
ma in una espressione un array "decade" trasformandosi in un
puntatore al suo primo elemento. Considera queste differenze:
   char array[10];
   char *punt;
   punt=array;  /* Ok, punt ora punta al primo elemento di array */
   printf("%i\n",sizeof(array)); /* Stampa 10 */
   printf("%i\n",sizeof(punt));  /* Probabilmente stampa 4 */
   punt++;  /* Ok, punt ora punta al SECONDO elemento di array */
   array++; /* Errore, gli array non possono essere modificati */
   punt[3]='x';  /* Ok, imposta il QUINTO elemento di array */
   array[3]='y'; /* Ok, imposta il QUARTO elemento di array */
   punt=array+5; /* Ok, punt ora punta al QUARTO elemento di array */
   *punt=10;     /* Ok, imposta il QUARTO elemento di array */
   punt[0]=12;   /* Ok, reimposta sempre lo stesso elemento */
Spero di non averti confuso le idee.
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 Luca.
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it

Siete stati entrambi chiarissimi.
Dunque se non ho capito male le cose funzionano in questa maniera:
Il costrutto
    char stringa[] = "Pippo";
permette di dichiarare la variabile 'stringa' di tipo array, inoltre
permette di dimensionare e inizializzare tutti gli elementi dell'array in
una sola riga.
E' un costrutto un pò particolare, dal momento che in C tutte le scritture
del tipo "Pippo" sono stringhe costanti, ossia non modificabili, per questo
motivo il costrutto
    char *str = "Pippo";
non permette di modificare il contenuto della stringa attraverso la
vavriabile 'str'. Praticamente è come definire un'area di memoria a sola
lettura inizializzata con "Pippo" e fornire in str l'indirizzo iniziale di
tale spazio.
Come mai queste righe di codice funzionano correttamente?
    char *str;
    str = "Pippo";
    printf("%s",str);    // stampa correttamente "Pippo"
Evidentemente prima viene riservata l'area di memoria (a sola lettura) per
la stringa "Pippo" e poi viene fornito in 'str' l'indirizzo del carattere
'P'.
Ora chi mi sa spiegare questa cosa?
    char stringa[] = "Pippo";
    char *str = "Pippo";
    char *str1 = "Pippo";
    printf("stringa:%x str: %x str1:%x",stringa,str,str1);    // stampa gli
indirizzi (in esadecimale) dei tre puntatori
Il risultato dell'esecuzione di questo pezzo di codice è che il contenuto di
'stringa' (un indirizzo) è diverso dal contenuto di 'str' e 'str1', ciò è
comprensibile dal momento che 'stringa' punta a una zona di memoria a
lettura/scrittura, mentre 'str' punta a una zona di memoria a sola lettura,
ossia puntano a zone di memoria diverse.
La cosa (secondo me) sorprendente è che il contenuto di 'str' (un indirizzo)
è lo stesso di 'str1', ossia puntano alla stessa zona di memoria. Io mi
aspettavo che il compilatore assegnasse la stringa costante "Pippo" a una
zona di memoria e assegnasse a 'str' l'indirizzo iniziale; poi in un'altra
zona di memoria scrivesse ancora "Pippo" e fornisse in 'str1' l'indirizzo
iniziale.
Tra l'altro se il codice fosse:
    char *str = "Pippo";
    char *str1 = "Pippa";
    printf("str:%x str1:%x",str,str1);
Gli indirizzi contenuti in 'str e 'str1' sono diversi, ossia "Pippo" e
"Pippa" sono stringhe costanti diverse contenute in aree di memoria
distinte.
Ciò che accade è quindi che il compilatore tutte le volte che incontra una
stringa costante "Pippo" dispone l'area di memoria (a sola lettura)
inizializzata con "Pippo". Se nel codice il compilatore incontra altre
stringhe costanti "Pippo", fa riferimento all'area di memoria che ha già
riservato, non ne dispone un'altra distinta. Visto che la stringa è comunque
a sola lettura, tanto vale riservarla solo una volta.
E' possibile che il compilatore faccia un ragionamento di questo tipo?


 è lo stesso di 'str1', ossia puntano alla stessa zona di memoria.
E' una delle ottimizzazioni che il compilatore esegue.
EMG