Operatori Aritmetici

OperatoreNomeEsempioRisultato
+Addizione5 + 38
-Sottrazione5 - 32
*Moltiplicazione5 * 315
/Divisione7 / 23 (intera!)
%Modulo (resto)7 % 21
COperatori aritmetici in azione
#include <stdio.h>

int main() {
    int a = 17, b = 5;

    printf("a + b = %d\n", a + b);  // 22
    printf("a - b = %d\n", a - b);  // 12
    printf("a * b = %d\n", a * b);  // 85
    printf("a / b = %d\n", a / b);  // 3 (divisione intera!)
    printf("a %% b = %d\n", a % b); // 2 (resto)

    // Divisione reale: almeno uno deve essere double
    printf("a / b (reale) = %.2f\n", (double)a / b); // 3.40

    // Operatori di incremento e decremento
    int x = 10;
    printf("x++  = %d\n", x++);  // Stampa 10, poi x diventa 11
    printf("x ora = %d\n", x);   // 11
    printf("++x  = %d\n", ++x);  // x diventa 12, stampa 12
    printf("x--  = %d\n", x--);  // Stampa 12, poi x diventa 11

    return 0;
}
Suggerimento Il modulo % è utilissimo: n % 2 == 0 controlla se n è pari. n % 10 dà l'ultima cifra di n. n % k produce valori da 0 a k-1.

Operatori di Assegnamento Composto

Abbreviazioni molto usate per modificare una variabile:

OperatoreEquivalente a
x += 5x = x + 5
x -= 3x = x - 3
x *= 2x = x * 2
x /= 4x = x / 4
x %= 3x = x % 3

Operatori Relazionali

Confrontano due valori e restituiscono 1 (vero) o 0 (falso).

OperatoreSignificatoEsempioRisultato
==Uguale a5 == 51
!=Diverso da5 != 31
>Maggiore di5 > 31
<Minore di5 < 30
>=Maggiore o uguale5 >= 51
<=Minore o uguale4 <= 51
Errore classico Non confondere = (assegnamento) con == (confronto)! Scrivere if (x = 5) assegna 5 a x e la condizione è sempre vera. Sempre usare == nei confronti.

Operatori Logici

OperatoreNomeDescrizioneEsempio
&&AND logicoVero se ENTRAMBI sono veri(a>0) && (b>0)
||OR logicoVero se ALMENO UNO è vero(a>0) || (b>0)
!NOT logicoNega la condizione!(a == 0)
COperatori logici e short-circuit
#include <stdio.h>

int main() {
    int eta = 20;
    int ha_patente = 1;  // 1 = true, 0 = false

    // AND: entrambe le condizioni devono essere vere
    if (eta >= 18 && ha_patente) {
        printf("Può guidare\n");
    }

    // OR: almeno una condizione deve essere vera
    int pioggia = 0, vento = 1;
    if (pioggia || vento) {
        printf("Tempo brutto\n");
    }

    // NOT
    int loggato = 0;
    if (!loggato) {
        printf("Utente non loggato\n");
    }

    // Short-circuit evaluation:
    // Se la prima parte di && è falsa, la seconda NON viene valutata
    int n = 0;
    if (n != 0 && (10 / n > 1)) {  // Sicuro! Non divide per zero
        printf("Questo non stampa\n");
    }

    return 0;
}

Operatori Bitwise (su bit)

Lavorano direttamente sui bit di un valore intero. Fondamentali nella programmazione a basso livello, sistemi embedded e ottimizzazioni.

OperatoreNomeDescrizione
&AND bit a bit1 solo se entrambi i bit sono 1
|OR bit a bit1 se almeno un bit è 1
^XOR bit a bit1 se i bit sono diversi
~NOT bit a bitInverte tutti i bit
<<Shift sinistroSposta i bit a sinistra (×2 per ogni posizione)
>>Shift destroSposta i bit a destra (÷2 per ogni posizione)
COperatori bitwise
#include <stdio.h>

int main() {
    unsigned char a = 0b11001010;  // 202 in decimale
    unsigned char b = 0b10110101;  // 181 in decimale

    printf("a       = %d  (0b11001010)\n", a);
    printf("b       = %d  (0b10110101)\n", b);
    printf("a & b   = %d\n", a & b);   // AND
    printf("a | b   = %d\n", a | b);   // OR
    printf("a ^ b   = %d\n", a ^ b);   // XOR
    printf("~a      = %d\n", (unsigned char)~a);  // NOT

    // Shift: veloce per moltiplicare/dividere per potenze di 2
    int x = 8;
    printf("\n%d << 1 = %d (x2)\n",  x, x << 1);  // 16
    printf("%d << 2 = %d (x4)\n",   x, x << 2);  // 32
    printf("%d >> 1 = %d (/2)\n",   x, x >> 1);  // 4

    // Usare i flag con OR/AND
    unsigned char flags = 0;
    flags |= (1 << 0);  // Imposta bit 0 (FLAG_A)
    flags |= (1 << 2);  // Imposta bit 2 (FLAG_C)
    printf("\nFlags: 0b%d%d%d%d\n",
        (flags >> 3) & 1, (flags >> 2) & 1,
        (flags >> 1) & 1, (flags >> 0) & 1);
    printf("Bit 0 attivo? %s\n", (flags & (1 << 0)) ? "Sì" : "No");
    printf("Bit 1 attivo? %s\n", (flags & (1 << 1)) ? "Sì" : "No");

    return 0;
}

Operatore Ternario

È un if/else compatto su una sola riga: condizione ? valore_se_vero : valore_se_falso

COperatore ternario ?:
#include <stdio.h>

int main() {
    int a = 10, b = 20;

    // Versione con if/else
    int max;
    if (a > b) max = a;
    else max = b;

    // Versione compatta con operatore ternario
    int massimo = (a > b) ? a : b;
    int minimo  = (a < b) ? a : b;

    printf("Max: %d, Min: %d\n", massimo, minimo);

    // Usato in printf direttamente
    int n = 7;
    printf("%d è %s\n", n, (n % 2 == 0) ? "pari" : "dispari");

    int voto = 28;
    printf("Voto %d: %s\n", voto, (voto >= 18) ? "PASSATO" : "BOCCIATO");

    return 0;
}

Precedenza degli Operatori

Come nella matematica, alcuni operatori hanno priorità maggiore di altri. Usa le parentesi per essere esplicito.

PrioritàOperatoriAssociatività
Alta() [] . ->Sinistra→Destra
! ~ ++ -- (unari)Destra→Sinistra
* / %Sinistra→Destra
+ -Sinistra→Destra
<< >>Sinistra→Destra
< <= > >=Sinistra→Destra
== !=Sinistra→Destra
&Sinistra→Destra
^Sinistra→Destra
|Sinistra→Destra
&&Sinistra→Destra
||Sinistra→Destra
?:Destra→Sinistra
Bassa= += -= *= /= %=Destra→Sinistra
🏋️ Esercizi
Pratica con tutti i tipi di operatori.
1
Parità e divisibilità
Facile%

Leggi un numero intero e stampa: se è pari o dispari, se è divisibile per 3, se è divisibile per 5, se è divisibile per entrambi (FizzBuzz).

C
#include <stdio.h>

int main() {
    int n;
    printf("Inserisci un numero: ");
    scanf("%d", &n);

    printf("%d è %s\n", n, (n % 2 == 0) ? "PARI" : "DISPARI");
    printf("Divisibile per 3? %s\n", (n % 3 == 0) ? "Sì" : "No");
    printf("Divisibile per 5? %s\n", (n % 5 == 0) ? "Sì" : "No");

    if (n % 3 == 0 && n % 5 == 0) printf("FizzBuzz!\n");
    else if (n % 3 == 0) printf("Fizz!\n");
    else if (n % 5 == 0) printf("Buzz!\n");

    return 0;
}
2
Massimo tra tre numeri
FacileTernario

Leggi tre interi a, b, c. Usa l'operatore ternario (senza if/else) per trovare e stampare il massimo tra i tre.

Puoi annidare gli operatori ternari: (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c)
C
#include <stdio.h>

int main() {
    int a, b, c;
    printf("Inserisci tre interi: ");
    scanf("%d %d %d", &a, &b, &c);

    int max = (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c);
    printf("Massimo tra %d, %d, %d = %d\n", a, b, c, max);

    return 0;
}
3
Calcolatrice shift
MedioBitwise / Shift

Leggi un intero positivo. Stampa le potenze di 2 da 2⁰ a 2¹⁰ usando SOLO l'operatore di shift a sinistra << (non usare pow o moltiplicazioni). Poi verifica se il numero letto è una potenza di 2 usando il trucco bitwise: n & (n-1) == 0.

C
#include <stdio.h>

int main() {
    int n;
    printf("Inserisci un intero positivo: ");
    scanf("%d", &n);

    printf("\nPotenze di 2 con shift:\n");
    for (int i = 0; i <= 10; i++) {
        printf("2^%2d = %d\n", i, 1 << i);
    }

    if (n > 0 && (n & (n - 1)) == 0) {
        printf("\n%d È una potenza di 2!\n", n);
    } else {
        printf("\n%d NON è una potenza di 2.\n", n);
    }

    return 0;
}
4
Swap senza variabile temporanea
MedioXOR

Leggi due interi. Scambia il loro valore usando il trucco XOR (senza usare una variabile temporanea): a ^= b; b ^= a; a ^= b;. Verifica che funzioni stampando prima e dopo.

C
#include <stdio.h>

int main() {
    int a, b;
    printf("Inserisci a e b: ");
    scanf("%d %d", &a, &b);

    printf("Prima:  a=%d, b=%d\n", a, b);

    // Swap con XOR (senza variabile temporanea)
    a ^= b;
    b ^= a;
    a ^= b;

    printf("Dopo:   a=%d, b=%d\n", a, b);
    return 0;
}
5
Manipolazione di bit
DifficileBitwise avanzato

Crea un programma che gestisca permessi Unix-style usando 3 bit (r=bit2, w=bit1, x=bit0). Il programma deve: impostare un permesso, rimuovere un permesso, controllare se un permesso è attivo, e stampare la rappresentazione rwx (con - se il bit è 0). Leggi l'input come stringa "rwx", "r--", "rw-", etc.

C
#include <stdio.h>

#define BIT_R 4  // 0b100
#define BIT_W 2  // 0b010
#define BIT_X 1  // 0b001

void stampa_permessi(unsigned char p) {
    printf("%c%c%c\n",
        (p & BIT_R) ? 'r' : '-',
        (p & BIT_W) ? 'w' : '-',
        (p & BIT_X) ? 'x' : '-');
}

int main() {
    unsigned char perm = 0;

    // Aggiungi lettura ed esecuzione
    perm |= BIT_R;
    perm |= BIT_X;
    printf("Dopo r+x: ");
    stampa_permessi(perm);

    // Aggiungi scrittura
    perm |= BIT_W;
    printf("Dopo +w:  ");
    stampa_permessi(perm);

    // Rimuovi esecuzione
    perm &= ~BIT_X;
    printf("Dopo -x:  ");
    stampa_permessi(perm);

    // Verifica permessi
    printf("Lettura attiva?   %s\n", (perm & BIT_R) ? "Sì" : "No");
    printf("Scrittura attiva? %s\n", (perm & BIT_W) ? "Sì" : "No");
    printf("Esecuzione attiva?%s\n", (perm & BIT_X) ? "Sì" : "No");

    return 0;
}