Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoElmo Moroni Modificato 9 anni fa
1
1 FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a.a. 2001-2002 - 4° Ciclo Puntatori e Stringhe
2
2 PUNTATORI Definizione: Per puntatore s’intende una variabile che contiene l’indirizzo di un’altra variabile. Quest’ultima a sua volta può contenere un valore specifico. Rappresentazione grafica: varPoint var 1000 Variabile puntatore, di nome varPoint, contenente l’indirizzo della variabile di nome var Variabile di nome var contenente il valore specifico 1000
3
3 PUNTATORI Dichiarazione di puntatore: Tipo_Variabile …., * Nome_Puntatore, …….. Esempi: int *varPoint; float *latPtr, *longPtr; long *varPtr, var,……; Inizializzazione di un puntatore: Si può inizializzare un puntatore con un puntamento a nessuna variabile in uno dei due seguenti modi. varPoint= NULL; varPoint=0;
4
4 PUNTATORI Operatore di indirizzo &: L’operatore di indirizzo & è un operatore unario che restituisce l’indirizzo del suo operando. L’operando di & deve essere un lvalue, ossia un oggetto a cui si può assegnare un valore. In modo simbolico si può scrivere: Tipo_Variabile …., * Nome_Puntatore, …, Nome_Variabile,..; Nome_Puntatore= &Nome_Variabile; Esempio: int var, *varPtr; varPtr= &var;
5
5 PUNTATORI Operatore * di risoluzione dei riferimenti: L’operatore * di risoluzione dei riferimenti (detto anche di deferenziazione) è un operatore unario su operandi di tipo puntatore che restituisce un alias della variabile puntata. L’alias permette di acquisire il valore della variabile o di assegnargli un nuovo valore. Tipo_Variabile …., * Nome_Puntatore,.. Nome_VarA,.. Nome_VarB; …………….. Nome_Puntatore= &Nome_VarA; …………….. Nome_VarB = * Nome_Puntatore: Esempio: int interoA, interoB, *varPtr; interoA= 10; varPtr= &interoA; interoB= *varPtr; //Assegna il valore di interoA a interoB
6
6 PUNTATORI Associatività Gli operatori & e * associano da destra verso sinistra. Ossia se si considera l’espressione che segue in cui varPtr è un puntatore a cui è stato assegnato l’indirizzo della variabile var &*varPtr tutto va come se si dovesse applicare l’operatore & a ciò che viene restituito da *varPtr. Poiché *varPtr restituisce var, l’applicazione dell’operatore & restituisce l’indirizzo di var. Nel caso inverso: *&varPtr tutto va come se si dovesse applicare l’operatore * a ciò che viene restituito da &varPtr. Poiché &varPtr restituisce l’indirizzo di varPtr, l’applicazione dell’operatore * restituisce il contenuto di varPtr, ossia proprio l’indirizzo di var. Gli operatori & e * sono quindi l’uno l’inverso dell’altro.
7
7 PUNTATORI Chiamata per riferimento con argomenti di tipo puntatore Un puntatore può essere passato come argomento di una chiamata a funzione. In questo caso il prototipo della funzione deve contenere la dichiarazione del puntatore:....Nome_Funzione (…, Tipo_Variabile *, ….); L’invocazione della funzione deve contenere in corrispondenza un puntatore (o un valore di puntatore): Nome_Funzione (…., Nome_Puntatore, ……); L’implementazione della funzione deve contenere in corrispondenza la dichiarazione della variabile puntatore locale: …Nome_Funzione (….., Tipo_Variabile *Nome_Variabile, ….) { ….// Deferenziando Nome_variabile si accede al contenuto della variabile puntata da Nome_Puntatore nell’invocazione della funzione. }
8
8 PUNTATORI Esempio di argomenti di tipo puntatore: void funct (int *);// Prototipo della funzione int var ………… funct (&var);// Invocazione della funzione ……….. void funct (int *localVar)// Implementazione della funzione { ……. *localVar ……..// Accesso al contenuto di var } Nota: questo esempio e le notazioni simboliche della pagina precedente fanno riferimento al caso di un passaggio di puntatore non costante a dati non costanti. In altre parole sia i puntatori che i dati puntati possono essere modificati. Per evitare che il valore di una variabile sia modificato si deve utilizzare il qualificatore const.
9
9 PUNTATORI Utilizzo dell’attributo const: Dichiarazione di puntatore costante a dati non costanti. Tipo_Variabile *const Nome_Puntatore; Dichiarazione di puntatore non costante a dati costanti: const Tipo_Variabile *Nome _Puntatore; Dichiarazione di puntatore costante a dati costanti: const Tipo_Variabile *const Nome _Puntatore; Nota: Le dichiarazioni suddette inserite come dichiarazioni di parametri corrispondenti nel prototipo e nell’implementazione di una funzione permettono di rendere nell’ambito del codice della funzione i puntatori e/o i dati da essi puntati di tipo a sola lettura (read only).
10
10 PUNTATORI Esempio di passaggio di puntatore non costante a dati costanti: void funct (const int *);//Prototipo della funzione int kappa; funct (&kappa);//Invocazione della funzione ……………….. Void funct (const int *varPtr) //Implementazione della funzione { …….. //Non è ammesso fare un’assegnazione del tipo: *varPtr= 100; }
11
11 PUNTATORI Restituzione di una variabile puntatore da una funzione: Una chiamata a funzione può restituire una variabile puntatore. In questo caso il prototipo della funzione deve contenere la dichiarazione del tipo di puntatore in restituzione: Tipo_Variabile *Nome_Funzione (……….); L’invocazione della funzione può quindi essere assegnata ad una variabile puntatore del tipo dichiarato nel prototipo: Tipo_Variabile *Nome_Variabile_Puntatore, ….; Nome_Variabile_Puntatore = Nome_Funzione (……); L’implementazione della funzione deve ripetere la dichiarazione del tipo di puntatore in restituzione (uguale a quella del prototipo) e la parola riservata Return deve essere seguita da un valore o variabile puntatore sempre dello stesso tipo: Tipo_Variabile *Nome_Funzione (………..) {……….return Nome_Variabile_Puntatore; }
12
12 PUNTATORI Esempio di funzione che restituisce un puntatore: ………….. float *Calcola (float, int); //Prototipo ………….. float *retPtr, retCalc; retPtr= Calcola (7.5, 10); //Invocazione …………….. float *Calcola (float datoF, int datoI) //Implementazione {………….. float *localPtr; …………… return localPtr; }
13
13 PUNTATORI Operatore sizeof: L’operatore unario sizeof restituisce la dimensione in byte dell’operando che può essere un array o un dato qualsiasi. L’operando di sizeof deve essere racchiuso tra parentesi tonde se è il nome di un tipo di dato (come int, float,..) altrimenti non è necessario. La seguente operazione:..sizeof Nome_Array/sizeof (Tipo_Dato_Array) restituisce la lunghezza dell’array in elementi.
14
14 PUNTATORI Esempio di applicazione di sizeof: ……………….. int beta [ ]= {10, 20, 30, 40, 50}; int dim; ………………. dim= sizeof beta/sizeof(int);//Assegna il valore 5 a dim ……………….
15
15 PUNTATORI Aritmetica dei puntatori: I casi considerati sono quelli di puntatori ad elementi di array, di tipo qualsiasi, e quindi di lunghezza in byte dipendente dal tipo. Operazione sul puntatore: Incremento (++) Decremento (--) Somma di un intero n Sottrazione di un intero n Indirizzo risultante: Punta all’elemento successivo Punta all’elemento precedente Punta all’elemento dopo n elementi Punta all’elemento precedente di n elementi Si possono anche fare differenze tra puntatori, purché dello stesso array e, in tal caso, il risultato è un numero intero corrispondente alla distanza tra i due puntatori in numero di elementi dell’array.
16
16 PUNTATORI Assegnazione tra puntatori: Si può assegnare un puntatore ad un altro dello stesso tipo o, in generale, usando l’operatore cast, ad un altro di tipo diverso. Puntatore di tipo void Tutti i tipi di puntatore possono essere assegnati ad un puntatore di tipo void (void *), che è un tipo generico, ma non è vero il contrario. Un puntatore di tipo void non può nemmeno essere deferenziato Puntatori ed operatori relazionari Gli operatori relazionari possono essere utilizzati per confrontare i puntatori, ma ciò ha normalmente senso per puntatori ad elementi di uno stesso array.
17
17 PUNTATORI Correlazione tra puntatori e array La dichiarazione di un array, come la seguente: Tipo_Variabile …., Nome_Array [Dimensione_Array], … comporta la dichiarazione di un puntatore costante al primo elemento dell’array di nome Nome_Array. In base a ciò l’accesso ad un elemento dell’array può ottenersi con uno dei seguenti modi: Indicizzazione dell’array: Nome_Array [Variabile _Indice] Nome dell’array e offset: *(Nome_Array + Variabile_Indice) Indicizzazione di puntatore: Puntatore_1°_Elemento [Variabile_Indice] Puntatore e offset: *(Puntatore _1°_Elemento + Variabile_Indice)
18
18 PUNTATORI Esempi di modi di accesso ad un array: float floatArray [10], *floatPtr, floatVar; int index; floatPtr= floatArray; //Equivalente a: floatPtr= &floatArray[0]; index= 5; floatVar= floatArray [index]; floatVar= floatArray [5]; floatVar= *(floatArray + index); floatVar= floatPtr [index]; floatVar= *(floatPtr + index);
19
19 PUNTATORI Puntatori a Funzioni Una funzione può accettare in input un puntatore ad un’altra funzione. Ciò è possibile perché il nome di una funzione è un puntatore alla funzione stessa. Il prototipo assume l’aspetto: …. Nome _Funzione_A (…, Tipo_Restituito (*) (Lista_Tipi), ….); La corrispondente invocazione di funzione è: Nome_Funzione_A (…., Nome_Funzione_B, ……..); dove Nome_Funzione_B deve corrispondere ad una funzione che ha il Tipo_Restituito e la Lista_Tipi identici a quelli indicati nel prototipo: possono esistere più funzioni con queste caratteristiche. L’implementazione è infine:..Nome_Funzione_A (.., Tipo_Restituito(*Nome_Funzione_Locale) (Lista_Tipi), …..) { …….(*Nome_Funzione_Locale) (Lista_Argomenti);…….. }
20
20 PUNTATORI Esempio di passaggio di puntatore a funzione: void funzA (int, int, int (*)(float, int), float); //Prototipo della funzione int funzB (float, int); //Prototipi delle funzioni che possono essere int funzC (float, int); //passate come parametri con il loro puntatore ……………………….. funzA (3, 5, funzC, 3.5) //Invocazione della funzione ……………………….. //Implementazione della funzione: funzA (int var1, int var2, int (*localFunz) (float, int), float var3) { ………//Invocazione della funzione passata con un puntatore: (*localFunz) (var3, 6); ………………... }
21
21 STRINGHE Costanti carattere: Una costante carattere è un carattere racchiuso tra apici singoli e corrisponde ad un numero intero che è il codice ASCII di quel carattere. Sono costanti carattere: ‘a’, ‘b’, …’z’, ‘\n’. Quest’ultimo è il valore intero di new line. Costanti stringa: Una costante stringa è una sequenza di caratteri racchiusi tra doppi apici che vengono trattati come un’entità singola. Una costante stringa è: “abcde”. Stringhe: Una stringa è un array di caratteri che termina con il carattere nullo (‘\0’). Il valore di una stringa è quindi l’indirizzo costante del suo primo carattere.
22
22 STRINGHE Dichiarazione ed inizializzazione di una stringa: In base alla definizione di stringa la sua dichiarazione ed inizializzazione si può ottenere come segue: char Nome_Stringa [ ]= {‘a’, ‘b’, ‘c’, … ‘z’, ‘\0’}; oppure, ricorrendo alle costanti stringa, nel modo seguente: char Nome_Stringa[ ]= “abcd…z”; in questo caso l’array di caratteri che compone la stringa conterrà un ultimo carattere in più, rispetto a quelli della costante stringa, automaticamente impostato a: ‘\0’. Una stringa può anche essere inizializzata senza assegnargli un nome, ma dichiarando solo il puntatore al suo primo carattere con la dichiarazione: char *Puntatore_alla_Stringa= “abcd….z”;
23
23 STRINGHE Input di stringhe: L’input di una stringa in un array di caratteri si può ottenere con l’operatore di estrazione dallo stream e cin nel modo seguente: char Nome_Array [Dimensione_Array]; //Dichiarazione array cin >> Nome_Array; //Input stringa L’input termina alla digitazione di: spazio, tabulazione, new line o end of file. Non c’è controllo al superamento dell’ultimo posto dell’array. Ciò si può invece ottenere con l’operatore setw, che termina l’input dopo il carattere del penultimo posto e pone ‘\0’ nell’ultimo: cin >> setw(Dimensione_Array) >> Nome_Array; L’input di righe di testo complete si ottiene con la funzione: cin.getline (Nome_Array, Dimensione_Array, \n); per la quale l’input termina se si riempie il penultimo posto dell’array (nell’ultimo si pone: ‘\0’), oppure si digita new line o end of file.
24
24 STRINGHE Funzioni di libreria per le stringhe Quelli che seguono sono i prototipi di funzioni di libreria che manipolano stringhe, confrontano stringhe, ricercano caratteri, segmentano stringhe, ne determinano la lunghezza,.. ecc. char *strcpy (char *s1, const char *s2); char *strcat (char *s1, const char *s2); char *strncpy (char *s1, const char *s2, size_t n); char *strncat (char *s1, const char *s2, size_t n); int strcmp (const char *s1, const char *s2); int strncmp (const char *s1, const char *s2, size_t n); char *strtok (char *s1, const char *s2); size_t strlen (const char *s):
25
25 RICHIAMI AI RIFERIMENTI Chiamata a funzione con argomenti di tipo riferimento: Un riferimento può essere passato come argomento di una chiamata a funzione. In questo caso il prototipo della funzione deve contenere la dichiarazione del riferimento: ….. Nome_Funzione (…., Tipo_Variabile &, …); L’invocazione della funzione deve contenere in corrispondenza un nome di variabile che in tal caso viene passata per riferimento (ossia potrà essere direttamente riferita) invece che per valore: …… Nome_Funzione (….., Nome_Variabile, …); L’implementazione della funzione deve contenere in corrispondenza la dichiarazione del riferimento locale che si comporta come alias della variabile passata: … Nome_Funzione (…., Tipo_Variabile &Nome_Locale_Variabile, …) {…….//Attraverso il Nome_Locale_Variabile si accede direttamente in lettura/scrittura alla variabile passata nell’invocazione della funzione ……..}
26
26 RICHIAMI AI RIFERIMENTI Esempio di argomento di tipo riferimento: void funct (int &);// Prototipo della funzione int var; ………… funct (var);// Invocazione della funzione ……….. void funct (int &localVar)// Implementazione della funzione { ……. localVar = 10;// Accesso al contenuto di var }
27
27 RICHIAMI AI RIFERIMENTI Restituzione di un riferimento da una funzione: Una chiamata a funzione può restituire un riferimento al un alias. In questo caso il prototipo della funzione deve contenere la dichiarazione del tipo di riferimento in restituzione: Tipo_Variabile &Nome_Funzione (……); L’invocazione della funzione può quindi essere assegnata ad una variabile riferimento del tipo dichiarato nel prototipo: Tipo_Variabile ……., &Nome_Variabile,..; Nome_Variabile = Nome_funzione (……..); L’implementazione della funzione deve ripetere la dichiarazione del tipo di riferimento in restituzione (uguale a quella del prototipo) e la parola riservata return deve essere seguita dal nome di una variabile, sempre dello stesso tipo: Tipo_variabile &Nome_Funzione (……….) {…….. return Nome_Variabile; }
28
28 RICHIAMI AI RIFERIMENTI Esempio di funzione che restituisce un riferimento: ………….. float &Calcola (float, int); //Prototipo ………….. float &retCalc; retCalc= Calcola (7.5, 10); //Invocazione retCalc= 10; //Accesso a localVar ! …………….. float &Calcola (float datoF, int datoI) //Implementazione {………….. float localVar; …………… return localVar; }
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.