----------------------------

                           The C programming's book

                                 Lessons #05

                          ----------------------------


			      PUNTATORI & STRINGHE
	 	 	      --------------------
	
	A differenza delle precedenti lezioni che sono state pubblicate  di
	getto ho deciso di aspettare  un po' prima di rendere  pubblica  la
	quinta lezione al C.Questo per rendermi conto di come andava avanti  
	la cosa, se i miei scritti piacevano o no. Ciò che mi fa piacere  è
	che pare stiano piacendo a molti (non me l'aspettavo neanche io)  e
	quindi , come vedete qui ci sono ancora io a scrivere.In questo file
	affronteremo una panoramica sui puntatori, cosa sono e a cosa servo-
	no. I puntatori sono variabili contenenti un  indirizzo di  memoria. 
	I puntatori non sono un tipo di dato ma vengono suddivisi a seconda 
	del tipo di dato a cui puntano. I puntatori vengono  dichiarati  in 
	modo del tutto analogo alle variabili:

	   tipo *nome_puntatore

	Quindi int ciao è una variabile integer mentre int *ciao è un punta-
	tore a un area di memoria integer. Stessa cosa, per esempio, per char 
	ciao e char *ciao capito? La dichiarazione di puntatori e variabili 
	assieme è sintatticamente valida, quindi:

	   long *punt1,*punt2; //dichiara due puntatori di tipo long

	   int *punt1,*punt2,nomero; //due puntatori e una variabile di tipo int

	   short *punt1,numero,*punt2; //come sopra ma di tipo short

	Tuttavia questa pratica può rivelarsi fastidiosa (soprattutto per i di-
	stratti). Ecco un esempio sull'uso di un puntatore:

	   Char prova; //Dichiaro una variabile char
	   Char *punt; //dichiaro un puntatore char
	   prova='B'; //Assegno alla variabile il valore B
	   punt = &c; //Ora inpunt c'è il contenuto della variabile prova cioè B
	
	Mediante l'operatore & (detto "indirizzo di", o address of) è possibi-
	le, inoltre, conoscere l'indirizzo di una variabile. Ecco un  esempio
	che riassume quanto detto fino ad ora: 
	   
	   float numero = 12.5;
	   float *numPtr = №

       	   printf("numero = %f\n",numero);
       	   printf("numero = %f\n",*numPtr);
           printf("l'indirizzo di numero e' %X\n",&numero);
    	   printf("l'indirizzo di numero e' %X\n",numPtr);
    	   printf("l'indirizzo di numPtr e' %X\n",&numPtr);

	L'output prodotto è il seguente:
	   
	   numero = 12.5
	   numero = 12.5
	   l'indirizzo di numero è FFE6
	   l'indirizzo di numero è FFE6
	   l'indirizzo di numPtr è FFE4

	/*Gli indirizzi me li sono inventati ora*/

	Faccio una nota su printf che c'entra poco con  l' argomento  ma  che
	risulta comunque utile: Per stampare un intero in formato esadecimale 
	si deve inserire nella stringa, invece di %d, %X se si desidera che le 
	cifre A-F siano visualizzate con caratteri maiuscoli, %x se si prefe-
	riscono i caratteri minuscoli. Qui sotto vi pasto un listato  di  un 
	programma che si spiega da solo utile a capire le operazioni effettua-
	bili con i puntatori:


	  #include 
	   main() 
	   {
  	     int k[50];  //array di interi (è un argomento che tratteremo
	                 //più avanti, per vi dico solo che è una variabile
	                 //che contiene altre variabili.
  	     int *punt;
	     punt=&k;	//punt punta all'area di memoria
             //k[0]
   	     punt++;	//punt punta a k[1]
	     punt=punt+5;	//punt punta a k[6]
	     punt--;	//punt punta a k[5]
	     punt=punt-5;	//punt punta a k[0]				
	   }

	Concludendo possiamo dire che i  puntatori  sono, dunque,  strumenti
	appropriati alla manipolazione ad alto livello degli indirizzi delle 
	variabili. Sappiamo (e se non lo sapete ve lo dico ora) che il C non
	gestisce le stringhe di per sè quindi bisogna trovare altri strata-
	gemmi. Uno di questi consiste proprio nell'utilizzo di un puntatore
	come segue:

	  #include 

	   char *stringa = "Hello";

	   void main(void)
	   {
 	      printf(stringa);
    	      printf(" %s!\n",stringa);
	   }

	A questo punto nella vostra testa dovrebbe scattare qualche dubbio:
	da quello che abbiamo vistro fino ad ora stringa è un puntatore  ma
	in questo caso non gli viene assegnato un indirizzo di memoria ma una
	stringa (Hello) ... come è possibile? Niente  di strano.  Infatti a
	*stringa viene assegnato l'indirizzo di memoria della costante Hello
	Dunque *stringa non contiene la parola ciao ma i 16 bit che costi-
	tuiscono l'offset del suo indirizzo.... bello no?
	"Hello" occupa 5 byte ovvero 1 byte per carattere più il quinto che
	viene creato dal compilatore e in cui viene memorizzato il valore 0
	(terminatore  di stringa  o null  terminator). 
	Utilizzando la seguente chiamata a printf:

	       printf("%c è il primo carattere...\n",*stringa);

	Il programma ci restituisce come output il primo valore della stringa
	cioè il carattere char 'C' (una stringa infatti è formata da byte  a
	se stanti: ogni byte un carattere char). Per visualizzare i caratteri
	che seguono  sarà sufficente incrementare  di un valore il  puntatore 
	con i cicli che vedremo più avanti.Infine prelevando i vari caratteri
	è possibile anche cambiarli:

	   char *string = "Rosso\n";

	   void main(void)
	   {
             printf(string);
             *(string+1) = 'u';     //cambia la lettera 'o' con 'u'
             printf(string);        
	     *(string+3) = 'p'      //cambia la lettera 's' con 'p'
	     printf(string);      
	     *(string+4) = 'a'      //cambia la lettera 'o' con 'a' 
	     printf(string);
	     *(string+2) = NULL;    //tronca la stringa dopo la 'o'    
           }

	L'output sarà:

	   Rosso
	   Russo
	   Rospo
	   Rossa

	Per ora basta, è arrivata la pizza, io ho fame e non voglio confonder-
	vi le idee spiegandovi mille argomenti insieme quindi per questa volta
	direi che può bastare. Mi scuso ma solo ora mi rendo conto che questa
	lezione può risultare un po' confusa. Alla prossima (si parlerà di ar-
	ray e stringhe). Bye


                                Written by Shady


                             robcasanovi@virgilio.it

    Source: geocities.com/it/songbook2003

               ( geocities.com/it)