Pez_93

Programmazione
Guida alla programmazione in C

41 risposte in questa discussione

: Programmazione

Guida alla programmazione in C

 

 

cimage.jpg?itok=2sE08jEp

 

 

Lo scopo di questa guida è insegnare i fondamenti della programmazione in C, uno dei primi linguaggi ad alto livello nato nel 1972.

Ora vi chiederete: perchè iniziare da C, che è uno dei più vecchi linguaggi di programmazione ?

La risposta è semplice: saper programmare in C aiuta molto a dover affrontare i moderni linguaggi ad oggetti come C# e Java; vi troverete già con metà lavoro fatto.

 

IDE per programmare in C

I primi programmi potremo anche scriverli su un blocco note e compilarli da console ma dopo un po' per i programmi più complessi dovremo passare ad un software munito di entrambe le cose ed automatizzato per la programmazione.

A questo scopo consiglio Code::Blocks.

Home page ---> http://www.codeblocks.org/home

Le librerie

Ogni linguaggio di programmazione per poter usare le istruzioni di codice scritte dal programmatore, ha bisogno delle librerie.

Una libreria è un inseme di istruzioni, che al loro interno svolgono altre istruzioni; praticamente nella libreria c'è l'istruzione con le operazioni che deve svolgere mentre il programmatore andrà solo ad usare l'struzione dandogli i valori che servono:

//#include <nome_libreria>#include <stdio.h>

In questo modo si aggiunge una libreria di sistema al proprio foglio di codice; da notare che le librerie hanno come estensione .h.

Se invece vogliamo aggiungere una libreria presente nella cartella del file di codice del programma, dobbiamo fare così:

//#include "nome_libreria.h"#include "custom_library.h"

Il main

Che cos'è il main ?

Esso si può definire come il principale contenitore del nostro programma; contiene tutte le istruzioni che il nostro programma deve eseguire:

int main(){  //istruzioni del programma da eseguire  return 0;}

Da notare che per terminare il main e dunque il nostro programma dobbiamo inserire al fondo del main l'istruzione return 0.

Le variabili

Iniziamo col dire che le variabili sono dei contenitori di dati ed ognuna di esse ha il suo tipo; quest'ultimo varia in base al dato che biosgna memorizzare.

I tipi di variabile sono:

  • int che rappresenta un numero intero a 2 byte
  • char che rappresenta un carattere a 1 byte
  • short che rappresenta un numero intero "corto" a 2 byte
  • long che rappresenta un numero intero "lungo" a 4 byte
  • float che rappresenta un numero reale a 4 byte
  • double che rappresenta un numero reale "lungo" a 8 byte
int a;  //Dichiarazione variabile di tipo interoa = 3;  //Assegno alla variabile un valore numerico interochar b;  //Dichiarazione variabile che rappresenta un carattereb  = 'f';  //Assegno alla variabile un carattere mediante i singoli apici

Ovviamente con le variabili di tipo numerico si possono svolgere le operazioni matematiche:

int a, b, c; a = 2;b = 4;c = a * b;  //Moltiplico le due variabilib = a + c;  //Sommo le due variabilia = c - b;  //Eseguo la sottrazione tra le due variabilic = a / b;  //Eseguo la divisione tra le due variabili

Le variabili di tipo char possono però essere dichiarate anche definendo il numero di caratteri da contenere; in questo caso la variabile prenderà in nome di stringa:

char a[6];  //Dichiarazione variabile che può contenere 7 caratteri

Sebbene siano definiti apparentemente 6 posti nella variabile, in verità saranno 7 dato che conta anche il posto numero 0.

Nel linguaggio C però il valore di una variabile con più caratteri non si può assegnare con = ma deve essere fatto con l'istruzione strcpy:

//strcpy(char destinazione, char sorgente);char b[6];strcpy(b, "casa");  //Copio la stringa "casa" nella variabile b

Le operazione sulle stringhe, come per esempio il confronto, possono essere usando altre istruzioni come la strcmp ma questi sono apprrofondimenti che vedremo in seguito.

L'istruzione printf

Abbiamo imparato come assegnare dei valori alle variabili ed a farci le operazioni base.

Ora per visualizzare a schermo i valori di tali variabili si usa l'istruzione printf; serve però sapere gli identificatori dei tipi di variabile, dato che sarà da specificare nell'istruzione:

  • %d, %i ---> int(numero decimale)
  • %c ---> char a singolo carattere
  • %s ---> chat con più caratteri
  • %f ---> double e float(numeri reali)
  • %u ---> numero senza segno

Questi sono gli identificatori fondamentali, ce ne sono degli altri ma vengono usati in casi estremamente eccezionali.

Ora vediamo un esempio:

//printf("identificatore_tipo_variabile", variabile);int a = 3;printf("%d", a);char d = 'g';printf("%c", d);char b[5];strcpy(b, "casa");printf("%s", b);

L'istruzione printf può essere anche utilizzata per stampare a video una stringa non memorizzata in nessuna variabile:

printf("Ciao come va ?");

L'istruzione scanf

Ora che abbiamo visto come stampare a video i valori delle variabili, vediamo come inserire dentro le variabili dei valori scritti da tastiera.

L'istruzione in questione da utilizzare è scanf che utilizza gli stessi identificatori della printf.

La scanf ha però un altro dettaglio: per le variabili numeriche e a carattere singolo bisogna specificare l'indirizzo della variabile e non il nome della variabile.

Ciò è possibile con il carattere &; vediamo un esempio:

//scanf("identificatore_tipo_variabile", indirizzo_variabile_numerica);//scanf("identificatore_tipo_variabile", indirizzo_variabile_char_carattere_singolo);//scanf("identificatore_tipo_variabile", variabile_char_più_caratteri);int a;scanf("%d", &a);char d;scanf("%c", &d);char b[5];scanf("%s", b);

Gli operatori di incremento e decremento

A volte possiamo abbreviare la scrittura delle istruzioni di incremento e decremento dei valori delle variabili.

Si usano due operatori:

  • ++ ---> incrementa di 1 il valore di una variabile numerica; equivale a scrivere var = var + 1
  • -- ---> decrementa di 1 il valore di una variabile numerica; equivale a scrivere var = var - 1

int a = 1;a++;  //equivale a scrivere a = a + 1;a--;  //equivale a scrivere a = a - 1;

I controlli condizionali

A volte dovremo eseguire una serie di istruzioni se determinate condizioni variabili sono verificate o no.

Per fare ciò si utilizzano le istruzioni if ed else, con l'ausilio di quattro operatori di confronto:

  • > ---> Maggiore
  • < ---> Minore
  • >= ---> Maggiore o uguale
  • <= ---> Minore o uguale
int a = 10;if(a > 9){   printf("La variabile ha un valore maggiore di 9");}else{   printf("La variabile ha un valore minore o uguale a 9");}

Se dobbiamo verificare più di una condizione, dobbiamo utilizzare l'struzione else if:

int a = 5;if(a > 5){  printf("La variabile ha un valore maggiore di 5");}else if(a < 5){  printf("La variabile ha un valore minore di 5");}else{  printf("La variabile ha un valore uguale a 5");}

Da notare che se dobbiamo eseguire una sola istruzione al verificarsi di una condizione, possiamo anche tralasciare di scrivere le parentesi graffe ( { } ):

int a = 5;if(a > 5)  printf("La variabile ha un valore maggiore di 5");else if(a < 5)  printf("La variabile ha un valore minore di 5");else  printf("La variabile ha un valore uguale a 5");

Esistono poi due caratteri, detti operatori logici, che permettono di verificare due o più condizioni nello stesso controllo:

  • && ---> Le istruzioni del controllo saranno eseguite solo se tutte le condizioni sono verificate
  • || ---> Le istruzioni del controllo saranno eseguite anche solo con una condizione verificata

int a = 5;int b = 5;if(a > 5 && b > 5)  printf("Le variabili hanno un valore maggiore di 5");else if(a < 5 && b < 5)  printf("Le variabili hanno un valore minore di 5");else  printf("La variabili non soddisfano le due precedenti condizioni");if(a > 5 || b > 5)  printf("Almeno una variabile ha un valore maggiore di 5");else if(a < 5 || b < 5)  printf("Almeno una variabile ha un valore minore di 5");else  printf("La variabili non soddisfano le due precedenti condizioni");

Inoltre possiamo verificare la diversita o l'uguaglianza di due valori tramite altri due operatori di confronto:

  • != ---> Diverso
  • == ---> Uguale

int a = 5;if(a != 5)  printf("La variabile ha un valore diverso da 5");if(a == 5)  printf("La variabile ha un valore uguale a 5");

Da notare anche che si possono verificare più di una condizione senza usare l'else ma per logica è sempre consigliato usare anche quest'ultimo.

Esiste ancora l'istruzione switch, che permette di gestire solo una variabile, impostando tutti i casi che si vogliono controllare in base al valore della variabile:

int a = 3;switch(a){  case 0:    printf("La variabile ha un valore uguale a 0");    break;  case 1:    printf("La variabile ha un valore uguale a 1");    break;  case 2:    printf("La variabile ha un valore uguale a 2");    break;  default:    printf("La variabile non ha un valore uguale a 0, 1, 2");    break;} 

Come possiamo vedere si usa l'istruzione case seguita dal valore che si vuole confrontare con quello della variabile; se i due valori risultano uguali verranno eseguite le istruzioni del case in questione.

Inoltre l'istruzione default identifica tutti i casi che non corrispondono ai case precedenti e per terminare un case si usa l'istruzione break.

I vettori

Un vettore è come un insieme di variabili, esso ha più posti ed ogni posto è occupato da un valore.

Semplicemente per definire un vettore dobbiamo specificare i posti da usare:

int vettore[5];float vector[10];

Se ci pensate succede la stessa cosa con i char con più caratteri, infatti quest'ultimi sono dei vettori.

Il numero che indica il posto del vettore si chiama indice e permette di accedere a qualsiasi cella di esso:

int vettore[5];int i = 2;int a;vettore[i] = 3;scanf("%d", &vettore[i]);printf("%d", vettore[i]);a = vettore[i];

Le matrici

Una matrice è un vettore multidimensionale, ovvero ha due serie di posti e di conseguenza due indici.

Avendo due serie di posti, per trovare il numero totale dei posti basta moltiplicare il numero della prima serie di posti per il numero della seconda serie di posti.

int matrice[5][5];int r = 2;int c = 3;int a;matrice[r][c] = 2;scanf("%d", &matrice[r][c]);printf("%d", matrice[r][c]);a = matrice[r][c];

In questo esempio la matrice avrà 25 posti.

Da notare che sia nei vettori che nelle matrici la gestione della printf e della scanf è uguale a quella per le normali variabili.

Il ciclo do - while

Quando ci troviamo a dover eseguire una stessa serie di istruzioni per più volte, al posto di riscriverle più volte possiamo usare i cicli, il primo di questi è il do - while.

Fino a quando la condizione espressa nel blocco while risulta vera la serie di istruzioni viene eseguita:

//do - while//do//{    //istruzioni da eseguire//}//while(condizione da verificare)int a = 1;do{  a = a + 1;}while(a < 10)

In questo caso finchè la variabile a sarà minore di 10 verrà incrementata di 1 ad ogni giro del ciclo.

Da notare che ad ogni giro del ciclo, le istruzioni di esso vengono eseguite una volta.

Inoltre anche se la condizione fosse falsa al primo giro, le istruzioni sarebbero comunque eseguite una volta; il ciclo do - while è infatti detto "post condizionale".

Il ciclo while

Esiste poi il ciclo while che ha la stessa funzionalità del do - while.

Le differenze sono che non è presente l'istruzione do e la condizione viene verificata già all'inizio del primo giro del ciclo:

//while//while(condizione da verificare)//{    //istruzioni da eseguire//}int a = 1;while(a < 10){  a = a + 1;}

Per cui se già all'inizio del primo giro del ciclo, la condizione fosse falsa, le istruzioni non verrebbero eseguite neanche una volta.

Il ciclo for

Il terzo ciclo è il for; esso viene usato quando si sa quante volte deve essere eseguito il ciclo.

Da questo esempio si può vedere come il ciclo for si usi molto in combinazione con i vettori e le matrici:

//for//for(variabile = valore_partenza_variabile; condizione_variabile; operazione_che viene_eseguita_sulla_variabile_ad_ogni_giro)//{    //istruzioni da eseguire//}int vettore[20];int i;int a = 20;for(i = 0; i < 21; i++){  vettore[i] = a; }

I sottoprogrammi

A volte ci troviamo nella condizione di dover eseguire una serie di istruzioni per più volte; abbiamo già visto i cicli che permettono di fare questo utilizzando le condizioni.

Se però abbiamo bisogno di fare ciò senza imporre nessuna condizione e quando vogliamo noi, dobbiamo usare un sottoprogramma.

Quest'ultimo è molto utile per tenere il codice del programma ordinato; infatti esso viene scritto fuori dal main e quando ci serve viene richiamato in quest'ultimo.

Inoltre esistono due tipi di sottoprogrammi:

  • int, char, float, double, short, long ---> restituiscono un valore, dunque alla fine di ognuno di essi c'è l'istruzione return; si chiamano funzioni
  • void ---> non restituiscono nessun valore; si chiamano procedure
void stampa(){  printf("Sei rosso");}int somma(){  int a = 2;  int b = 3;  a = a + b;  return a;}int main(){  int valore_somma = 0;  stampa();  //Richiamo la procedura stampa  valore_somma = somma();  //Richiamo la funzione somma che restituisce un valore che viene memorizzato nella variabile valore_somma  return 0;}

Se avete notato lo stesso main è una funzione, infatti restituisce 0 in modo da terminare il programma.

Il passaggio dei parametri

Prima di tutto, cosa sono i parametri ?

Sono dei valori che vengono forniti ad una funzione o ad una procedura al momento del loro richiamo.

Nel caso della printf per esempio, passiamo una stringa da stampare a video oppure una variabile:

//printf(parametro_stringa);//printf(parametro identificatore, parametro variabile);int var = 2;printf("Ciao come va ?");printf("%d", var);

Nel caso però in cui vogliamo gestire i parametri di una funzione o procedura fatta da noi, possiamo agire in due modi:

  • Per valore ---> Il valore delle variabili passate al sottoprogramma non vengono modificati, anche se si agisce sulle variabili stesse nel sottoprogramma
  • Per referenza ---> Il valore delle variabili passate al sottoprogramma può essere modificato, se si agisce su di esse
void scambio(int *a){  *a = 4; //Modifico il valore della variabile a che corrisponde alla variabile var passata per referenza}void no_scambio(int b){  b = 10;  //Anche se modifico il valore della variabile b che corrisponde alla variabile var, il valore di var non verrà modificato}int main(){  int var = 2;  no_scambio(var);  //Passo il parametro (variabile var) per valore  printf("%d", var);  scambio(&var);  //Passo il parametro (variabile var) per referenza  printf("%d", var);  return 0;}

Come possiamo vedere, per passare un parametro per referenza si usa il carattere & davanti al parametro nel main, e il carattere * davanti al parametro nel sottoprogramma.

Le strutture

Abbiamo già visto che per aggregare più valori insieme possiamo utilizzare i vettori e le matrici.

Se però abbiamo la necessità di aggregare più variabili non omogenee fra loro, dunque di tipo diverso, possiamo utilizzare le strutture:

struct elenco  //Definisco la struttura    {      char nome[10];      char cognome[10];      int matricola;    };    struct elenco list, list2;  //Definisco le variabili del tipo della struttura in modo da lavorare sopra quest'ultima

Come possiamo vedere per dichiarare una struttura si usa l'struzione struct  e successivamente bisognerà definire una variabile del tipo della struttura per poterci lavorare sopra.

Ora vediamo come accedere ed usare le variabili interne alla struttura:

strcpy(list.nome, "Luca");strcpy(list.cognome, "Rossi");list.matricola = 1;strcpy(list2.nome, "Paolo");strcpy(list2.cognome, "Polti");list2.matricola = 2;

La sintassi è semplice: nome della variabile del tipo della struttura.variabile interna alla struttura.

I file

Per rendere un programma più interattivo e più competitivo possiamo integrare la gestione dei file di testo.

Prima di tutto dobbiamo gestire l'apertura del nostro file:

FILE *fp;

Così ci siamo definiti un puntatore al file che servirà per l'apertura, la scrittura e la lettura del file.

Andiamo ora a vedere l'apertura, la scrittura e la lettura; l'apertura può avvenire in tre modi:

  • r ---> in lettura; se dobbiamo solo svolgere operazioni di lettura sul file
  • w ---> in scrittura; se dobbiamo solo svolgere operazioni di scrittura sul file
  • a ---> in scrittura al fondo del file; se dobbiamo solo svolgere operazioni di scrittura sul file

Per l'apertura utilizziamo dunque l'istruzione fopen:

//puntatore_file = fopen("nome_file.txt", "modalità_apertura");fp = fopen("record.txt", "r");fp = fopen("record.txt", "w");fp = fopen("record.txt", "a");

Passiamo ora alla scrittura, usando l'istruzione fprintf che utilizza gli stessi identificatori della printf:

//fprintf(puntatore_file,"identificatori_variabili", variabili);FILE *fp;int num, anni;char nome[10], descrizione[10];fp = fopen("record.txt", "w");strcpy(nome, "Gianni");strcpy(descrizione, "Impiegato");num = 1;anni = 40;fprintf(fp, "%d %s %s %d", num, nome, descrizione, prezzo);

Infine vediamo la lettura che è l'operazione più lunga, e si esegue tramite l'istruzione fscanf, che usa sempre gli stessi identificatori e regole della scanf:

//fscanf(puntatore_file,"identificatori_variabili", &variabili_numeriche_e_carattere_singolo, variabili_più_caratteri);FILE *fp;int num, anni;char nome[10], descrizione[10];fp = fopen("record.txt", "r");fscanf(fp, "%d %s %s %d", &num, nome, descrizione, &prezzo);  //Faccio la prima fscanf per liberare la letturawhile(!feof(fp)){  fscanf(fp, "%d %s %s %d", &num, nome, descrizione, &prezzo);  //Porto il contenuto della riga del file nelle varibili del programma  printf("%d %s %s %d", num, nome, descrizione, prezzo);}

Come possiamo vedere per leggere un intero file si usa un ciclo dato che ogni fscanf legge una riga; si usa l'istruzione feof che indica la fine del file.

Inoltre si può vedere come si debba fare una fscanf prima del ciclo, per tenere la lettura del file pulita.

In verità la lettura porta il contenuto del file nelle variabili del programma e poi stampa le variabili a schermo.

Da ricordare bene, la posizione degli identificatori della fscanf deve essere scritta esattamente come sono posizionati i valori sul file.

C'è ancora una funzione che viene utilizzata per chiudere l'apertura del file, si chiama fclose:

//fclose(puntatore_file);fclose(fp);

La fclose è molto utile se dobbiamo passare da una modalità di apertura del file ad un'altra; per esempio da scrittura a lettura.

Infatti apriremo il file in modalità di scrittura, poi chiuderemo l'apertura e poi riapriremo il file in modalità di lettura.

E' sempre buona regola chiudere l'apertura del file prima che il programma termini.

Il casting

A volte potremmo avere la necessità di convertire una variabile in un altro tipo; questo perchè certe istruzioni accettano solo determinati tipi di variabili oppure perchè dobbiamo copiare un tipo di dato in una variabile di diverso tipo.

Vediamo un esempio:

int intero;float reale;reale = 20.35;intero = (int) reale;  //Il valore di intero sarà 20, dato che reale è stato considerato un int e così ha perso la parte decimale

In questo modo forziamo la conversione temporanea della variabile reale, che è di tipo float, al tipo int; in questo modo la copia nella variabile intero potrà avvenire senza problemi.

La visibilità delle variabili

Fin ora quando abbiamo definito le variabili lo abbiamo sempre fatto nel main o in un sottoprogramma.

Ciò di cui non abbiamo ancora parlato è la visibilità delle variabili che si divide in due rami:

  • Locali ---> Le variabili definite nel main sono visibili ed utilizzabili solo nel main, quelle definite in un sottoprogramma sono visibili ed utilizzabili solo in quel sottoprogramma
  • Globali ---> Le variabili sono definite fuori dal main e dai sottoprogrammi; possono essere utilizzate in tutto il programma
#include <stdio.h>#include <stdlib.h>int a = 5, b = 6;  //Variabili globali visibili in tutto il programmaint somma(){  int c;  //Variabile locale alla funzione somma  c = a + b;  return c;}int main(){  int d = 0;  //Variabile locale al main  d = somma();  printf("La somma e' %d", d);  return 0;}

Le costanti

In C oltre alle variabili è possibile definire delle costanti che come dice il nome non possono cambiare valore.

//#define nome_costante valore_costante#include <stdio.h>#define COSTANTE 2int main(){  int costant;  costant = COSTANTE;  return 0;}

Come possiamo vedere, per definire una costante si utilizza l'istruzione #define seguita dal nome e dal valore da attribuire alla costante.

Il vantaggio, se così si può considerare, rispetto ad una variabile è che non si rischia di modificare il valore inavvertitamente.

Documentazione

Elenco delle funzioni in lingua italiana ---> http://msdn.microsoft.com/it-it/library/634ca0c2.aspx

Elenco delle funzioni in lingua inglese ---> http://msdn.microsoft.com/en-us/library/634ca0c2.aspx

 

lh1s.gif

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Complimenti innanzitutto per l'impegno nel scrivere un papiro così! ;) Una guida veloce ed essenziale senza dubbio, che per quanto possa risultare molto semplice per uno come me spero possa esser d'aiuto a chi si sta approcciando a questo linguaggio. :sasa:

 

Per il resto ti auguro buona fortuna nella stesura. :zizi:

 

P.S.

Nella descrizione dello scanf c'è un errore di battitura: biosgna;

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Per chi ne capisce non è di difficile comprensione. Per chi non ne capisce ci vorrebbe un approccio ancor più soft credo :soso:

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Io ho capito tutto. Il problema é che magari ad alcuni necessiteranno alcune nozioni ancor più basilari. Tipo per nabbissimi

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Io ho capito tutto. Il problema é che magari ad alcuni necessiteranno alcune nozioni ancor più basilari. Tipo per nabbissimi

 

Cerco di renderla il più comprensibile possibile.

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Ottima guida Pez complimenti ^_^ termini ottimi, anche per chi conosce poco, e sei partito dalle nozioni basilari ^_^

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

A tua discrezione .... Secondo me viene più intuitivo :ahsi:

Inviato dal mio Galaxy Nexus con Tapatalk 2

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

@Pez_93 Si, lo spoiler è anche meglio. Così è meno confusionario per gestire i passaggi

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Ottima, ottima, ottima guida!
Te ne ringrazio già da adesso se mi servirà da ripasso :zuzu:
Ma senza offesa:

Mille volte meglio Java :asd:

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Non é che ora, ogni volta che leggete guide su C , dovete dire meglio java XD

:P

Inviato dal mio Galaxy Nexus con Tapatalk 2

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Pez ma come per php non c'è un sito di documentazione dove ci sono l'elenco delle funzioni ecc...?

Pensavo di vedere in fondo al topic qualche sito, che consigli, per apprendere anche il resto. È un ottimo inizio!

Condividi questo messaggio


Link di questo messaggio
Condividi su altri siti

Crea un account o accedi per lasciare un commento

You need to be a member in order to leave a comment

Crea un account

Iscriviti per un nuovo account nella nostra community. È facile!


Registra un nuovo account

Accedi

Sei già registrato? Accedi qui.


Accedi Ora