Che materia stai cercando?

Appunti di programmazione C

Parte I del corso di fondamenti di informatica;if;while;do_while;for;struct; Appunti basati su appunti personali del publisher presi alle lezioni del prof. Colace dell’università degli Studi di Salerno - Unisa, Facoltà di Ingegneria. Scarica il file in formato PDF!

Esame di Fondamenti di infomratica docente Prof. F. Colace

Anteprima

ESTRATTO DOCUMENTO

….

default: comando;

}

La semantica dell’istruzione switch impone che:

• venga valutata l’espressione intera: se corrisponde ad uno dei valori case, il flusso di esecuzione

viene trasferito alla prima istruzione successiva al case nel programma;

• se non c’è corrispondenza tra l’espressione switch ed alcun valore case, allora il flusso di esecuzione

viene trasferito all’istruzione del ramo default (non obbligatorio)

Non possono esistere, inoltre, case con valori uguali. Nell’istruzione switch, il flusso di esecuzione, a partire

dal case selezionato, prosegue fino alla successiva istruzione di controllo del flusso o alla fine dell’istruzione

switch. L’istruzione break forza l’uscita dal costrutto switch, trasferendo il controllo alla prima istruzione che

segue il costrutto.

L’uso dell’istruzione break all’interno dello switch evita che il controllo del programma passi da un case al

successivo.

CICLO WHILE:

La sintassi del while è la seguente:

while(espressione){

comando;

}

Dal punto di vista semantico quello che si fa è valutare l’espressione: se è diversa da zero (cioè vera) viene

eseguito il comando(ovvero il corpo del ciclo) ed il controllo ritorna all’inizio del ciclo. Questa operazione si

ripete fino al momento in cui l’espressione vale zero (cioè l’espressione è falsa): il programma supera il ciclo

while ed esegue le istruzioni successive.

ESEMPIO di uso del ciclo while: SOMMA DEI PRIMI N NUMERI,

#include <stdio.h> /* la uso per poter immettere dati da tastiera e per visualizzare a schermo i risultati*/

#include <stdlib.h> /* mi serve per "implementare la funzione system("pause") */

int somma (int); /* prototipo della funzione*/

int main (){

int n,totale;

printf("Inserisci un numero:\n");

scanf("%d",&n);

/* SOMMA DEI PRIMI N NUMERI */

totale=somma(n); /* richiamo della funzione */

printf("Il risultato e':%d\n", totale);

system("pause"); /* mi consente di bloccare a video tutto il programma*/

}

/* dichiarazione della funzione */

int somma (int a){

int i=1,tot=0; 14

while(i<=a){

tot=tot+i;

i+=1;

}

}

return tot; /* mi restituisce il valore della variabile intera tot*/

}

Cioè fino a che i è minore o al più uguale di a, esegui il comando tot=tot+i ed incrementa i. Quando i risulta

maggiore di a non far nulla. Questo è quello che mi dice il while in questo esercizio.

DO-WHILE:

La sintassi del do-while è la seguente:

do{

comando;

}while(espressione);

In questo costrutto il corpo del ciclo viene eseguito almeno una volta perché il controllo è in coda

(..while(espressione);). NOTA: Malgrado il controllo in coda, l’iterazione è “per vera” come nel caso del

ciclo while.

In questi costrutti, per comando intendiamo un solito comando o un blocco di codice.

Un esempio dell’uso del costrutto SWITCH è il seguente:

#include <stdio.h> /* la uso per poter immettere dati da tastiera e per visualizzare a schermo i risultati*/

#include <stdlib.h> /* mi serve per "implementare la funzione system("pause") */

int main (){

int a,b,i,somma,prod,diff,div;

do{

printf("Inserisci il primo numero:\n");

scanf("%d",&a);

printf("Inserisci il secondo numero:\n");

scanf("%d",&b);

if(a>=b){

printf("Inserisci 1 per sommare i due numeri.\n");

printf("Inserisci 2 per sottrarre i due numeri .\n");

printf("Inserisci 3 per moltiplicare i due numeri.\n");

printf("Inserisci 4 per dividere i due numeri.\n\n");

printf("La mia scelta e':");

scanf("%d",&i);

switch(i){

case 1:

somma=a+b;

printf("\nLa somma dei due numeri e':%d\n\n",somma);

break;

case 2: 15

diff=a-b;

printf("La differenza tra i due numeri e':%d\n\n",diff);

break;

case 3:

prod=a*b;

printf("Il prodotto tra i due numeri e':%d\n\n",prod);

break;

case 4:

div=a/b;

printf("Il rapporto tra i due numeri e':%d\n\n",div);

break;

default:

printf("DEVI INSERIRE UN NUMERO DA 1 a 4\n\n");

}

}

else

printf("Il primo numero deve essere maggiore del secondo\n");

}while(a>=b);

system("pause"); /* mi consente di bloccare a video tutto il programma*/

}

ESERCITAZIONE 18/03/2016

Il debug permette di vedere se e dove ci sono problemi nel programma.

La variabile è un contenitore all’interno del quale posso metterci dei dati e la &(e-commerciale) mi permette

di entrare nell’indirizzo di memoria della variabile.

ESERCIZIO: IL MINIMO TRA DUE NUMERI

#include <stdio.h>

#include <stdlib.h>

int main (){

int numero1,numero2; //dichiarazione primo e secondo numero

printf("INSERISCI IL PRIMO NUMERO:\n");

scanf("%d",&numero1);

printf("INSERISCI IL SECONDO NUMERO:\n");

scanf("%d",&numero2);

// confronto tra i due numeri

if(numero1<numero2){

printf("il minimo e':%d\n",numero1);

}

else if(numero2<numero1){

printf("il minimo e' %d\n",numero2);

}

else if(numero1==numero2){

printf("i due numeri sono uguali");

}

system("pause");

return 0;

}

LEZIONE 8 - 21/03/2016

CICLO FOR 16

Sappiamo in questo caso quante volte eseguire l’operazione, quante iterazione vogliamo. Il costrutto è il

seguente:

for(condizionale iniziale; condizione di uscita; condizione che va a modificare il parametro su cui stiamo

facendo il controllo){

comando;

}

Esempio:

for(i=0;i<=9;i++){

comando;

}

i=0 è un’assegnazione, mentre i++ vuol dire i=i+1(si utilizza prima il valore di i e poi si incrementa). ++i

significa prima incrementa e poi usa la variabile.

BREAK-CONTINUE:

Il break non fa altro che uscire da un loop o da uno switch, il continue invece salta un’iterazione del

loop. Si possono trovare in costrutti quali while, do-while e for.

Per questi costrutti:

- all’interno del comando può comparire l’istruzione BREAK che, se eseguita, termina il ciclo;

- può comparire la keyword CONTINUE che, una volta invocata, riavvia immediatamente un nuovo

ciclo.

Consideriamo un ciclo for:

for(inizio;condizione;passo){

comando;

}

Con un while avrei:

inizio;

while(condizione){

comando;

passo;

}

Per lo switch invece:

switch(espressione){

case v1: comando1;

break;

case v2: comando2;

break;

case v3: comando3;

break;

default: comandod;

break;

}

Con un if avrei:

int tmp=espressione;

if(tmp==v1)

comando1; 17

else if(tmp==v2)

comando2;

else if(tmp==v3)

comando3;

else comandod;

per raggruppare le condizioni è possibile usare l’operatore && che rappresenta una AND: le condizioni

devono essere verificate entrambe.

ESERCIZIO:

- Calcolare la circonferenza sapendo che l’utente deve inserire il valore del raggio da tastiera. Il

calcolo deve essere effettuato solo tra 0 e 32767. Qualora l’utente metta un numero sbagliato:

dobbiamo dire che l’utente ha sbagliato e fargli reinserire un altro valore.

POSSIBILE SOLUZIONE:

#include <stdio.h>

#include <stdlib.h>

int main (){

int raggio;

float circ;

do{ printf("Inserisci un raggio compreso tra 0 e 32767:\n");

scanf("%d",&raggio);

if(raggio>=0 && raggio<=32767){

circ=2*raggio*3.14;

printf("Il valore della circonferenza e' pari a

%f\n\n",circ);

}

else printf("Valore del raggio ERRATO!\n\n");

}while(raggio<0 || raggio>32767);

system("pause");

return 0;

}

- Progettare una calcolatrice in cui il divisore deve essere diverso da 0. Se non è diverso da zero dirlo

e far inserire un nuovo valore

POSSIBILE SOLUZIONE:

#include <stdio.h> /* la uso per poter immettere dati da tastiera e per

visualizzare a schermo i risultati*/

#include <stdlib.h> /* mi serve per "implementare la funzione system("pause")

*/

int main (){

int a,b,i,somma,prod,diff,div;

do{ printf("Inserisci il primo numero:\n");

scanf("%d",&a);

printf("Inserisci il secondo numero:\n");

scanf("%d",&b); 18

if(a>=b){

printf("Inserisci 1 per sommare i due numeri.\n");

printf("Inserisci 2 per sottrarre i due numeri .\n");

printf("Inserisci 3 per moltiplicare i due numeri.\n");

printf("Inserisci 4 per dividere i due numeri.\n\n");

printf("La mia scelta e':");

scanf("%d",&i);

switch(i){

case 1:

somma=a+b;

printf("\nLa somma dei due numeri e':%d\n\n",somma);

break;

case 2:

diff=a-b;

printf("La differenza tra i due numeri e':%d\n\n",diff);

break;

case 3:

prod=a*b;

printf("Il prodotto tra i due numeri e':%d\n\n",prod);

break;

case 4:

if(b!=0){

div=a/b;

printf("Il rapporto tra i due numeri e':%d\n\n",div);

}

else {

printf("inserisci il divisore:\n");

scanf("%d",&b);

div=a/b;

printf("Il rapporto tra i due numeri e':

%d\n\n",div); }

break;

default:

printf("DEVI INSERIRE UN NUMERO DA 1 a 4\n\n");

}

}

else

printf("Il primo numero deve essere maggiore del

secondo\n"); }while(a>=b);

system("pause"); /* mi consente di bloccare a video tutto il programma*/

return 0;

}

- Algoritmo per il calcolo dei numeri primi. Cioè dato un numero vedere se è primo o meno.

POSSIBILE SOLUZIONE:

#include <stdio.h>

#include <stdlib.h>

int main(){

int num;

do{ printf("Inserisci un numero:\n");

scanf("%d",&num);

if(num%2==1 || num==2)

printf("Il numero e' primo\n\n"); 19

else printf("il numero non e' primo\n\n");

}while(num%2==0);

return 0;

system("pause");

} - SOMMA DEI PRIMI N NUMERI

POSSIBILE SOLUZIONE:

#include <stdio.h> /* la uso per poter immettere dati da tastiera e per

visualizzare a schermo i risultati*/

#include <stdlib.h> /* mi serve per "implementare la funzione system("pause")

*/

int somma (int); /* prototipo della funzione*/

int main (){

int n,totale;

printf("Inserisci un numero:\n");

scanf("%d",&n);

/* SOMMA DEI PRIMI N NUMERI */

totale=somma(n); /* richiamo della funzione */

printf("Il risultato e':%d\n", totale);

system("pause"); /* mi consente di bloccare a video tutto il programma*/

}

/* dichiarazione della funzione */

int somma (int a){

int i=1,tot=0;

for(i=1;i<=a;i++){

tot=tot+i; /* oppure posso scrivere tot+=i*(che è

l'equivalente di tot=tot+i)/

}

/* al posto del ciclo for potrei usare un ciclo while:

while(i<=a){ tot=tot+i;

i+=1;

}

*/

}

return tot; /* mi restituisce il valore della variabile

intera tot*/ }

LEZIONE 9 – 22/03/2016

ESERCIZIO: creare un programma main che restituisce un intero. dovrà dichiarare due interi x e y,

inizializzare x a 4 e y a 5, in seguito il main chiamerà una funzione scambia che accetta in ingresso due

variabili intere. Il main termina con la stampa a video dei valori di x e y. La funzione scambia che restituisce

un void ha come parametri due interi, a e b, all’interno del main scambia(x,y), in più questa funzione ha

l’obiettivo di scambiare i valori inseriti.

#include <stdio.h>

#include <stdlib.h>

void scambia(int a,int b){

int temp;

temp=a; 20

a=b;

b=temp;

}

int main(){

int x=4;

int y=5;

scambia(x,y);

printf("%d e %d\n",x,y);

system("pause");

return 0;

}

In realtà quello che esce a video è ancora 4 e 5.

ESERCIZIO 2: il main dichiara due variabili(x e y): x=3, y=fact(x). La funzione fact accetta un intero n e

restituisce un intero. Inizializza una variabile locale p=1, fino a quando il valore di n è maggiore di 0, calcola

: p=p*n, ad ogni operazioni devo decrementare n. Il fact restituisce p.

#include <stdio.h>

#include <stdlib.h>

int fact (int n){

int p=1;

while(n>0){

p=p*n;// avrei potuto scrivere p*=n--;

n--;// in questo modo avrei evitato questo comando.

}

return p;

}

int main(){

int x=3;

int y;

y=fact(x);

printf("il fattore di %d e':%d\n",x,y);

system("pause");

return 0;

}

OPERATORI LOGICI

&&: AND logico

|| : OR logico

!: NOT logico

L’operatore NOT è possibile usarlo anche in questo modo:

if(!espressione)

istruzione;

in questo caso l’istruzione verrà eseguita se l’espressione risulta falsa.

L’uguale (=) è un operatore di assegnazione:

x=2*y-1; assegno ad x il valore 2y-1 e così via..

E’ possibile utilizzare anche un’assegnazione multipla:

var_1=var_2=…=espressione;

per il compilatore viene fatto in due fasi, cioè:

var_1=espressione;

var_2=var_1; 21

OPERATORI BIT A BIT (O BITWISE)

Sono in grado di operare su ogni singolo bit. Quindi andiamo a lavorare sul singolo bit presente all’interno

del registro. E sono:

- Tilde

- L’& (AND)

- ^ (XOR)

- | (OR)

Esistono altri due operatori, detti di shifting:

- <<, traslazione a sinistra

- >>, traslazione a destra

La tilde effettua il complemento ad uno dell’operando(utilizzabile per variabili senza segno): nella pratica

quello che faccio è invertire il valore dei bit della variabile.

Es. 101011111  010100000 (questo è il complemento a 1)

L’AND logico bit a bit, esempio:

00101101111 &

10011101101 =

00001101101

Quello che ho fatto è una and tra i vari bit. 1&0=0, 0&1=0; 1&1=1.

L’XOR logico bit a bit:

00101101111 ^

10011101101 =

10110000010

L’OR logico bit a bit invece:

00101101111 |

10011101101 =

10111101111

Tra 0 e 255, cioè 8 bit e quindi 1 byte. L’indirizzo è formato da 4 byte e quindi da 32 bit.

IP tra 0 e 127 sono indirizzi di classe A, il numero della rete è data dal primo numero: 10.13.14.15 questo è

un indirizzo IP di classe A il cui numero della rete è 10, mentre la targa del computer è 13.14.15 .

La classe B ha un indirizzo IP tra 128 a 191 e la rete è identificata dai primi due numeri: 140.74.37.12,

la rete è 140.74, la targa del computer è 37.12.

La classe C ha un indirizzo IP tra 192 e 223 e la rete è identificata dai primi tre numeri mentre il quarto è la

targa del computer: 193.205.164.141 &

255.255.255.0

255 in bit ha tutti 1 (11111111). In questo modo ho una maschera di rete. Con la and riesco ad ottenere il

numero della rete. Questo per la classe C. Per la classe B dovrei confrontarlo con 255.255.0.0; per la classe A

invece 255.0.0.0

ESERCIZIO:

Attraverso il meccanismo degli operatori bit a bit, trovare automaticamente la rete e il numero dell’host

all’interno della rete. Chiedere all’utente di inserire 4 numeri e, tramite gli operatori bit a bit,restituire il

numero della rete e il numero dell’host di quella rete.

ESPRESSIONI CONDIZIONALI 22

Utilizza un operatore ternario, cioè il punto interrogativo (?). E’ possibile usare il punto interrogativo per

sostituire un’if per ottimizzare le locazioni di memoria.

La sintassi è:

variabile=(condizione) ? variabile1:variabile2

se la condizione è vera si ha:

variabile=variabile 1

se la condizione è falsa si ha:

variabile=variabile2

PASSAGGIO DI PARAMETRI NELLE FUNZIONI

Il record di attivazione contiene tutto il mondo di una funzione:

- Le variabili locali

- I parametri formali

- Il valore di ritorno

Ad ogni chiamata viene creato un nuovo record di attivazione.

Quando faccio partire un programma quello che succede è che a quel programma viene assegnata una

porzione di memoria: una parte , che contiene il codice del programma, l’altra parte contiene la cosiddetta

“area dati”, che contiene le variabili statiche, l’area heap per le allocazioni dinamiche e infine lo stack. Lo

stack è quello che contiene i record di attivazioni delle funzioni. Quanto spazio occupa il tutto?

Per quanto riguarda l’area del programma, questa è una dimensione fissa perché all’interno troviamo le linee

di codice che caratterizza il programma e le variabili statiche che sono decise in fase di compilazione. L’heap

e lo stack, prese singolarmente non hanno dimensione fissa, prese complessivamente hanno anche loro

dimensione fissa.

Lancio un programma, questo va in memoria e succede che in memoria viene allocato uno spazio per il

programma(variabili statiche e linee di codice), questa porzione è ben definita fin dall’inizio perché io so

quanto è lungo il programma a tempo di compilazione. Quello che può cambiare è l’area dati, heap e stack

possono variare di dimensioni se presi singolarmente. Lo stack è vuoto fino a che non chiamo la funzione e

quindi non può avere dimensione fissa, così anche l’heap.

Lo spazio complessivo dedicato a queste due grandezze(heap e stack) deve però essere fisso, se la supero il

programma può bloccarsi.

Le funzioni possono essere chiamate in due modi:

- O con i parametri passati per valore

- O parametri passati per indirizzo (tramite i puntatori)

In un passaggio per valore si ha un passaggio di dati, di valori; in un passaggio di indirizzo si ha

appunto un passaggio di variabili.

Nel primo caso (parametri per valore) nella cella del record di attivazione corrispondente al parametro

formale, viene copiato il valore assunto dal parametro attuale all’atto della chiamata.

Dato questo codice, scrivere cosa accade in memoria:

#include <stdio.h>

#include <stdlib.h>

void scambia(int a,int b){

int temp;

temp=a;

a=b; 23

b=temp;

}

int main(){

int x=4;

int y=5;

scambia(x,y);

printf("%d e %d\n",x,y);

system("pause");

return 0;

}

Quando il main viene eseguito quello che accade è che viene allocato il record di attivazione. Nel record di

attivazione ho due variabili locali, la x e la y che sono inizializzati a valori 4 e 5. Il return address è relativo

al SO che ha chiamato il main mentre non ha un link dinamico .

Con il main abbiamo bisogno di un return address legato al SO mentre non ha bisogno di un link dinamico

perché la conclusione del main corrisponde alla conclusione dell’intero programma.

Ad un certo punto il main chiama la funzione scambia e parte il record di attivazione legato a scambia.

Questo record di attivazione ha bisogno di un return address(all’istruzione che viene subito dopo la

chiamata) e di un link dinamico verso il main. Questo record inoltre ha una variabile locale temp e due

parametri formali a e b. Una volta che la funzione scambia termina, il suo record di attivazione viene

deallocato e ritorna il controllo al main che ripristina il suo record di attivazione.

Fare lo stesso ragionamento con quest’altro esercizio:

#include <stdio.h>

#include <stdlib.h>

int fact (int n){

int p=1;

while(n>0){

p=p*n;// avrei potuto scrivere p*=n--;

n--;// in questo modo avrei evitato questo comando.

}

return p;

}

int main(){

int x=3;

int y;

y=fact(x);

printf("il fattore di %d e':%d\n",x,y);

system("pause");

return 0;

}

Quando il main viene eseguito quello che accade è che viene allocato il record di attivazione. Nel record di

attivazione ho due variabili locali, la x e la y , di queste due variabili è inizializzata solo la x a 3. Il return

address è relativo al SO che ha chiamato il main mentre non ha un link dinamico .

Ad un certo punto il main chiama la funzione fact e parte il record di attivazione legato a fact. Questo record

di attivazione ha bisogno di un return address e di un link dinamico verso il main. Questo record inoltre ha

una variabile locale p , un parametro formale n e la locazione di memoria dove verrà messo il valore di

ritorno che la funzione restituirà al main . Una volta che la funzione fact termina, il suo record di attivazione

viene deallocato e ritorna il controllo al main che ripristina il suo record di attivazione. 24

RICORSIONE

L’approccio è quello del divide et impera: dato un problema lo si divide in sottoproblemi molto più semplici.

Una funzione è detta ricorsiva se chiama se stessa mentre se due funzioni si chiamano l’un l’altra sono dette

mutuamente ricorsive.

La funzione ricorsiva sa risolvere direttamente (cioè da subito un risultato) solo casi particolari di un

problema detti casi di base, se viene invocata passandole dei dati che non sono di base allora chiama se

stessa.

Esempio:

Calcolare il fattoriale con funzione ricorsiva.

#include <stdio.h>

#include <stdlib.h>

int fact (int n){

if(n<=1){

return 1;

}

else return n*fact(n-1);

}

int main(){

int x;

int y;

printf("Inserisci un valore:\n ");

scanf("%d\n",&x);

y=fact(x);

printf("il fattore di %d e':%d\n",x,y);

system("pause");

return 0;

}

Che succede con i record di attivazione?

Si generano N record di attivazione fino a che non arriviamo al caso base.

ESERCIZIO: SUCCESSIONE DI FIBONACCI CON LA RICORSIONE.

#include <stdio.h>

#include <stdlib.h>

int fibonacci(int n){

if(n==1 || n==2)

return 1;

else return Fibonacci(n-1)+Fibonacci(n-2);

}

int main(){

int num,fib;

printf("Inserisci un numero:\n");

scanf("%d\n",&num);

fib=fibonacci(num);

printf("Il valore di Fibonacci associato al numero %d e’: %d

\n",num,fib);

system("pause");

return 0;

}

All’avvio del programma vedrò una cosa del genere: 25

Mi chiede di inserire un numero (grazie al comando Come

printf("Inserisci un numero:\n");).

esempio suppongo di inserire il numero 6, come in figura:

Dopo aver digitato il numero 6 il programma mi restituisce il valore associato a fibonacci(6), ovvero 8.

Se volessi invece mostrare a video tutta la sequenza dei numeri fino a fibonacci(6) dovrei fare in questo

modo:

#include <stdio.h>

#include <stdlib.h>

int fibonacci(int n){

if(n==1 || n==2)

return 1;

else return Fibonacci(n-1)+Fibonacci(n-2);

}

int main(){

int num,fib,i;

printf("Inserisci un numero:\n");

scanf("%d\n",&num);

printf("La sequenza di Fibonacci fino al numero %d e’:\n",num); 26


PAGINE

31

PESO

322.18 KB

PUBBLICATO

+1 anno fa


DETTAGLI
Corso di laurea: Corso di laurea in ingegneria elettronica
SSD:
Università: Salerno - Unisa
A.A.: 2016-2017

I contenuti di questa pagina costituiscono rielaborazioni personali del Publisher massimiliano.avagliano1 di informazioni apprese con la frequenza delle lezioni di Fondamenti di infomratica e studio autonomo di eventuali libri di riferimento in preparazione dell'esame finale o della tesi. Non devono intendersi come materiale ufficiale dell'università Salerno - Unisa o del prof Colace Francesco.

Acquista con carta o conto PayPal

Scarica il file tutte le volte che vuoi

Paga con un conto PayPal per usufruire della garanzia Soddisfatto o rimborsato

Recensioni
Ti è piaciuto questo appunto? Valutalo!

Altri appunti di Corso di laurea in ingegneria elettronica

Matematica 2
Appunto
Appunti analisi matematica 2
Appunto
Concetti e argomenti per l'esame di analisi matematica 2
Appunto
Appunti algebra lineare
Appunto