# Puntatori
## Esercizio 01 - Utilizzo Base dei Puntatori
Scrivi un programma che utilizza un puntatore per leggere dallo standard input un numero intero inserito dall’utente. Il programma raddoppia il valore inserito dall’utente utilizzando il puntatore. Stampare, prima e dopo il raddoppio del valore, le seguenti informazioni:
1. Indirizzo della variabile puntata dal puntatore
2. Indirizzo della variabile a cui punta il puntatore
3. Valore della variabile
4. Valore della variabile a cui punta il puntatore
```c
#include <stdio.h>
int main(int argc, char* argv[]) {
// Variabili
int a, *pa;
// Assegnamento del puntatore
pa = &a;
// Acquisizione del valore
printf("Inserisci un intero: ");
scanf("%d", pa);
// Stampa info
printf("Indirizzo variabile: %p\n", &a);
printf("Indirizzo a cui punta il puntatore: %p\n", pa);
printf("Valore variabile: %d\n", a);
printf("Valore della variabile a cui punta il puntatore: %d\n", *pa);
// Raddoppio del valore
*pa = 2*(*pa);
// Stampa info
printf("Indirizzo variabile: %p\n", &a);
printf("Indirizzo a cui punta il puntatore: %p\n", pa);
printf("Valore variabile: %d\n", a);
printf("Valore della variabile a cui punta il puntatore: %d\n", *pa);
}
```
---
## Esercizio 02 - Swap
Scrivi un programma che implementa il meccanismo di `swap` tra due puntatori, che scambia i valori di due variabili intere usando i puntatori. Il programma dovrà:
1. Leggere due interi da input.
2. Usare il meccanismo di `swap` per scambiare i valori.
3. Stampare i valori prima e dopo lo scambio.
```c
#include <stdio.h>
int main(int argc, char* argv[]) {
// Variabili
int a, b, *pa, *pb, tmp;
// Inizializzazione puntatori
pa = &a;
pb = &b;
// Acquisizione valori
printf("Inserisci il primo valore: ");
scanf("%d", pa);
printf("Inserisci il secondo valore: ");
scanf("%d", pb);
// Stampa info
printf("Indirizzo prima variabile: %p\n", &a);
printf("Indirizzo a cui punta il puntatore alla prima variabile: %p\n", pa);
printf("Indirizzo seconda variabile: %p\n", &b);
printf("Indirizzo a cui punta il puntatore alla seconda variabile: %p\n", pb);
printf("Valore prima variabile: %d\n", a);
printf("Valore della variabile a cui punta il primo puntatore: %d\n", *pa);
printf("Valore seconda variabile: %d\n", b);
printf("Valore della variabile a cui punta il seconda puntatore: %d\n", *pb);
// Swap
printf("\nSWAP!\n");
tmp = *pa;
*pa = *pb;
*pb = tmp;
// Stampa info
printf("Indirizzo prima variabile: %p\n", &a);
printf("Indirizzo a cui punta il puntatore alla prima variabile: %p\n", pa);
printf("Indirizzo seconda variabile: %p\n", &b);
printf("Indirizzo a cui punta il puntatore alla seconda variabile: %p\n", pb);
printf("Valore prima variabile: %d\n", a);
printf("Valore della variabile a cui punta il primo puntatore: %d\n", *pa);
printf("Valore seconda variabile: %d\n", b);
printf("Valore della variabile a cui punta il seconda puntatore: %d\n", *pb);
return 0;
}
```
---
## Esercizio 03 - Inserimento, Somma, Min e Max di un Array
Scrivere un programma che dichiara un array di interi di 5 elementi e che usa un puntatore per:
1. Leggere i valori degli elementi dell’array dallo standard input
2. Sommare tutti gli elementi dell’array
3. Trovare il minimo valore dell’array
4. Trovare il massimo valore dell’array
5. Stampare la somma, il minimo e il massimo
### Versione Base
```c
#include <stdio.h>
#define N 5
int main(int argc, char* argv[]) {
// Variabili
int v[N], *pv, i, somma, min, max;
// Inizializzazione puntatore
pv = v;
// Acquisizione valori
for(i=0; i<N; i++){
printf("Inserisci l'elemento in posizione %d: ", i);
scanf("%d", pv+i);
}
// Somma valori
somma = 0;
for(i=0; i<N; i++){
somma += *(pv+i);
}
// Trova minimo
min = *pv;
for(i=0; i<N; i++){
if(*(pv+i) < min) min = *(pv+i);
}
// Trova massimo
max = *pv;
for(i=0; i<N; i++){
if(*(pv+i) > max) max = *(pv+i);
}
// Stampa
printf("Somma elementi: %d\n", somma);
printf("MASSIMO: %d\n", max);
printf("minimo: %d\n", min);
return 0;
}
```
### Versione Ottimizzata
```c
#include <stdio.h>
#define N 5
int main(int argc, char* argv[]) {
// Variabili
int v[N], *pv, i, somma, min, max;
// Inizializzazione puntatore
pv = v;
// Acquisizione valori
somma = 0;
for(i=0; i<N; i++){
printf("Inserisci l'elemento in posizione %d: ", i);
scanf("%d", pv+i);
if(i == 0){
max = *(pv+i);
max = min;
}
else{
if(max < *(pv+i)) max = *(pv+i);
if(min > *(pv+i)) min = *(pv+i);
}
somma += *(pv+i);
}
// Stampa
printf("Somma elementi: %d\n", somma);
printf("MASSIMO: %d\n", max);
printf("minimo: %d\n", min);
return 0;
}
```
---
## Esercizio 04 - Puntatori e Stringhe
Scrivi un programma che chiede all'utente di inserire una stringa e poi:
1. Usa un puntatore per contare il numero di caratteri nella stringa (senza usare `strlen()`).
2. Usa il puntatore per stampare la stringa in ordine inverso.
```c
#include <stdio.h>
#define N 100
int main(int argc, char* argv[]) {
// Variabili
char stringa[N], *p_stringa;
int i, len;
// Inizializzazione puntatore
p_stringa = stringa;
// Acquisizione stringa
printf("Inserire una stringa: ");
scanf("%s", p_stringa);
// Calcolo lunghezza
len = 0;
i = 0;
while(*(p_stringa + i) != '\0'){
len++;
i++;
}
// Stampa stringa in ordine inverso
printf("Stringa invertita: ");
for(i=len-1; i>=0; i--) printf("%c", *(p_stringa + i));
printf("\n");
return 0;
}
```
---
## Esercizio 05 - Inversione di un Array
Scrivi un programma che chiede all'utente di inserire un array di 10 interi positivi, sfruttando **solo** l’aritmetica dei puntatori.
Il programma deve stamparne quindi l’inverso, di nuovo usando **solo** l’aritmetica dei puntatori.
(la soluzione riporta comunque la versione senza puntatori per studiarne la differenza a livello di codice)
### Versione senza puntatori
```c
#include <stdio.h>
#define N 10
int main(){
int array[N], i;
// Acquisizione valori
for(i = 0; i < N; i++){
do{
printf("inserisci elemento in posizione %d: ", i);
scanf("%d", &array[i]);
}while(array[i] < 0);
}
// stampa dell'array invertito
printf("Array invertito:\n");
for(i = N - 1; i >= 0; i--){
printf("%d ", array[i]);
}
printf("\n");
return 0;
}
```
### Versione con puntatori
```c
#include <stdio.h>
#define N 10
int main(){
int array[N], *p, i;
// Inizializzazione puntatore
p = array;
// Acquisizione valori
for(i = 0; i < N; i++){
do{
printf("inserisci elemento in posizione %d: ", i);
scanf("%d", p + i);
}while(*(p + i) < 0);
}
// stampa dell'array invertito
printf("Array invertito:\n");
for(i = N - 1; i >= 0; i--){
printf("%d ", *(p + i));
}
printf("\n");
return 0;
}
```
---
## Esercizio 06 - Doppio di un Array
Si scriva un programma che consenta all’utente di inserire un array di 5 interi positivi. Il programma deve salvare in un secondo array di stessa dimensione il doppio di ogni elemento.
Si usi **solo** l’aritmetica dei puntatori (la soluzione riporta comunque la versione senza puntatori per studiarne la differenza a livello di codice)
### Versione senza puntatori
```c
#include <stdio.h>
#define N 5
int main(){
int array1[N], array2[N], i;
// Acquisizione valori per il primo array
for(i = 0; i < N; i++){
do{
printf("inserisci elemento in posizione %d: ", i);
scanf("%d", &array1[i]);
}while(array1[i] < 0);
}
// 2* ogni elemento e salvataggio in secondo array
for(i = 0; i < N; i++){
array2[i] = 2 * array1[i];
}
// Stampa del secondo array
printf("Secondo array (doppio del primo):\n");
for(i = 0; i < N; i++){
printf("%d ", array2[i]);
}
printf("\n");
return 0;
}
```
### Versione con puntatori
```c
#include <stdio.h>
#define N 5
int main(){
int array1[N], array2[N], i, *p1, *p2;
// Inizializzazione puntatori
p1 = array1;
p2 = array2;
// Acquisizione valori per il primo array
for(i = 0; i < N; i++){
do{
printf("inserisci elemento in posizione %d: ", i);
scanf("%d", p1 + i);
}while(*(p1 + i) < 0);
}
// 2* ogni elemento e salvataggio in secondo array
for(i = 0; i < N; i++){
*(p2 + i) = 2 * (*(p1 + i));
}
// Stampa del secondo array
printf("Secondo array (doppio del primo):\n");
for(i = 0; i < N; i++){
printf("%d ", *(p2 + i));
}
printf("\n");
return 0;
}
```
---
## Esercizio 07 - Pari in Pari e Dispari in Dispari
Si scriva un programma sfruttando **solo** l’aritmetica dei puntatori che, in un array di 10 interi positiviacquisito da input, conti quanti elementi pari ci sono in posizione pari, e quanti dispari in posizione dispari (contare la posizione “0” come pari).
Esempio:
[5,1,3,4,14,16,3,80,191,11]
Pari in pari: 1 (il 14)
Dispari in dispari: 2 (3 e 11)
(la soluzione riporta comunque la versione senza puntatori per studiarne la differenza a livello di codice)
### Versione senza puntatori
```c
#include <stdio.h>
#define N 10
int main(){
int array[N], i, cPinP=0, cDinD=0;
// Acquisizione valori
for(i = 0; i < N; i++){
do{
printf("inserisci elemento in posizione %d: ", i);
scanf("%d", &array[i]);
}while(array[i] < 0);
}
// Conteggio pari in posizione pari e dispari in posizione dispari
// nota! non servono due loop, possiamo scorrere l'array
// una sola volta!
for(i = 0; i < N; i++){
if(i % 2 == 0 && array[i] % 2 == 0){
cPinP++;
}
else if(i % 2 != 0 && array[i] % 2 != 0){
cDinD++;
}
}
// Stampa risultati
printf("Numeri pari in posizione pari: %d\n", cPinP);
printf("Numeri dispari in posizione dispari: %d\n", cDinD);
return 0;
}
```
### Versione con puntatori
```c
#include <stdio.h>
#define N 10
int main(){
int array[N], i, *p, cPinP=0, cDinD=0;
// Inizializzazione puntatore
p = array;
// Acquisizione valori
for(i = 0; i < N; i++){
do{
printf("inserisci elemento in posizione %d: ", i);
scanf("%d", p + i);
}while(*(p + i) < 0);
}
// Conteggio pari in posizione pari e dispari in posizione dispari
// nota! non servono due loop, possiamo scorrere l'array
// una sola volta!
for(i = 0; i < N; i++){
if(i % 2 == 0 && (*(p + i)) % 2 == 0){
cPinP++;
}
else if(i % 2 != 0 && (*(p + i)) % 2 != 0){
cDinD++;
}
}
// Stampa risultati
printf("Numeri pari in posizione pari: %d\n", cPinP);
printf("Numeri dispari in posizione dispari: %d\n", cDinD);
return 0;
}
```
---
## Esercizio 07bis - Pari in Pari e Dispari in Dispari BIS
Dopo il programma precedente, salvare i “pari in pari” ed i “dispari in dispari” in due nuovi array
Esempio:
[5,1,3,4,14,16,3,80,191,11]
Pari in pari: 1 (il 14) -> pari_in_pari = contiene il 14 in posizione 0
Dispari in dispari: 2 (3 e 11) -> dispari_in_dispari = contiene 3 e 11 in posizione 0 e 1
### Versione con puntatori
```c
#include <stdio.h>
#define N 10
int main(){
int array[N], i, *p, cPinP=0, cDinD=0, pariinpari[N], dispariindispari[N], *pp, *pd;
// Inizializzazione puntatore
p = array;
pp = pariinpari;
pd = dispariindispari;
// Acquisizione valori
for(i = 0; i < N; i++){
do{
printf("inserisci elemento in posizione %d: ", i);
scanf("%d", p + i);
}while(*(p + i) < 0);
}
// Conteggio pari in posizione pari e dispari in posizione dispari
// nota! non servono due loop, possiamo scorrere l'array
// una sola volta!
for(i = 0; i < N; i++){
if(i % 2 == 0 && (*(p + i)) % 2 == 0){
cPinP++;
*(pp++) = *(p + i);
}
else if(i % 2 != 0 && (*(p + i)) % 2 != 0){
cDinD++;
*(pd++) = *(p + i);
}
}
// Stampa risultati
printf("Numeri pari in posizione pari: %d\n", cPinP);
printf("Numeri dispari in posizione dispari: %d\n", cDinD);
printf("Array dei pari in posizione pari:\n");
pp = pariinpari; // reset puntatore all'inizio dell'array
pd = dispariindispari; // reset puntatore all'inizio dell'array
for(i = 0; i < cPinP; i++){
printf("%d ", *(pp + i));
}
printf("\n");
printf("Array dei dispari in posizione dispari:\n");
for(i = 0; i < cDinD; i++){
printf("%d ", *(pd + i));
}
printf("\n");
return 0;
}
```
---