Easy
Esercizio 1 easy
puntatori Dato ill seguente scheletro di programma:
stampa l'indirizzo di memoria di x, e stampa il valore di x.
per stampare l’indirizzo di memoria di una variabile, basta chiamare “&x”, che sostanzialmente mi tira fuori l’indirizzo di memoria di x. Invece per stampare il contenuto di x basta stampare x (come abbiamo sempre fatto). Se non hai capito nulla forse è il caso di studiare un po’ di roba sui puntatori qui
Esercizio 2 easy
puntatori Dato il seguente scheletro di programma:
stampa il valore e l'indirizzo di memoria di x, SENZA CHIAMARE DIRETTAMENTE LA VARIABILE X
essendo un puntatore, se stampo “y” mi stamperà l’indirizzo di memoria della variabile puntata da y (in questo caso x). Invece se lo “deferenzio” usando l’operatore ”*” quello che accade è che invece di farmi vedere l’indirizzo di memoria di x, mi fa vedere il valore contenuto nell’indirizzo di memoria di x, quindi 3.
Esercizio 3 easy
array Dato il seguente scheletro di programma
Questa cosa genera errore?
No, infatti a, contiene l’indirizzo di memoria del primo elemento, quindi assegnare a b il valore di a significa assegnargli l’indirizzo di memoria del primo elemento
cosa succede se stampo b?
Succede che stampo l’indirizzo di memoria del primo elemento dell’array.
stampa il quarto elemento dell'array a, usando b.
Esercizio 4 easy
Alloca dinamicamente un array di 4 elementi ed assegnagli i valori che vanno da 1 a 4 con un ciclo for
hint1: allocazione dell'array
alloco dinamicamente un array di quattro elementi interi, per farlo serve la funzione malloc, contenuta nella libreria stdlib.h (ricordatevi di includerla se state usando la malloc). La malloc prende in input la dimensione in byte da allocare, ovviamente questa è 4 volte la dimensione in byte di un intero (sizeof(int) per 4 volte).
hint2: assegnamento all'array
Esercizio 5 easy
fai una struct che rappresenti un punto
ovviamente come sappiamo un punto è fatto da una coordinata x e una y. ricordatevi di mettere il ; alla fine della graffa dopo la struct
nel main dichiara due punti: (1,2) e (1,7)
Continua questo esercizio: da adesso in poi si alza la difficoltĂ : continua esercizio 4 medium
Medium
Esercizio 1 medium
puntatori dato il seguente scheletro di programma
Definisci la funzione “aumenta”. SENZA MODIFICARE LE ALTRE PARTI DEL MAIN (IN PARTICOLARE LA PRINT). “aumenta” prende in input un numero float e un intero, e aumenta il primo numero di tanto quanto specificato dall’intero. In questo caso, quindi dovrebbe aumentare il valore di “pi” di 1.
Hint 1
Dobbiamo definire una funzione: che prende in input un float e un intero.
Ma attenzione! Cosiì non va bene! Perchè?…
Hint 2
Non va bene perché la funzione non sta veramente modificando la variabile pi! Quello che sta facendo è solamente prenderne il valore, andate su python tutor per convincervene. Quindi quello che vogliamo sapere, è dov’è ESATTAMENTE la variabile pi. Ergo gli dobbiamo passare il suo indirizzo di memoria, non il suo valore
Soluzione
Cioè: la funzione aumenta, prende il puntatore al primo numero, in modo tale che so dove sta esattamente. E al valore puntato da quel puntatore (nel nostro caso pi greco) ci aggiungo 1. Quando chiamo la funzione “aumenta” non posso passargli il valore di pi greco! Devo passargli l’indirizzo di memoria!!!!! (&pi) Questo perchè se non gli do l’indirizzo di memoria di pi, il puntatore (il pirmo argomento della funzione aumenta) non sa dove andarsela a cercare l’indirizzo di memoria di pi greco! Dentro la funzione aumenta: ovviamente adesso “puntatore_a_num1” non è il valore vero e proprio che voglio aumentare, bensì un PUNTATORE, al valore che voglio aumentare, quindi se ho il puntatore ad un valore, e voglio accedere al valore, come faccio? Si usa il cosidetto “operatore di deferenziazione” (la stellina) *puntatore_a_num.
Esercizio 2 medium
dato questo programma
La prima printf stampa l’indirizzo di memoria di b. Se non siete convinti di questo andatevi a vedere gli esercizi easy sugli array. Nel mio caso stampa l’indirizzo di memoria “1803711096”
Ma cosa stampa la seconda printf?
- l’indirizzo di memoria di b più 2 (es: “1803711098”)
- l’indirizzo di memoria di b più 2 x sizeof(int)
Ma cosa stampa la seconda printf?
Ovviamente la seconda, C, che è molto intelligente, capisce che b è un puntatore ad intero, e quindi quando va a sommare un numero all’indirizzo di memoria, sa già che deve moltiplicarlo per la size del tipo dell’elemento dell’array. Questo è anche il motivo per cui non possiamo mettere tipi diversi nell’array. Altrimenti il compilatore non saprebbe che fare in casi come questo se il tipo non fosse deciso a priopri
Ora che questa cosa è chiarita possiamo passare al vero esercizio.
Dato questo scheletro di programma, fai un ciclo for che stampa il contenuto di a, senza usare a, e SENZA USARE LE PARENTESI QUADRE.
Hint 1
ovviamente dobbiamo fare un ciclo for per scorrere tutto l’array, se non posso usare a, posso usare un puntatore agli elementi di a, cioè b.
Hint 2
Nella printf devo chiamare ad ogni iterazione di i, l’i-esimo elemento puntato da b. Per scrivere l’i-esimo elemento puntato da b, si scrive:
ma non basta stampare questo! perchè questo non stampa il VALORE dell’i-esimo elemento puntato da b, bensì stampa l’INDIRIZZO DI MEMORIA dell’i-esimo elemento puntato da b! Se solo ci fosse un modo per stampare il valore contenuto da un indirizzo di memoria…
Soluzione per australopitechi
ovviamente il modo per stampare il valore contenuto da un certo indirizzo di memoria è l’operatore di deferenziazione (la stellina *). Quindi
Esercizio 3 medium
Definisci una funzione che prende in input un array di interi, somma tutti i numeri dell’array e alloca un nuovo array composto da tanti “1” quanto è il risultato della somma precedente
ESEMPIO: se l’array è
la sua somma è 8 Io voglio un array fatto da otto “1”
Parti dal seguente main
Hint1
siccome non so a priori quanto grosso dovrà essere l’array me lo devo creare dinamicamente
Hint 2
La funzione che voglio prende in input un array, la sua dimensione, e mi restituisce in output un nuovo array fatto di “uni”
Soluzione
Esercizio 4 medium
Questa è la continuazione dell’esercizio 5 easy Se non hai fatto quello, fallo prima di fare questo
Fai una funzione che prende in input un punto, ad esempio p2 e lo stampa così: "(1,7)"
<
Fai una funzione che presi due punti calcola il punto medio dati due punti
Questa funzione a dirla tutta ha un difetto, sapresti dire quale, sapresti renderla migiore??
rendi migliore la funzione data come soluzione alla domanda prima
Soluzione completa
Hard
esercizio 1 hard
arraypuntatorimalloc Fai un programma che prende in input dall’utente continuamente un intero fino a quando non riceve in input qualcosa di diverso. Ogni intero che viene preso in input dall’utente deve essere inserito in un array. Ogni volta che inserisci l’intero stampa l’array.
Hint 1 la funzione che stampa l'array
Una parte importante di questo programma è la funzione che stampa l’array, consiglio di cominciare da quella.
Hint 2 il main: prendere l'intero in input
Ovviamente serve un array, visto che non sappiamo quanti interi metterà l’utente è chiaro che non ci basta allocare l’array così
questo perchè se poi l’utente decide di mettere 11 interi allora il programma si rompe. Quindi come possiamo fare? Semplice: allochiamo dinamicamente l’array (malloc), e quando finisce lo spazio, lo aumentiamo dinamicamente (realloc)
Cominciamo con le prime variabili: l’array, su cui alloco 10 elementi, e altre due variabili, una che tiene conto di quanti elementi sono nell’array, e l’altra che tiene conto di quanti ce ne possono entrare al massimo. In pratica quando la dimensione corrente supera la dimensione massima mi tocca riallocare l’array con altro spazio! Infine stampo un prompt per far capire all’utente cosa deve fare.
Questo loop è infinito (while(1)) chiaramente l’utente può inserire quanti interi vuole, il programma si interrompe nel caso in cui inserisco un non intero, per uscire dal loop sto usando un break. Con la scanf prendo in input l’intero, e ora che ci faccio? Lo metto in un array!
Hint 3: inserire l'intero nell'array
adesso la parte succosa. Non possiamo inserire e basta l’intero nell’array! dobbiamo prima verificare che l’array non sia pieno! se è pieno va aumentata la memoria
fatto questo aggiungiamo l’intero all’array