- Messaggi: 124
- Ringraziamenti ricevuti 7
[Pillola] Esercizi per 'Skillare'
- Ifrit_Prog
-
Autore della discussione
- Premium Utente
-
Da un po' ho pensato di scrivere una lista e aggiornarla ogni volta che noto una lacuna nelle persone che si avvicinano al Problem Solving.
Oggi, pensando ai vari forum che bazzico (oltre al magone di non avere un sito mio per pigrizia e poca voglia di convincere altri admin a unirsi a me), ho pensato di postare qui tale lista, in modo che io possa tenere un punto di riferimento online, e magari dare una mano a chi capita qui

Se avete idee, suggerimenti, richieste, dubbi, etc etc.... non esitate a chiedere ^^
Ah sia ben chiaro, questa lista è in continuo aggiornamento, e affianco ai quesiti ci mettero' le mie proposte per la soluzione, e sottolineo Proposte, perche' (se un giorno scrivero' la pillola di riferimento) per risolvere un algoritmo esistono infiniti modi, piu' o meno validi, piu' o meno efficiaci in varie situazioni.
- Scrivere una funzione che generi un array di tipo intero, allocato nella memoria heap, di dimensione 5, e ritorni l'indirizzo in testa a esso associato.
Soluzione PropostaCode:int* funzione1(){ int* result = (int*)malloc(sizeof(int)*5); return result; } // oppure int* funzione1(){ return (int*)malloc(sizeof(int)*5); }
- Scrivere una funzione che generi un array di tipo intero, allocato nella memoria heap, di dimensione pari al valore contenuto in una variabile passatagli come argomento. si chiede in oltre di ritornare l'indirizzo in testa all'array creato.
Soluzione PropostaCode:int* funzione2(int len){ int* result = (int*)malloc(sizeof(int)*len); return result; } // oppure /** In questo caso facciamo un controllo sul valore passato come argomento * per essere certi di allocare un array grande almeno una cella. * Nel caso in cui l'intero in ingresso sia pari a zero, o peggio di valore negativo * la funzione ritorna NULL. * * * Nota: * E' una pessima idea implementare una funzione di questo tipo creando * una firma di tipo "unsigned int", ovvero una cosa simile: * * int* funzione2bis(unsigned int len); * * Questo perche' generalmente i compilatori C/C++ fanno un cast "brutale" * di un eventuale dato negativo in un dato, sempre intero, senza segno, * e da un valore che poteva essere "-3" vi ritrovate un valore in argomento * pari a "4294967293". Ovviamente non è questo il caso (per chi conosce) bene * la libreria malloc, ma è buona norma capire questi casi particolari ed eviare * di cercare scappatoie che provochino piu' danni che soluzioni. */ int* funzione2bis(int len){ int* result = NULL; if (len > 0){ result = (int*)malloc(sizeof(int)*len); } return result; }
- Scrivere una funzione che, dato un array di tipo intero come primo argomento, e come secondo argomento un intero che indichi la sua dimensione, azzeri tutti i campi dell'array.
Soluzione PropostaCode:void funzione3(int arr[], int len) { int cnt; for ( cnt = 0; cnt < len ; ++cnt ) { arr[cnt] = 0; } } // oppure void funzione3bis1(int* arr, int len) { int cnt = 0; for ( ; cnt < len ; ++cnt ) { *(arr + cnt) = 0; } } // oppure /** Questa soluzione è piu' veloce delle precedenti presentate. * Riflettere sul perche'. */ void funzione3bis2(int* arr, int len) { int cnt; for ( cnt = len - 1; cnt >= 0 ; --cnt ) { *(arr + cnt) = 0; } }
- Scrivere una funzione identica all'esercizio precedente, con la differenza che azzeri tutti i campi eccetto l'ultimo.
Soluzione PropostaCode:void funzione4(int arr[], int len) { int cnt; for ( cnt = 0; cnt <= len - 1 ; ++cnt ) { arr[cnt] = 0; } } // oppure void funzione4bis1(int* arr, int len) { int cnt; --len; for ( cnt = 0; cnt <= len ; ++cnt ) { arr[cnt] = 0; /* se ve lo state chiedendo, non c'e' errore, e voluto. * scrivere *(arr + cnt) o arr[cnt] è la stessa cosa, * pertanto un puntatore puo essere 'visto' come un array, * e viceversa. * (il modo esatto di esprimere questo concetto risiede * sulla sintassi, ovvero quello che viene chiamato * "Zucchero Sintattico") */ } } // oppure void funzione4bis2(int* arr, int len) { int cnt; for ( cnt = len - 2; cnt >= 0 ; --cnt ) { *(arr + cnt) = 0; } }
- Scrivere una funzione complementare a quella dell'esercizio precedente, ovvero che azzeri solo l'ultimo elemento.
Soluzione PropostaCode:void funzione5(int arr[], int len){ arr[len - 1] = 0; } // oppure void funzione5bis(int* arr, int len){ *(arr + len - 1) = 0; }
- Scrivere una funzione che, dato un array di tipo intero come primo argomento, e come secondo argomento un intero che indichi la sua dimensione, ritorni la somma di tutti i valori contenuti nell'array.
Soluzione PropostaCode:int funzione6(int arr[], int len) { int result = 0; int cnt; for ( cnt = 0; cnt < len ; ++cnt ) { result = result + arr[cnt]; } return result; } // oppure int funzione6bis(int* arr, int len) { int result = 0; /* Saliamo un gradino... CONTROLLI! * per creare codice robusto bisogna sempre fare controlli. * Ho evitato negli esercizi precedenti, ma è buona abitudine pensare * sempre ai casi border line (= */ if ( len > 0 ) { int cnt = len - 1; for ( ; cnt >= 0 ; --cnt ) { result += *(arr + cnt); } } return result; }
- Scrivere una funzione che, dato un array di tipo intero come primo argomento, e come secondo argomento un intero che indichi la sua dimensione, ritorni il prodotto ri tutti i valori conetuti nell'array.
Soluzione PropostaCode:int funzione7(int* arr, int len) { int result = 1; if ( len > 0 ) { int cnt = len - 1; for ( ; cnt >= 0 && result ; --cnt ) { result *= *(arr + cnt); } } return result; }
[hr]
Algoritmi di Ordinamento
- Impementa l'algoritmo di
Selection sort
su un array di interi sfruttando l'effetto collaterale.
Soluzione PropostaCode:void selectionSort(int* arr, int len) { if ( len > 0 && arr != NULL ) { int cnt_0, cnt_1, pivot, tmp; for ( cnt_0 = 0; cnt_0 < len - 1 ; ++cnt_0 ) { pivot = cnt_0; for ( cnt_1 = cnt_0 + 1; cnt_1 < len ; ++cnt_1 ) { if ( *(arr + pivot) > *(arr + cnt_1) ) { pivot = cnt_1; } } if ( pivot != cnt_0 ) { tmp = *(arr + pivot); *(arr + pivot) = *(arr + cnt_0); *(arr + cnt_0) = tmp; } } } }
- Impementa l'algoritmo di
Bubble Sort
su un array di interi sfruttando l'effetto collaterale.
Soluzione PropostaCode:void bubbleSort(int* arr, int len) { if ( len > 0 && arr != NULL ) { int cnt, tmp, sorted; do { --len; sorted = 1; for ( cnt = 0; cnt < len ; ++cnt ) { if ( *(arr + cnt) > *(arr + cnt + 1) ) { tmp = *(arr + cnt); *(arr + cnt) = *(arr + cnt + 1); *(arr + cnt + 1) = tmp; sorted = 0; } } } while ( !sorted ); } }
- Impementa l'algoritmo di
Gnome Sort
su un array di interi sfruttando l'effetto collaterale.
Soluzione PropostaCode:void gnomeSort(int* arr, int len) { if ( len > 0 && arr != NULL ) { int cnt, cnt_1, tmp; for ( cnt = 1; cnt < len ; ++cnt ) { if ( *(arr + cnt) < *(arr + cnt - 1) ) { tmp = *(arr + cnt); for ( cnt_1 = cnt - 1; cnt_1 >= 0 ; --cnt_1 ) { if ( *(arr + cnt_1) <= tmp ) { *(arr + cnt_1 + 1) = tmp; cnt_1 = -1; } else { *(arr + cnt_1 + 1) = *(arr + cnt_1); if ( cnt_1 == 0 ) { *arr = tmp; } } } } } } }
Si prega Accesso o Crea un account a partecipare alla conversazione.
- pier
-
- Anziano Utente
-
- Messaggi: 52
- Ringraziamenti ricevuti 3
Ecco, una cosa che non ho mai capito è il cast prima della malloc... Se non sbaglio si mette però non è necessario, ma allora perchè?
Dal libro che ho sottomano (il linguaggio C, di Ritchie) sembra che fosse necessario prima dell'avvento dello standard ansi, ma poi non più. Sarà per tradizione allora?
edit: posso aggiunge anch'io qualche esempio se mi viene in mente qualcosa di interessante?


Si prega Accesso o Crea un account a partecipare alla conversazione.
Questi esercizi mi stanno facendo tornare al periodo universitario...
...quando preparavo l'esame di Informatica II...
Ottima raccolta di esempi e soluzioni.
Saluti,
Mauro
Si prega Accesso o Crea un account a partecipare alla conversazione.
- Ifrit_Prog
-
Autore della discussione
- Premium Utente
-
- Messaggi: 124
- Ringraziamenti ricevuti 7
pier ha scritto: Non li ho guardati tutti (gli esempi), ma buona l'idea e ben fatto!! fanno sempre comodo..
Ecco, una cosa che non ho mai capito è il cast prima della malloc... Se non sbaglio si mette però non è necessario, ma allora perchè?
Dal libro che ho sottomano (il linguaggio C, di Ritchie) sembra che fosse necessario prima dell'avvento dello standard ansi, ma poi non più. Sarà per tradizione allora?
edit: posso aggiunge anch'io qualche esempio se mi viene in mente qualcosa di interessante?![]()
il cast della malloc è dovuto per dare un'aritmetica al puntatore in ritorno, ovvero siccome malloc ritorna un tipo void*, per far si che la memoria puntata sia trattata nel modo adeguato (dimensione di lettura/scrittura, accesso alle proprietà nel caso di strutture, incremento di locazione, etc etc) si fa il cast al dato che, appunto, vuoi usare.
Il fatto che questo cast viene fatto in automatico da alcuni compilatori (la cosa non la so, non ci ho mai fatto caso, io il cast lo faccio sempre) secondo me è svantaggiosa, perche' puo' introdurre degli errori a livello logico di difficile individuazione.
per quanto riguarda gli esercizi... eh magari

Si prega Accesso o Crea un account a partecipare alla conversazione.
- StefA
-
- Moderatore
-
- Messaggi: 1222
- Ringraziamenti ricevuti 104
Ste
..avevano magari fatto lo sgambetto al ka, ma il sangue restava sempre più denso dell'acqua.. [cit.]
Si prega Accesso o Crea un account a partecipare alla conversazione.
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.
Forum - Ultimi messaggi
-
- Strana anomalia LT lib module_EEPROM
- da marcoilgrande
-
- Nuova versione Kicad 9
- da Mauro Laurenti
-
- MODULO GSM SIM900A
- da embedded
-
- Freedom III e compilazioni fallite
- da Black
-
- LTerminal - nuove funzioni
- da Mauro Laurenti