FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a a
- Slides: 28
FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a. a. 2001 -2002 - 4° Ciclo Puntatori e Stringhe 1
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: var. Point var 1000 Variabile puntatore, di nome var. Point, contenente l’indirizzo della variabile di nome var Variabile di nome var contenente il valore specifico 1000 2
PUNTATORI Dichiarazione di puntatore: Tipo_Variabile …. , * Nome_Puntatore, ……. . Esempi: int *var. Point; float *lat. Ptr, *long. Ptr; long *var. Ptr, var, ……; Inizializzazione di un puntatore: Si può inizializzare un puntatore con un puntamento a nessuna variabile in uno dei due seguenti modi. var. Point= NULL; var. Point=0; 3
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, *var. Ptr; var. Ptr= &var; 4
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_Var. A, . . Nome_Var. B; ……………. . Nome_Puntatore= &Nome_Var. A; ……………. . Nome_Var. B = * Nome_Puntatore: Esempio: intero. A, intero. B , *var. Ptr; intero. A= 10; var. Ptr= &intero. A; intero. B= *var. Ptr; //Assegna il valore di intero. A a intero. B 5
PUNTATORI Associatività Gli operatori & e * associano da destra verso sinistra. Ossia se si considera l’espressione che segue in cui var. Ptr è un puntatore a cui è stato assegnato l’indirizzo della variabile var &*var. Ptr tutto va come se si dovesse applicare l’operatore & a ciò che viene restituito da *var. Ptr. Poiché *var. Ptr restituisce var, l’applicazione dell’operatore & restituisce l’indirizzo di var. Nel caso inverso: *&var. Ptr tutto va come se si dovesse applicare l’operatore * a ciò che viene restituito da &var. Ptr. Poiché &var. Ptr restituisce l’indirizzo di var. Ptr, l’applicazione dell’operatore * restituisce il contenuto di var. Ptr, ossia proprio l’indirizzo di var. Gli operatori & e * sono quindi l’uno l’inverso dell’altro. 6
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. } 7
PUNTATORI Esempio di argomenti di tipo puntatore: void funct (int *); // Prototipo della funzione int var ………… funct (&var); // Invocazione della funzione ………. . void funct (int *local. Var) // Implementazione della funzione { ……. *local. Var ……. . // 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. 8
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). 9
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 *var. Ptr) //Implementazione della funzione { ……. . //Non è ammesso fare un’assegnazione del tipo: *var. Ptr= 100; } 10
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; } 11
PUNTATORI Esempio di funzione che restituisce un puntatore: …………. . float *Calcola (float, int); //Prototipo …………. . float *ret. Ptr, ret. Calc; ret. Ptr= Calcola (7. 5, 10); //Invocazione ……………. . float *Calcola (float dato. F, int dato. I) //Implementazione {…………. . float *local. Ptr; …………… return local. Ptr; } 12
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. 13
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 ………………. 14
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: Indirizzo risultante: Incremento (++) Punta all’elemento successivo Decremento (--) Punta all’elemento precedente Somma di un intero n Punta all’elemento dopo n elementi Sottrazione di un intero n 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. 15
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. 16
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) 17
PUNTATORI Esempi di modi di accesso ad un array: float. Array [10], *float. Ptr, float. Var; int index; float. Ptr= float. Array; //Equivalente a: float. Ptr= &float. Array[0]; index= 5; float. Var= float. Array [index]; float. Var= float. Array [5]; float. Var= *(float. Array + index); float. Var= float. Ptr [index]; float. Var= *(float. Ptr + index); 18
Puntatori a Funzioni PUNTATORI 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); ……. . } 19
PUNTATORI Esempio di passaggio di puntatore a funzione: void funz. A (int, int (*)(float, int), float); //Prototipo della funzione int funz. B (float, int); //Prototipi delle funzioni che possono essere int funz. C (float, int); //passate come parametri con il loro puntatore ……………. . funz. A (3, 5, funz. C, 3. 5) //Invocazione della funzione ……………. . //Implementazione della funzione: funz. A (int var 1, int var 2, int (*local. Funz) (float, int), float var 3) { ………//Invocazione della funzione passata con un puntatore: (*local. Funz) (var 3, 6); ………………. . . } 20
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 (‘ ’). Il valore di una stringa è quindi l’indirizzo costante del suo primo carattere. 21
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’, ‘ ’}; 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: ‘ ’. 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”; 22
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 ‘ ’ 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: ‘ ’), oppure si digita new line o end of file. 23
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 *s 1, const char *s 2); char *strcat (char *s 1, const char *s 2); char *strncpy (char *s 1, const char *s 2, size_t n); char *strncat (char *s 1, const char *s 2 , size_t n); int strcmp (const char *s 1, const char *s 2); int strncmp (const char *s 1, const char *s 2 , size_t n); char *strtok (char *s 1, const char *s 2); size_t strlen (const char *s): 24
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 ……. . } 25
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 &local. Var) // Implementazione della funzione { ……. local. Var = 10; // Accesso al contenuto di var } 26
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; } 27
RICHIAMI AI RIFERIMENTI Esempio di funzione che restituisce un riferimento: …………. . float &Calcola (float, int); //Prototipo …………. . float &ret. Calc; ret. Calc= Calcola (7. 5, 10); //Invocazione ret. Calc= 10; //Accesso a local. Var ! ……………. . float &Calcola (float dato. F, int dato. I) //Implementazione {…………. . float local. Var; …………… return local. Var; } 28
- Unisi ingegneria gestionale
- Ingegneria gestionale parthenope
- Giovanni danese unipv
- Fondamenti di informatica 2
- Fondamenti di informatica 2
- Ingegneria informatica pisa
- Ingegneria dell'informazione informatica e statistica
- I fondamenti dell'ict
- Kupido gestionale
- Il naturalismo francese i fondamenti teorici
- Fondamenti di astronomia
- Acnp gestionale
- Sifead raccolta dati 2020
- Fondamenti di automatica unife
- Impedenzimetro
- Gestionale
- Genotipo
- Gestionale open fattura elettronica
- Fondamenti di automatica benvenuti
- Crisi dei fondamenti
- Fondamenti di sociologia giddens
- Gestionale di cura
- Gestionale produzione calzature
- Metodo embyon
- Pedagogia generale slide
- Chimica organica
- Gat gestionale
- Spinte metallostatiche
- Scienza e ingegneria dei materiali callister