Newsgroup: it.comp.lang.c
Titolo: Accesso ai valori puntati

Ciao a tutti, sono abbastanza niubbo :)
Stavo testanto questo codice:
#include <stdio.h>
main()
{
char *p = "pippo";
char *q = "pippo";
typedef enum {FALSE = 0, TRUE} bool;
bool uguali = FALSE;
int i,j;
for(i=0; *(p+i)!='\0'; i++);
for(j=0; *(q+j)!='\0'; j++);
if (i==j)
    {
    for(i=0; *(p+i) == *(q+i); i++); /* IL PROBLEMA E' QUI (?) */
    if (i<j) uguali = FALSE;
    else uguali = TRUE;
    }
else uguali = FALSE;
}
Il problema è questo for:
for(i=0; *(p+i) == *(q+i); i++);
Compilo con cygwin su Win98, l'errore che restituisce è questo:
handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
open_stackdumpfile: Dumping stack trace to AAA.EXE.stackdump
Ho provato anche ad accedere diversamente ai valori puntati:
for(i=0; p[i] == q[i]; i++);
Ma ho sempre lo stesso errore.
Qual'è il problema? Compilatore o sintassi?
Deep

 char *q = "pippo";
Scusate, forse ho capito: il problema è che i due puntatori puntano alla
stessa stringa.
Dico bene? :)
Deep


Non sono un grosso esperto, ma se provi a far girare questo programma:
#include <stdio.h>
int main()
{
char *p = "Pippo";
char *q = "Pippo";
printf("p = %p  q = %p\n", p, q);
return 0;
}
ti accorgi subito di come effettivamente puntino allo stesso indirizzo di
memoria. Probabilmente, si tratterà di una ottimizzazione del compilatore...
(è una mia ipotesi)
'sera lietissima, Marco


Ho fatto una prova per sfizio: se tu sostituisci
char * p = "pippo";
char * q = "pippo";
con
char p[] = "pippo";
char q[] = "pippo";
questi due array sono proprio variabili distinte, che puntano a due zone di
memoria diverse. Azzardando una spiegazione, posso pensare che nel primo
caso tu dichiari due puntatori, e si alloca spazio per quelli, e poi copi
nei puntatori l'indirizzo della cella di memoria che contiene la costante
(qui l'inghippo) "pippo", "allocata" una sola volta.
Viceversa, nel secondo modo, tu inizializzi due array, e uno spazio
ovviamente separato per ciascuno di essi, in cui tu copi la stringa "pippo".
Spero di non aver dato una spiegazione poco aderente allo standard; nel
caso, siate implacabili ! =P
'sera lietissima, Marco

 (qui l'inghippo) "pippo", "allocata" una sola volta.
[cut]
Ho pensato anche io cosě e difatti, nelle prove che ho fatto dopo,  p e q
puntano lo stesso indirizzo.
Grazie per le risposte :)
Deep

     for(i=0; *(p+i) == *(q+i); i++); /* IL PROBLEMA E' QUI (?) */
for(i == 0; *(p + i)  !=  '\0'; i++);
Il tuo ciclo fallisce poichè il ciclo stesso non termina con il carattere
'\0';
E dato che stai puntando ad una memoria non allocata (ovvero dopo
il carattere '\0') , il tuo programmino genera un'eccezione.

 il carattere '\0') , il tuo programmino genera un'eccezione.
Forse non ho capito cosa intendi dire.
Se ti riferisci alla parte di codice quotato, no: funziona benissimo.
Quella riga legge la stringa puntata da p. Le stringhe terminano sempre con
\0. Quindi finchč non incontra \0 incremente i. Mi serviva per calcolare la
lunghezza della stringa (anche se la conosco a priori).
Deep

 un'eccezione.
Ma il problema non è dovuto al fatto che p e q puntano alla stessa stringam
quindi il SO si ritrova a dover accedere ad una variabile già in uso?
Spero non vi arrabbierete se dico cazzate :)
Cmq ho riscritto il codice, lo posto qui sotto:
/* Il programma realizza un confronto fra due stringhe puntate da due
puntatori */
#include <stdio.h>
main()
{
char *p = "stringa1";
char *q = "stringa2";
typedef enum {FALSE = 0, TRUE} bool;
bool uguali = FALSE;
int i,j;
if(q==p) uguali=TRUE; /*se puntano alla stessa stringa è ovvio che siano
uguali*/
else
    {
    for(i=0; *(p+i)!='\0'; i++); /*conteggio la lunghezza delle due
stringhe*/
    for(j=0; *(q+j)!='\0'; j++);
    if (i==j) /* se hanno la stessa lunghezza...*/
        {
        for(i=0; *(p+i) == *(q+i); i++);
        if (i<j) uguali=FALSE; /*se il ciclo si interrompe significa che le
stringhe non sono uguali*/
        else uguali=TRUE;
        }else uguali=FALSE;
    }
}

 [ ...]
IMO questo e' un concetto importante per capire il C.
Un puntatore e' una variabile che contiene un indirizzo
di memoria. Period ! ( come dicono gli americani  ;)  )
Non c'e' nessun concetto di 'variabile da sfondare'.
E' vero che punta ad una array lunga 6 char,
ma questo lo sai tu ( e ne devi tener conto ),
lui conosce solo l'indirizzo a cui punta e niente altro.
E' questo il bello del C ( o il brutto,secondo i gusti ).   :)
Ciao
E.

  egrep -A2 '^   \*.+string'
   * GCC normally makes string constants read-only.  If several
     identical-looking string constants are used, GCC stores only one
     copy of the string.
[fok@localhost varie]$
---live action---
-- 
error: can't find .sigfile 'a_punto_foco_presso_virgilio_punto_it'

      copy of the string.
Perfetto :)
Grazie a tutti per l'aiuto e le delucidazioni
Deep

"gsx" wrote..:
[cut]
Denghiů anche a te
Deep

 Assolutamente nessuna (anche se manca il !='\0', ti si perso un pezzo:)).
Affatto.
(p[i] != '\0') e (p[i]) 
sono equivalenti. 8)
-- 
error: can't find .signature file 'a_punto_foco_presso_virgilio_punto_it'

 sono equivalenti. 8)
Ok, è chiaro che ho le idee abbastanza confuse sui puntatori e ho fatto la
mia pessima figura :)
Ma non avevamo detto che il ciclo senza la condizione p[i] != '\0' porta il
puntatore a puntare fuori dalla stringa?
Quindi se consideriamo solo il ciclo:
for (i = 0; (p[i] == q[i]) && p[i]; ++i);
p[i] in pratica non porta a questa condizione poichè è sempre verificata?
Sono confuso :(
Deep

 p[i] in pratica non porta a questa condizione poichč č sempre verificata?
Andrea vuol dire che, dato che in C vero e falso
corrispondono a "diverso da zero" e "uguale a zero",
quindi quando stiamo valutando la verita'
di una espressione, scrivere     p[i]
e scrivere    p[i]!='\0'     sono la stessa cosa.
( perche' il valore di  '\0'  e' zero )
Ricapitolando:
per quanto riguarda la verita' di una espressione,
p[i] != '\0'
p[i] != 0
p[i]
sono equivalenti.
( Ti capitera' anche in questo ambito di leggere
del codice tipo                !var
che corrisponde a           (var == 0)
sempre per lo stesso motivo   )
Ciao
E.

 sempre per lo stesso motivo   )
Si qualcosa del genere mi è capitato :)
Bene bene, siete stati gentilissimi. Grazie ancora!
Deep