il linguaggio c puntatori - moreno.marzolla.name · linguaggio c - puntatori 3 ringraziamenti...
TRANSCRIPT
![Page 1: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/1.jpg)
Il linguaggio CIl linguaggio CPuntatoriPuntatori
Moreno MarzollaDipartimento di Informatica—Scienza e Ingegneria (DISI)
Università di Bolognahttp://www.moreno.marzolla.name/
![Page 2: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/2.jpg)
Linguaggio C - puntatori 2
Copyright © Mirko ViroliCopyright © 2016–2018 Moreno Marzollahttp://www.moreno.marzolla.name/teaching/FINFA/
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA.
![Page 3: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/3.jpg)
Linguaggio C - puntatori 3
Ringraziamenti
● Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna
![Page 4: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/4.jpg)
Linguaggio C - puntatori 4
Dichiarazioni di array e matrici
int x[4]={11,12}; /* OK, {11,12,0,0} */int y[4]; /* OK, {?,?,?,?} */int z[] = {3, 5}; /* OK, lunghezza 2 */int m[3][2]={{11,12},{21,22},{31,32}}; /* OK */int k[3][2]={{11}, {21, 22}}; /* OK, {{11,0},{21,22},{0,0}} */int n[3][2]; /* OK, {{?,?},{?,?},{?,?}} */int p[][] = {{1,2}, {4,5}}; /* ERRORE */int q[][2] = {{1,2}, {4,5}}; /* OK */
![Page 5: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/5.jpg)
Linguaggio C - puntatori 5
Come sono rappresentati gli array in C?
● Consideriamo int a[] = {11, -7, 3, 22}● Supponiamo che un intero occupi 4 byte
– Cioè sizeof(int) == 4● Supponiamo che il primo elemento di a[] sia
memorizzato a partire dall'indirizzo di memoria 1000
11 -7 3 22
1000 1004 1008 1012
a[0] a[1] a[2] a[3]
Indirizzo di memoria
![Page 6: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/6.jpg)
Linguaggio C - puntatori 6
In generale
● Dato un array a[N] di valori di tipo T● Supponiamo che sizeof(T)= k● Sia Mem(a[i]) l'indirizzo di memoria a partire dal
quale è memorizzato il valore a[i]● Allora, per ogni 0 ≤ i < N si ha:
Mem(a[i]) = Mem(a[0]) + i k
11 -7 3 22
1000 1004 1008 1012
a[0] a[1] a[2] a[3]
![Page 7: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/7.jpg)
Linguaggio C - puntatori 7
Array multidimensionali
● In C le matrici sono memorizzate "per righe"– Cioè le righe della matrice sono memorizzate in posizioni
contigue della memoria
int m[4][3]
m[0][0] m[1][0] m[2][0] m[3][0]
![Page 8: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/8.jpg)
Linguaggio C - puntatori 8
Array multidimensionali
● Consideriamo int v[3][2]={{11,12},{21,22},{31,32}}
● Supponiamo che v[0][0] sia memorizzato a partire dall'indirizzo di memoria 1000
● Supponiamo che sizeof(int) == 4
11 12 21 22
1000 1004 1008 1012
v[0][0]
31 32
1016 1020
v[1][0] v[2][0]
v[0][1] v[1][1] v[2][1]
... ...
![Page 9: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/9.jpg)
Linguaggio C - puntatori 9
In generale
● Data una matrice m[R][C] di valori di tipo T● Supponiamo che sizeof(T)= k● Sia Mem(m[i][j]) l'indirizzo di memoria a partire dal
quale è memorizzato il valore m[i][j]● Allora, per ogni 0 ≤ i < R, 0 ≤ j < C si ha:
Mem(m[i][j]) = Mem(m[0][0]) + (i C + j) k
![Page 10: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/10.jpg)
Linguaggio C - puntatori 10
Domanda
● Supponiamo che sizeof(double) == 8● Dato un array double a[10]
– Supponiamo che a[0] sia memorizzato a partire dall'indirizzo di memoria 2048
– A partire da quale indirizzo di memoria si trova a[5]?
● Dato un array double m[3][7]– Supponiamo che m[0][0] sia memorizzato a partire
dall'indirizzo di memoria 4096– A partire da quale indirizzo di memoria si trova m[2][4] ?
![Page 11: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/11.jpg)
Linguaggio C - puntatori 11
Stringhe (sequenze di caratteri) in C
● La notazione "prova di stringa" è convertita dal compilatore in un array di char che termina col carattere speciale '\0', il cui valore è 0– Quindi "prova di stringa" occupa 17 byte di memoria:
16 per i caratteri + 1 per il terminatore● È possibile calcolare la lunghezza di una stringa
contando quanti caratteri ci sono prima del '\0'
![Page 12: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/12.jpg)
Linguaggio C - puntatori 12
Esempio stringhe/* es-stringhe.c */#include <stdio.h>
int main( void ) {
char s1[6] = "Prova"; /* Ok, il compilatore alloca 6 elementi */ char s2[] = "Prova"; /* Ok, il compilatore alloca 6 elementi */char s3[] = {'P','r','o','v','a','\0'};printf("Stampa diretta di s2 e s3 : %s, %s\n", s2, s3);printf("Elementi di s2: %c %c %c %c %c %c\n",
s2[0], s2[1], s2[2], s2[3], s2[4], s2[5]);printf("Codici ASCII di s3: %d %d %d %d %d %d\n",
s3[0], s3[1], s3[2], s3[3], s3[4], s3[5]);return 0;
}
Stampa diretta di s2 e s3 : Prova, Prova
Elementi di s2: P r o v a
Codici ASCII di s3: 80 114 111 118 97 0
![Page 13: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/13.jpg)
Linguaggio C - puntatori 13
Lunghezza di una stringa/* lunghezza-stringa.c */#include <stdio.h>
int lunghezza(char c[]){
int i;for (i=0; c[i]!=0; i++) ; /* Corpo vuoto */return i;
}
int main(void) {
char s1[] = "Prova";char s2[] = {'P','r','o','v','a','\0'};printf("Lunghezza di s1: %d\n", lunghezza(s1));printf("Lunghezza di s2: %d\n", lunghezza(s2));return 0;
}
Lunghezza di s1: 5
Lunghezza di s2: 5
![Page 14: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/14.jpg)
Linguaggio C - puntatori 14
Lunghezza di una stringa
/* es-strlen.c */#include <stdio.h>#include <string.h>
int main(void) {
char s[] = "Prova";printf("Lunghezza di s: %d\n", (int)strlen(s));return 0;
}
● Esiste una funzione predefinita strlen(s) che restituisce la lunghezza di s– È necessario includere string.h– Restituisce un size_t, che va convertito in int per poter
essere stampato con la stringa di formato %d
![Page 15: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/15.jpg)
Linguaggio C - puntatori 16
Puntatori: dichiarazione
● Un puntatore è una variabile che contiene un indirizzo di memoria in cui è presente un valore di un certo tipo
● Dichiarazione:– int *x; dichiara una variabile x contenente l'indirizzo di
memoria di un valore di tipo int– Il tipo di x è “puntatore a intero”
● Attenzione:– int *x, *y;
dichiara due variabili x e y di tipo "puntatore a intero"– int *x, y;
dichiara una variabile x di tipo "puntatore a intero", e una variabile y di tipo "intero" (NON puntatore)
![Page 16: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/16.jpg)
Linguaggio C - puntatori 17
Operatore & (riferimento)
● Operatore unario applicabile a variabili– restituisce l'indirizzo della cella di memoria in cui è memorizzata
quella variabile ● Se v è una variabile di tipo T, &v ha tipo “puntatore a T”
/* punt.c */#include <stdio.h>int main(void){ int i=5; double d=1.5; int a[5]; int *pi = &i; /* E' un puntatore alla variabile i */ double *pd = &d; /* E' un puntatore alla variabile d */ int *pa4 = &a[4]; /* E' un puntatore al quinto elemento di a[] */ printf("%p\n", (void*)pi); return 0;} 0x7ffc68e726d8
![Page 17: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/17.jpg)
Linguaggio C - puntatori 18
Esempio
/* punt.c */#include <stdio.h>int main(void){ int i=5; double d=1.5; int a[5]; int *pi = &i; double *pd = &d; int *pa4 = &a[4]; printf("%p\n", (void*)pi); return 0;}
5
1.5
??
??
??
??
??
i
d
a[0]
a[1]
a[2]
a[3]
a[4]
2048pi
2052
2076
pd
pa4
2048
2052
2060
2064
2068
2072
2076
2080
2084
2088
Indirizzidi mem.
Assumiamo che:●un int occupi 4 byte●un double occupi 8 byte●un puntatore occupi 4 byteDomanda: quale è la dimensione massima della memoria utilizzabile?
Non necessariamente le variabili i, d, pi, pd, pa4 e a[] sono adiacenti in memoria; gli elementi di a[] sono invece garantiti essere adiacenti
2056
![Page 18: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/18.jpg)
Linguaggio C - puntatori 19
Operatore di deriferimento *
● Detto anche operatore di indirezione– dato un puntatore, l'operatore unario * restituisce il valore
della variabile "puntata" dal puntatore
int main(void){ int v = 5; int *p = &v; /* p punta alla variabile v */ int w = *p; /* w ha valore 5 */ *p = *p + 1; /* v diventa 6 */ return 0;}
![Page 19: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/19.jpg)
Linguaggio C - puntatori 20
Operatore di deriferimento *
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 20: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/20.jpg)
Linguaggio C - puntatori 21
5
10
i
j
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 21: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/21.jpg)
Linguaggio C - puntatori 22
5
10
i
j
v
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 22: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/22.jpg)
Linguaggio C - puntatori 23
5
10
i
j
v
w ?
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 23: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/23.jpg)
Linguaggio C - puntatori 24
5
10
i
j
v
w
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 24: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/24.jpg)
Linguaggio C - puntatori 25
5
4
i
j
v
w
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 25: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/25.jpg)
Linguaggio C - puntatori 26
5
5
i
j
v
w
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 26: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/26.jpg)
Linguaggio C - puntatori 27
5
5
i
j
v
w
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 27: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/27.jpg)
Linguaggio C - puntatori 28
7
5
i
j
v
w
/* punt2.c */#include <stdio.h>
int main(void){ int i = 5, j = 10; int *v = &i; /* v punta alla variabile i */ int *w; /* w ha contenuto indefinito */ w = &j; /* w punta alla variabile j */ *w = 4; /* j viene modificato in 4 */ *w = *v; /* j viene modificato in 5, come i */ w = v; /* w punta a dove punta v, ossia i */ *w = 7; /* ora i vale 7 */ printf("i=%d, j=%d, *w=%d, *v=%d\n", i, j, *w, *v); return 0;}
![Page 28: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/28.jpg)
Linguaggio C - puntatori 29
Esempio con gli array
int main(void){ int a[] = {11, 7}; int *w = &a[1]; /* w punta al secondo elemento dell'array */ int i = *w; /* i viene assegnato a 7 */ *w = 0; /* il secondo elem. dell'array viene posto a 0 */ return 0;}
![Page 29: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/29.jpg)
Linguaggio C - puntatori 30
11
7
a[0]
a[1]
int main(void){ int a[] = {11, 7}; int *w = &a[1]; /* w punta al secondo elemento dell'array */ int i = *w; /* i viene assegnato a 7 */ *w = 0; /* il secondo elem. dell'array viene posto a 0 */ return 0;}
Esempio con gli array
![Page 30: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/30.jpg)
Linguaggio C - puntatori 31
11
7
a[0]
a[1]
w
int main(void){ int a[] = {11, 7}; int *w = &a[1]; /* w punta al secondo elemento dell'array */ int i = *w; /* i viene assegnato a 7 */ *w = 0; /* il secondo elem. dell'array viene posto a 0 */ return 0;}
Esempio con gli array
![Page 31: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/31.jpg)
Linguaggio C - puntatori 32
11
7
a[0]
a[1]
w
7i
int main(void){ int a[] = {11, 7}; int *w = &a[1]; /* w punta al secondo elemento dell'array */ int i = *w; /* i viene assegnato a 7 */ *w = 0; /* il secondo elem. dell'array viene posto a 0 */ return 0;}
Esempio con gli array
![Page 32: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/32.jpg)
Linguaggio C - puntatori 33
11
0
a[0]
a[1]
w
7i
int main(void){ int a[] = {11, 7}; int *w = &a[1]; /* w punta al secondo elemento dell'array */ int i = *w; /* i viene assegnato a 7 */ *w = 0; /* il secondo elem. dell'array viene posto a 0 */ return 0;}
Esempio con gli array
![Page 33: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/33.jpg)
Linguaggio C - puntatori 34
Puntatori: inizializzazione
● L'header file stddef.h definisce il simbolo NULL che può essere usato per denotare un indirizzo di memoria "non valido"– Può quindi essere usato come valore iniziale di un
puntatore, se necessario● stddef.h viene incluso indirettamente anche da altri
header (es., stdio.h), quindi potrebbe non essere necessario includerlo esplicitamente
![Page 34: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/34.jpg)
Linguaggio C - puntatori 35
/* null-ptr.c : esempio di uso di NULL */#include <stdio.h>#include <stddef.h>
int main( void ){
int a = 10, *ptr_a = NULL;ptr_a = &a;if ( ptr_a == NULL ) {
printf("ptr_a non valido\n");} else {
printf("ptr_a punta a %p che contiene il valore %d\n", (void*)ptr_a, *ptr_a);
}return 0;
}
ptr_a punta a 0x7ffe4439c7d4 che contiene il valore 10
Esempio
Può essere omesso, perché in gcc viene già incluso
indirettamente da stdio.h
![Page 35: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/35.jpg)
Linguaggio C - puntatori 36
Input da tastiera
● La funzione scanf, duale a printf, viene usata per ricevere input da tastiera e assegnarne il valore ad una variabile– bisogna passargli il puntatore alla variabile dove si vuole
venga memorizzato il risultato
#include <stdio.h>
int main(void) { int x; float f; printf("Inserisci un intero: "); scanf("%d",&x); printf("Inserisci un float: "); scanf("%f",&f); printf("x=%d, f=%f, prodotto=%f\n", x, f, x*f); return 0;}
![Page 36: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/36.jpg)
Linguaggio C - puntatori 37
Input di stringhe
● Le stringhe andranno depositate in un array di caratteri – scanf vuole l'indicazione %s o %Ns– come secondo argomento mettere l'array
#include <stdio.h>
int main(void){ char str1[11], str2[11]; printf("Inserisci una stringa: "); scanf("%s", str1); /* non usare &str1 !!! */ printf("Inserisci una stringa di non più di 10 caratteri: "); scanf("%10s", str2); /* nota: char str2[11] per includere il \0 finale */ printf("str1: %s\n", str1); printf("str2: %s\n", str2); return 0;}
![Page 37: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/37.jpg)
Linguaggio C - puntatori 39
Array e puntatori
● Un array di T si comporta come un puntatore– Se a è una variabile dichiarata come T a[N] (array di T)...– ...l'espressione a (senza indici) ha tipo T* (puntatore a T) e ha come
valore l'indirizzo di memoria di a[0]● Un puntatore può essere "indicizzato" come se fosse un array
– Se v è dichiarata come T *v (puntatore a T) e valore un indirizzo di memoria M...
– ...allora l'espressione v+k (k intero) ha tipo "puntatore a T" e contiene l'indirizzo di memoria
M + k sizeof(T)
– ...e l'espressione v[k] (k intero) ha tipo T e valore pari a quello memorizzato a partire dall'indirizzo M + k sizeof(T)
![Page 38: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/38.jpg)
Linguaggio C - puntatori 40
Aritmetica dei puntatori
/* arit-punt.c */#include <stdio.h>
int main(void){ int a[] = {15, 16, 17}; int *p, *q; p = a; /* Ok, e' come scrivere p = &a[0] */ *p = -1; /* ora l'array a[] vale {-1, 16, 17} */ q = p + 1; /* q contiene l'indirizzo di a[1] */ q++; /* q contiene l'indirizzo di a[2] */ *q = -3; /* ora l'array a[] vale {-1, 16, -3} */ *(p+1) = 2; /* ora l'array a[] vale {-1, 2, -3} */ printf("%d %d %d\n", a[0], a[1], a[2]); printf("%d\n", *(p+2)); return 0;}
![Page 39: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/39.jpg)
Linguaggio C - puntatori 41
Attenzione
● Se p è una variabile di tipo puntatore, allora in genere*(p+1) ≠ *p + 1
● Esempio: cosa stampa il programma seguente?
/* arit-punt2.c */#include <stdio.h>
int main(void){ int a[] = {1, 21, -3}; int *p = a; printf("%d\n", *(p+1)); printf("%d\n", *p + 1); return 0;}
![Page 40: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/40.jpg)
Linguaggio C - puntatori 42
Attenzione
● Da quanto detto in precedenza dovrebbe essere chiaro perché non sia possibile controllare se due array a[] e b[] contengono gli stessi valori scrivendo (a == b)– Il programma seguente stampa "falso": perché?
/* confronto.c */#include <stdio.h>
int main(void){
int a[] = {1, 21, -3};int b[] = {1, 21, -3};printf("%s\n", (a == b ? "vero" : "falso"));return 0;
}
![Page 41: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/41.jpg)
Linguaggio C - puntatori 43
Metodo corretto per confrontare il contenuto di due array
/* arrays_equal.c */#include <stdio.h>
/* restituisce 1 se e solo se a[] e b[] hanno lo stesso contenuto */int arrays_equal(int a[], int b[], int n){
int i;for (i=0; i<n; i++) {
if (a[i] != b[i]) {return 0;
}}return 1;
}
int main(void){
int a[] = {1, 21, -3};int b[] = {1, 21, -3};printf("%s\n", (arrays_equal(a, b, 3) ? "vero" : "falso"));return 0;
}
![Page 42: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/42.jpg)
Linguaggio C - puntatori 44
Array e funzioni● Le funzioni seguenti sono equivalenti e si invocano
tutte allo stesso modo
int sum1(int a[], int n) {
int i, s=0;for (i=0; i<n; i++) {
s += a[i];}return s;
}
int sum2(int *a, int n) {
int i, s=0;for (i=0; i<n; i++) {
s += a[i];}return s;
}
int sum3(int *a, int n) {
int i, s=0;for (i=0; i<n; i++) {
s += *(a+i);}return s;
}
int sum4(int *a, int n) {
int *p, s=0;for( p=a; p<a+n; p++) {
s += *p;}return s;
}
![Page 43: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/43.jpg)
Linguaggio C - puntatori 45
int sum4(int *a, int n) {
int *p, s=0;for( p=a; p<a+n; p++) {
s += *p;}return s;
}
3 -1 12 5 4
Spiegazione di sum4()● Supponiamo
– sizeof(int) == 4– a[] = {3, -1, 12, 5, 4}
a a+5
p p+1 p+2 p+3 p+4
![Page 44: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/44.jpg)
Linguaggio C - puntatori 46
Puntatori a carattere
● L'"equivalenza" tra array e puntatori consente di manipolare le stringhe (sequenze di caratteri) sia come array di char, sia come puntatori a char
/* lunghezza2.c */#include <stdio.h>
int lunghezza( char* s ) {int n;for (n=0; *s; s++) { n++; }return n;
}
int main( void ){
char *s1 = "Prova";char s2[] = "Prova";printf("%d %d\n", lunghezza(s1), lunghezza(s2));return 0;
}
'P' 'r' 'o' 'v' 'a' 0 'P' 'r' 'o' 'v' 'a' 0
s1 s2
Memoria
![Page 45: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/45.jpg)
Linguaggio C - puntatori 47
Attenzione
● C'è una differenza importante tra s1 e s2– Modificare il contenuto di s1 causa un comportamento indefinito
– Modificare il contenuto di s2 è ammesso
/* indefinito.c */#include <stdio.h>
int main( void ){
char *s1 = "Prova";char s2[] = "Prova";*s1 = 'p'; /* INDEFINITO */s2[0] = 'p'; /* Ok */printf(“%s %s\n”, s1, s2);return 0;
}
'P' 'r' 'o' 'v' 'a' 0 'P' 'r' 'o' 'v' 'a' 0
s1 s2
Memoria
Solo in questo caso, i caratteri del letterale
“Prova” vengono memorizzati in
un'area di memoria che si deve
immaginare “a sola lettura”
![Page 46: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/46.jpg)
Linguaggio C - puntatori 48
Passaggio per puntatore
● Una applicazione importante dei puntatori è per "modificare" il parametro attuale– non si passa il “cosa” ma
il “dove”
/* punt-parametro.c */#include <stdio.h>
void incrementa(int *x){
*x = *x + 1;}
int main( void ){ int a = 10; incrementa(&a); printf("a = %d\n", a); return 0;}
![Page 47: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/47.jpg)
Linguaggio C - puntatori 49
Passaggio per puntatore
/* punt-parametro.c */#include <stdio.h>
void incrementa(int *x){
*x = *x + 1;}
int main( void ){ int a = 10; incrementa(&a); printf("a = %d\n", a); return 0;}
101024 a
![Page 48: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/48.jpg)
Linguaggio C - puntatori 50
Passaggio per puntatore
/* punt-parametro.c */#include <stdio.h>
void incrementa(int *x){
*x = *x + 1;}
int main( void ){ int a = 10; incrementa(&a); printf("a = %d\n", a); return 0;}
101024 a
void incrementa(int *x){
*x = *x + 1;}
x = 1024
![Page 49: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/49.jpg)
Linguaggio C - puntatori 51
Passaggio per puntatore
/* punt-parametro.c */#include <stdio.h>
void incrementa(int *x){
*x = *x + 1;}
int main( void ){ int a = 10; incrementa(&a); printf("a = %d\n", a); return 0;}
111024 a
void incrementa(int *x){
*x = *x + 1;}
x = 1024
![Page 50: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/50.jpg)
Linguaggio C - puntatori 52
Passaggio per puntatore
/* punt-parametro.c */#include <stdio.h>
void incrementa(int *x){
*x = *x + 1;}
int main( void ){ int a = 10; incrementa(&a); printf("a = %d\n", a); return 0;}
111024 a
void incrementa(int *x){
*x = *x + 1;}
x = 1024
![Page 51: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/51.jpg)
Linguaggio C - puntatori 53
Passaggio per puntatore
/* punt-parametro.c */#include <stdio.h>
void incrementa(int *x){
*x = *x + 1;}
int main( void ){ int a = 10; incrementa(&a); printf("a = %d\n", a); return 0;}
111024 a
a = 11
Output
![Page 52: Il linguaggio C Puntatori - moreno.marzolla.name · Linguaggio C - puntatori 3 Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna](https://reader031.vdocuments.net/reader031/viewer/2022022114/5c68a7e809d3f27c028bd262/html5/thumbnails/52.jpg)
Linguaggio C - puntatori 54
Passaggio per puntatore
/* punt-parametro.c */#include <stdio.h>
void incrementa(int *x){
*x = *x + 1;}
int main( void ){ int a = 10; incrementa(&a); printf("a = %d\n", a); return 0;}
111024 a
a = 11
Output