Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
vuoi
o PayPal
tutte le volte che vuoi
Il linguaggio C
Il C esegue meno controlli sul programma rispetto agli altri linguaggi ad alto livello. Ciò facilita la scrittura di routine di accesso a basso livello e consente di avere eseguibili più veloci.
Di contro è più facile commettere errori, spesso rilevabili solo al momento dell'esecuzione.
Il C risulta meno leggibile di altri linguaggi. Per questo motivo è opportuno inserire sempre dei commenti all'interno del programma.
Struttura di un programma C
Un programma C è composto dalle seguenti parti:
- una intestazione destinata al preprocessore;
- un insieme di dichiarazioni di variabili globali;
- un insieme di dichiarazioni di funzioni;
- il corpo principale del programma, identificato con la parola chiave main.
Alcune di queste parti possono essere omesse, tranne l'ultima.
Struttura di un programma C
/* esempio */******************************************* questo programma scrive "Hello world" *******************************************/#include /* direttiva per il preprocessore */main() /* corpo principale */{ printf("hello world \n");}Note:
I commenti sono sempre racchiusi tra le coppie /* e */.È possibile utilizzare più di una riga per un unico commento.
Il corpo principale del programma è inserito all'interno della funzione main.
I tipi in C
In C tutte le variabili che verranno utilizzate devono esseredefinite obbligatoriamente, specificandone il tipo.
La sintassi del C presenta alcuni tipi base ed una serie dimodificatori da applicare ai tipi base.
Tipi base- void
- char - un singolo carattere (8 bit)
- int - una word (16 o 32 bit)
- float - numero reale in singola precisione (4 byte)
- double - numero reale in doppia precisione (8 byte)
- long
- signed
- unsigned
Strutture di controllo
L'istruzione break fa uscire dall'intero ciclo più interno, interrompendo il normale flusso di controllo.
L'istruzione continue fa saltare direttamente al termine del ciclo corrente, per effettuare un nuovo controllo della condizione del ciclo.
Strutture di controllo
/* esempio */#define ERROR 100#define SKIP 200int i,j;for(i=0; i<100; ++i){ ... j = ... if ( j == ERROR ) break; if ( j == SKIP ) continue; ...}...Se j=ERROR si esce dal ciclo for, anche se i<100.Se j=SKIP l'iterazione corrente viene ultimata, saltando le istruzioni seguenti, per ricominciare con la successiva iterazione (con i=i+1).
Le istruzioni break e continue possono essere presenti anche all'interno di cicli while, do..while, switch.
Gli array
È possibile anche definire array di record.
/* esempio */struct persona{ float altezza; int peso;} PERSONA[100];In questo caso si accede ai singoli campi con la seguente sintassi:PERSONA[10].peso = ...
Gli array
La dimensione di un array deve essere nota in fase di compilazione
/* esempi di definizione errata */int N=10;double x[N]; /* errato */void proc (int N){ double a[N]; /* errato */ ...}/* definizione corretta */#define N 10double x[N];Le macro
Si possono definire anche parametri per la macro.
#define area(x) (3.1415 * x * x)main(){ printf("%f /n",area(10.0)); }La macro precedente viene espansa in:
main(){ printf("%f /n", (3.1415 * 10.0 * 10.0)); }Note:1) tra area e (x) non c'è nessuno spazio2) in questo caso è utile racchiudere la seconda stringa tra parentesi
Le macro
A volte una stessa macro può risultare corretta o errata a seconda di comeviene utilizzata.
/* errato */#define quad(x) x * xmain(){ printf("%f",100 / quad(2)); }Viene espansa in:
100.0 / 2 * 2
che dà come risultato 100. Invece la definizione corretta è la seguente:
/* esatto */#define quad(x) (x * x)main(){ printf("%f",100 / quad(2)); }100.0 / (2 * 2)
Esempio
/*******************************************//* program grep.c *//*******************************************/#include <stdio.h>#define MAXLINE 1000
int GetLine(char [], int );int FindSubString(char [], char []);
char pattern[] = "if"; /* qui va inserito il pattern da ricercare */
main(){ char line[MAXLINE]; /* buffer per contenere la stringa letta */ while ( GetLine(line, MAXLINE) > 0 ) if ( FindSubString(line, pattern) >= 0 ) printf("%s",line) ;}
Esempio
int GetLine(char stringa[], int limite){ int c, i=0 ; while (--limite>0 && (c=getchar())!=EOF && c!='\n' ) stringa[i++] = c ; if (c == '\n') stringa[i++] = c; /* carattere di fine riga */ stringa[i] = 0; /* terminazione di una stringa in C */ return i; /* numero di caratteri nella stringa */}
int FindSubString(char stringa[], char sub[]){ int i, k ; for (i=0; stringa[i]!=0; ++i) /* scorre la prima stringa */ { for(k=0; sub[k]!=0 && stringa[i+k]==sub[k]; ++k); if (k>0 && sub[k]==0) return i; /* la stringa e' stata trovata */ } return -1; /* la stringa non e' stata trovata */}
Allocazione dello spazio di memoria
Per ogni variabile definita nel programma, il compilatore riserva lo spazio necessario per contenerne il valore.
Esempio:
- int j; il compilatore alloca automaticamente lo spazio necessario per la variabile int (2 o 4 byte).
- int a[100]; il compilatore riserva 100 x sizeof(int) byte di memoria.
- int *i; il compilatore alloca solo lo spazio per memorizzare il valore del puntatore (4 byte). Lo spazio per la variabile puntata deve invece essere riservato manualmente dall'utente.
In memoria abbiamo il seguente schema:
NOTA
Utilizzando i puntatori è di fondamentale importanza verificare sempre che la zona di memoria da essi indirizzata sia stata esplicitamente riservata da qualcuno (S.O. o programma utente).
La maggior parte degli errori che si verificano run-time sono dovuti ad indirizzamenti con puntatori non inizializzati.
L'utilizzo di un puntatore non corretto provoca, generalmente, un errore di segmentation fault.
Esempio: funzione che copia una stringa in un'altra.
void strcpy(char *dest, char *src){ int i=0; if(dest==NULL || src==NULL) return; while(src[i] != 0) { dest[i] = src[i]; ++i; } dest[i]=0;}Esempio: funzione che copia una stringa in un'altra.
void strcpy(char *dest, char *src){ int i=0; if(dest==NULL || src==NULL) return; while((dest[i]=src[i]) != 0) ++i;}Questa versione usa direttamente i puntatori. In uscita i valori di src e dest rimangono immutati.
void strcpy(char *dest, char *src){ if(dest==NULL || src==NULL) return; while((*dest = *src) != 0) { src++; dest++; }}