Panoramica del linguaggio C
C (ANSI C99 / C11) — linguaggio di sistema | autonomia minima | memoria manuale | controllo massimo
Paradigma
Imperativo, procedurale. Tipizzazione statica con sistema di tipi deboli (conversioni implicite, void*). Compilazione tramite preprocessore → compilatore → assembler → linker. Compilazione a passaggio singolo, basata su unità di traduzione.
Tipi
| Categoria | Tipi | Dimensioni (tipiche) |
|---|---|---|
| car | char |
1 byte |
| Firmato int | signed char short int long long long |
1, 2, 4, 8, 8 byte |
| Intero non firmato | unsigned char unsigned short unsigned int unsigned long unsigned long long |
1, 2, 4, 8, 8 byte |
| Galleggiante | float double long double |
4, 8, 8-16 byte |
| Bool (C99) | _Bool / bool (tramite <stdbool.h>) |
1 byte |
| Vuoto | void |
0 (incompleto) |
| Puntatore | T* |
8 byte (64 bit) |
| Matrice | T[N] T[] |
N * dimensione(T) |
| Struttura | struct Name { ... } |
Somma dei campi + riempimento |
| Unione | union Name { ... } |
Numero massimo di campi |
| Enum | enum Name { ... } |
dimensione(int) |
| Puntatore di funzione | T (*)(args) |
8 byte |
Modificatori di tipo
const volatile restrict (C99) inline (C99)
Specificatori della classe di archiviazione
auto register static extern _Thread_local (C11)
Dichiarazioni
| Costruisci | Sintassi | Note |
|---|---|---|
| Funzione | T name(params) { body } |
|
| Prototipo | T name(params); |
Dichiarazione senza corpo |
| Variabile | T x = expr; |
|
| Molteplici | T x, y, z; |
|
| Costante | const T x = expr; |
|
| Costante di enumerazione | enum { VAL = expr }; |
|
| Typedef | typedef T Alias; |
|
| Struttura | struct Name { T field; }; |
|
| Unione | union Name { T field; }; |
|
| Esterno | extern T name; |
Definito in un'altra TU |
| Statico | static T name; |
Collegamento interno |
Flusso di controllo
| Costruisci | Sintassi | Note |
|---|---|---|
| Se | if (cond) { ... } else { ... } |
Dichiarazione, non espressione |
| Mentre | while (cond) { ... } |
|
| Fatelo nel frattempo | do { ... } while (cond); |
|
| Per | for (init; cond; incr) { ... } |
|
| Cambia | switch (expr) { case N: ... break; } |
Fall-through per impostazione predefinita |
| Pausa | break; |
Esci da loop/switch |
| Continua | continue; |
Passa all'iterazione successiva |
| Vai a | goto label; |
Solo all'interno della funzione |
| Ritorno | return expr; |
Operatori (precedenza, dal più alto al più basso)
| Precedenza | Operatori | Ass |
|---|---|---|
| 1 | () [] . -> ++ -- (postfisso) |
A sinistra |
| 2 | ++ -- (prefisso) + - ! ~ * & sizeof _Alignof |
Giusto |
| 3 | (type) (fuso) |
Giusto |
| 4 | * / % |
A sinistra |
| 5 | + - |
A sinistra |
| 6 | << >> |
A sinistra |
| 7 | < > <= >= |
A sinistra |
| 8 | == != |
A sinistra |
| 9 | & |
A sinistra |
| 10 | ^ |
A sinistra |
| 11 | | |
A sinistra |
| 12 | && |
A sinistra |
| 13 | || |
A sinistra |
| 14 | ? : (ternario) |
Giusto |
| 15 | = += -= *= /= %= &= ^= |= <<= >>= |
Giusto |
| 16 | , (operatore virgola) |
A sinistra |
Preprocessore
| Direttiva | Scopo |
|---|---|
#include "file" / <file> |
Inclusione testuale |
#define MACRO body |
Macro simile a un oggetto |
#define MACRO(args) body |
Macro simile a una funzione |
#undef MACRO |
Rimuovi la macro |
#if expr / #ifdef MACRO / #ifndef MACRO |
Compilazione condizionale |
#elif expr / #else / #endif |
Altri rami |
#error "message" |
Errore in fase di compilazione |
#pragma |
Definito dall'implementazione |
#line N "file" |
Controllo della linea |
## (incolla token) |
Concatena i token |
# (stringificare) |
Converti in stringa letterale |
Macro predefinite (C99)
__LINE__ __FILE__ __DATE__ __TIME__ __STDC__ __STDC_VERSION__ __func__
Memoria
| Operazione | Sintassi | Intestazione |
|---|---|---|
| Assegnare | malloc(n) |
<stdlib.h> |
| Allocazione allineata (C11) | aligned_alloc(a, n) |
<stdlib.h> |
| Calloc | calloc(n, size) |
<stdlib.h> |
| Rialloc | realloc(p, n) |
<stdlib.h> |
| Gratuito | free(p) |
<stdlib.h> |
| Copia | memcpy(dst, src, n) |
<string.h> |
| Sposta (sovrapposizione sicura) | memmove(dst, src, n) |
<string.h> |
| Impostato | memset(p, c, n) |
<string.h> |
| Confronta | memcmp(a, b, n) |
<string.h> |
| Pila | alloca(n) (non standard) |
<alloca.h> |
Libreria standard (selezionata)
<stdio.h>
printf scanf fopen fclose fread fwrite fprintf sprintf fgets fputs feof ferror remove rename tmpfile
<stdlib.h>
atoi atof strtol strtod rand srand abs qsort bsearch system getenv exit abort atexit
<string.h>
strlen strcpy strncpy strcat strncat strcmp strncmp strchr strrchr strstr strtok memset memcpy memmove memcmp
<math.h>
sin cos tan asin acos atan atan2 sqrt pow exp log log10 fabs ceil floor fmod fma
<time.h>
time clock difftime mktime strftime localtime gmtime
<assert.h>
assert(expr)
<stdint.h> (C99)
int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t intptr_t uintptr_t size_t
<stdbool.h> (C99)
bool true false
Compilazione
| Passo | Comando | Uscita |
|---|---|---|
| Preelaborazione | cpp file.c > file.i |
Fonte estesa |
| Compilare | cc -S file.c |
Assemblaggio (file.s) |
| Assemblare | cc -c file.c |
Oggetto (file.o) |
| Collegamento | cc file.o -o prog |
Eseguibile (prog) |
| Tutto in uno | cc file.c -o prog |
Eseguibile diretto |
Bandiere comuni
-O0 -O1 -O2 -O3 -Os -g -Wall -Wextra -Wpedantic -std=c99 -std=c11 -DNAME=val -Ipath -Lpath -llib
Catena di strumenti
GCC (GNU), Clang/LLVM, MSVC (Windows), TinyCC, CompCert
Durata della conservazione
| Durata | Assegnazione | A vita |
|---|---|---|
| Automatico | Pila | Ambito |
| Statico | Segmento dati | Durata del programma |
| Thread locale (C11) | TLS | Durata del thread |
| Assegnato | Mucchio (malloc/free) |
Manuale |
Collegamento
| Parola chiave | Collegamento | Visibilità |
|---|---|---|
| (nessuno, ambito del file) | Esterno | Intero programma |
static (ambito del file) |
Interno | Unità di traduzione attuale |
extern |
Esterno | Intero programma |
static inline (C99) |
Interno | TU attuale (no fuori linea) |
Comportamento indefinito (insidie selezionate)
- Overflow del buffer (indice dell'array fuori dai limiti)
- Utilizzare dopo-libero/doppio-gratuito
- Overflow di numeri interi con segno
- Dereferenziazione del puntatore NULL
- Divisione per zero
- Violazione severa dell'aliasing
- Indirizzo di ritorno della variabile automatica
- Modifica della stringa letterale
- Corsa ai dati (accesso simultaneo non sincronizzato)
- Sposta di >= larghezza del testo
C99 vs C11 vs C17 vs C23
| Norma | Aggiunte chiave |
|---|---|
| C89/ANSI C | Norma originale |
| C99 | // commenti, stdint.h, bool, restrict, inline, macro variadici, inizializzatori designati, valori letterali composti, for-dichiarazioni di ambito |
| C11 | _Generic, _Static_assert, _Alignas, _Alignof, _Atomic, _Thread_local, anonimo structs/unions, noreturn, interfacce con controllo dei limiti (allegato K) |
| C17 | Versione con correzione di bug (nessuna nuova funzionalità) |
| C23 (bozza) | typeof, nullptr, #embed, bool come parola chiave, static_assert senza _, constexpr, auto per l'inferenza del tipo |
Idiomi C comuni
Puntatore opaco (incapsulamento)
// header
typedef struct Handle Handle;
Handle* handle_create(void);
void handle_destroy(Handle*);
// implementation
struct Handle { int fd; };
Richiamata (puntatore a funzione)
void sort(int* arr, int n, int (*cmp)(int, int));
Orientato agli oggetti (vtable manuale)
struct Vtable { void (*draw)(void*); };
struct Shape { struct Vtable* vtable; };
Generico (void* + puntatore a funzione)
void qsort(void* base, size_t n, size_t size,
int (*cmp)(const void*, const void*));