Newsgroup: it.comp.lang.c
Titolo: Piccola spiegazione...

Ciao a tutti, da poco a scuola abbiamo iniziato i puntatori e le
funzioni....
Ho capito la logica dei puntatori, ma mi potreste fare un esempio banale di
un programma basato sui puntatori?
Se ho capito bene utilizzando un puntatore si puo' agire sul valore di una
variabile senza richiamarla esplicitamente...Pero' non riesco a trovare un
utilizzo;-))))
Anche se in un programma mi richiedeva, dopo la compilazione, l'utilizzo di
un puntatore associato ad una funzione, percio' mi chiedo: Funzioni e
Puntatori si utilizzano insieme?
Grazie in anticipo e scusate per l'eventuale domanda stupida=))))
--
 Byez By Roby "Offear" '82
 Visit my personal Home-Page:  
http://surf.to/HPOffear
 And Sign My Guestbook!
 Coming Soon: 
http://surf.to/Blindguardian

 Grazie in anticipo e scusate per l'eventuale domanda stupida=))))
Non credo esistano domande stupide, al massimo esistono le FAQ.
--
Alessandro Monti

 Grazie in anticipo e scusate per l'eventuale domanda stupida=))))
No problem.
Dai un occhiata al codice seguente:
---
typedef struct
{
  int uno;
  int due;
  int tre;
  char *testo1;
  char *testo2;
} STRUTTURA_INCASINATA;
void funz (STRUTTURA_INCASINARA x)
{
  printf ("%d", x.uno);
  printf ("%s", x.testo1);
}
int main ()
{
  STRUTTURA_INCASINATA s;
  funz (s);
}
---
che succede? in pratica "main()" richiama "funz()" passandogli la
struttura come argomento. Ammettiamo che in un programma la funzione
"funz()" debba venir richiamata un migliaio di volte: cosa succede?
Quando si passa un parametro ad una funzione si deve copiare il
parametro stesso da una locazione di memoria ad un'altra (lo so che non
è esatto, ma il concetto è questo). Se devo passargli tutta la
struttura, anche se a livello di singola chiamata non noto la
differenza, rallenterà l'esecuzione del programma finale
considerevolmente (ricorda: il programma finale esegue la chiamata
migliaia di volte). Una soluzione consiste nel passare non la struttura
ma il puntatore ad essa. In pratica è come se anzichè dire alla funzione
"esegui certe operazioni su QUESTA struttura", gli dicessi "esegui certe
operazioni sulla struttura che trovi a...". Il programma diventa:
---
typedef struct
{
  int uno;
  int due;
  int tre;
  char *testo1;
  char *testo2;
} STRUTTURA_INCASINATA;
void funz (STRUTTURA_INCASINARA *x)
{
  printf ("%d", x->uno);
  printf ("%s", x->testo1);
}
int main ()
{
  STRUTTURA_INCASINATA *s;
  s = malloc (sizeof (STRUTTURA_INCASINATA));
/* Alloca la memoria per la struttura! Se non sai a cosa serve, non ti
preoccupare: non è importante al fine di capire lo scopo dei puntatori
*/
  funz (s);
}
---
Questo naturalmente è solo uno dei molti usi dei puntatori. Vedrai che
affronterai problemi via via più complessi, in cui essi si riveleranno
molto utili. Classico esempio per aiutarti a capire come un programma si
può evolvere è quello della calcolatrice. Un programmatore, all'inizio
dei suoi studi, decide di imparare un linguaggio di programmazione, e
per imparare la sintassi di base crea un semplice programma che calcola
"2+2" e ne stampa il risultato sullo schermo. Non soddisfatto, decide di
ampliare il programma in modo che esegua la somma di due addendi
specificati dall'utente. In seguito, fa specificare all'utente anche
l'operazione da eseguire fra le quattro di base. Poi decide che due
numeri non sono sufficienti, e quindi rende il suo programma capace di
accettare un numero indefinito di numeri, specificando di volta in volta
l'operazione da eseguire.
Così, man mano che il programma si "generalizza", sono necessarie
strutture sempre più complesse per l'immagazzinamento ed il trattamento
dei dati. E non c'è nulla di più generale di un puntatore, in quanto,
oltre a puntatori a "tipi" semplici (int, char) e a strutture, è
possibile definire puntatori a "void" che sono diciamo l'apice
dell'incertezza: a cosa puntano? Non lo sanno nemmeno loro! Devi
specificarlo tu ogni volta. Ma questa, naturalmente, è un'altra storia.
Per ora puoi dormire sonni tranquilli senza temere simili "mostruosità".
: )
Ciao!
-- 
+ ICEMAZE +
ice...@planet.it
"Hail! Hail and kick!"

int main (int argc, char **argv[]){
E' sbagliato :
o 
int main( int argc, char **argv) 
o 
int main( int argc, char *argv[]) ;
--------------------------------------------------------
* Andrea Laforgia        (
andrea_...@bigfoot.com
) *
--------------------------------------------------------

> E' sbagliato :
Hai ragione. A volte l'indecisione sulla forma da adottare le fa usare
entrambe.
Usando **argc avevo paura di essere bastonato :)
--
Alessandro Monti

Usando **argc avevo paura di essere bastonato :)
In realta' credo (ma sottolineo *credo*) che venga preferita : non
capisco il perche'... ;)


 capisco il perche'... ;)
Molto tempo fa dissi che mi sembrava che la forma con le parentesi
quadre venisse sconsigliata. Allora non ricordavo dove lo avessi letto e
oggi non lo ricordo ancora. Non è che qualcuno ne sa qualcosa di più?
EMG

 wrote:
~Se ho capito bene utilizzando un puntatore si puo' agire sul valore di una
~variabile senza richiamarla esplicitamente...Pero' non riesco a trovare un
~utilizzo;-))))
un esempio banale: hai bisogno che una funzione ritorni 2 valori...
mica puoi' scrivere
(a,b)=funzione_che_ritorna_2_valori(parametro1, parametro2);
!
ma ricorri ai puntatori, e la funzione_che_ecc_ecc tramite questi ti
modifica "a" e "b"
ciao
fritz