Cours programmation en langage C - Chapitre 2 : Opérateurs et expressions

Ce cours s’adresse aux étudiants de première année en informatique et couvre les opérateurs et expressions en langage C. Il présente les différents types d’opérateurs, leurs priorités, les conversions de types automatiques et forcées, ainsi que les fonctions mathématiques prédéfinies utiles en programmation C.

D'après le document Cours programmation en langage C - Chapitre 2 : Opérateurs et expressions

Cet article a été rédigé automatiquement à partir du document source, puis vérifié avant publication.

Document source

Afficher l'aperçu du document

Consulter le document original →

Ce cours s’adresse aux étudiants de première année en informatique et couvre les opérateurs et expressions en langage C. Il présente les différents types d’opérateurs, leurs priorités, les conversions de types automatiques et forcées, ainsi que les fonctions mathématiques prédéfinies utiles en programmation C.

Les opérateurs arithmétiques en C

Le langage C dispose d’opérateurs classiques binaires, qui agissent sur deux opérandes : + (addition), - (soustraction), * (multiplication), / (division), ainsi que d’opérateurs unaires, qui agissent sur un seul opérande : - (opposé), + (identité).

Exemple d’opérateur unaire :

-a ; +a

Le modulo, noté %, est un opérateur binaire qui ne s’applique qu’aux entiers et retourne le reste de la division entière.

Exemple :

5 / 2 = 2  (division entière)
5.0 / 2.0 = 2.5  (division flottante)
5 % 2 = 1  (reste de la division entière)

Il n’existe pas d’opérateur d’élévation à la puissance en C. Pour calculer x^3, il faut écrire x * x * x ou utiliser la fonction pow de la bibliothèque math.h.

#include <stdio.h>
#include <math.h>
void main() {
    int x = 3, y;
    y = pow(x, 4);
    printf("la puissance est %d", y);
}

Exécution : la puissance est 81

Autre exemple avec la racine carrée :

#include <stdio.h>
#include <math.h>
void main() {
    unsigned int x;
    float y;
    printf("saisir un entier positif");
    scanf("%d", &x);
    y = sqrt(x);
    printf("la racine carrée de %d est %f", x, y);
}

Exécution : saisir un entier positif 4
La racine carrée de 4 est 2.000000

Priorités relatives des opérateurs

Lorsque plusieurs opérateurs apparaissent dans une même expression, il faut connaître leur ordre d’évaluation :

  • Les opérateurs unaires + (identité) et - (opposé) ont la priorité la plus forte.
  • Ensuite viennent *, / et %.
  • Enfin, les opérateurs binaires + et -.

En cas de priorité identique, l’évaluation se fait de gauche à droite.

Les parenthèses permettent de modifier cet ordre.

Conversions implicites dans les expressions

Les opérateurs peuvent s’appliquer à des opérandes de types différents. Le compilateur effectue alors des conversions automatiques selon les règles suivantes :

  • Pour une opération entre deux entiers, les types char et short sont d’abord convertis en int. Puis, le type le plus large est choisi parmi int, unsigned int, long, unsigned long.
  • Pour une opération entre un entier et un flottant, l’entier est converti en flottant.
  • Pour une opération entre deux flottants, le type le plus large est choisi parmi float, double, long double.
  • Lors d’une affectation, le résultat est converti dans le type de la variable cible, ce qui peut entraîner une perte de précision.

Exemple :

#include <stdio.h>
void main() {
    int n = 2, p = 3;
    float x = 2.0, z;
    z = n * x + p;
    printf("%f", z);
}

Exécution : 7.000000
Le compilateur convertit n en float avant le calcul.

Exemple d’affectations :

char A = 3;
int B = 4;
float C = 4;
float D, E;
char F;

D = A / C;  // A converti en float, résultat 0.75
E = A / B;  // A converti en int, division entière 0, converti en float 0.0
F = A / C;  // résultat float 0.75 converti en char, valeur 0

Le cas du type char

Le type char est systématiquement converti en int lors des opérations. Une variable de type caractère peut être vue comme :

  • Le caractère lui-même (ex. 'A', 'z', '\n')
  • Le code ASCII correspondant (ex. 'A' = 65)

Exemple d’affichage :

#include <stdio.h>
void main() {
    char x = 'A';
    printf("%c", x);  // affiche A
    printf("%d", x);  // affiche 65
}

On peut aussi afficher un caractère à partir d’un entier :

#include <stdio.h>
void main() {
    int x = 65;
    printf("%c", x);  // affiche A
}

Exemple d’incrémentation :

#include <stdio.h>
void main() {
    char x = 'A';
    printf("le code ASCII de %c est %d   ", x, x);
    x = x + 1;
    printf("le code ASCII de %c est %d", x, x);
}

Exécution : le code ASCII de A est 65 le code ASCII de B est 66

Quelques codes ASCII usuels :

  • '0' = 48
  • '1' = 49
  • 'A' = 65
  • 'B' = 66
  • 'a' = 97
  • 'b' = 98

Les opérateurs relationnels

Ils permettent de comparer deux expressions :

  • < : strictement inférieur
  • <= : inférieur ou égal
  • > : strictement supérieur
  • >= : supérieur ou égal
  • == : égal à
  • != : différent de

Le résultat est un entier : 0 si la comparaison est fausse, 1 si elle est vraie.

Priorités :

  • <, <=, >, >= ont la même priorité.
  • ==, != ont une priorité inférieure à celle des précédents.

Exemple de comparaison de caractères :

#include <stdio.h>
void main() {
    char c1 = '1', c2 = 'a';
    if (c1 < c2) printf("inferieur");
    else printf("superieur");
}

Exécution : inferieur

L’ordre alphabétique est respecté pour les minuscules et majuscules, ainsi que l’ordre naturel des chiffres.

Les opérateurs logiques

Trois opérateurs logiques existent :

  • && : et logique (and)
  • || : ou logique (or)
  • ! : négation logique (not)

Ils retournent un entier (0 ou 1).

Exemples :

  • (a < b) && (c < d) vaut 1 si les deux conditions sont vraies, 0 sinon.
  • (a < b) || (c < d) vaut 1 si au moins une condition est vraie, 0 sinon.
  • !(a < b) vaut 1 si la condition est fausse, 0 sinon.

Priorités :

  • ! a la priorité la plus forte.
  • && a une priorité plus forte que ||.
  • Les opérateurs logiques ont une priorité inférieure aux opérateurs arithmétiques et relationnels.

Exemple :

a < b && c < d  // équivalent à (a < b) && (c < d)

L’évaluation est courte-circuitée : si a < b est faux, c < d n’est pas évalué.

L’opérateur d’affectation

L’opérateur d’affectation simple est =. Il affecte la valeur de l’expression de droite à la variable de gauche.

Exemple :

i = 5;  // i prend la valeur 5
c = b + 3;  // c prend la valeur de b + 3

La priorité de = est faible par rapport aux opérateurs arithmétiques et relationnels.

L’opérateur d’affectation est associatif de droite à gauche :

i = j = 5;  // équivalent à i = (j = 5);

Lorsqu’on affecte une valeur d’un type à une variable d’un autre type, une conversion automatique est effectuée.

Opérateurs d’incrémentation et de décrémentation

Les opérateurs ++ et -- permettent d’incrémenter ou décrémenter une variable de 1 :

  • i = i + 1; peut s’écrire i++ ou ++i
  • n = n - 1; peut s’écrire n-- ou --n

Exemple :

#include <stdio.h>
void main() {
    int n, i = 5;
    n = ++i - 5;
    printf("i: %d et n: %d", i, n);  // i:6 et n:1

    i = 5;
    n = i++ - 5;
    printf("\n i: %d et n: %d", i, n);  // i:6 et n:0
}

Opérateurs d’affectation élargie

Ces opérateurs condensent certaines opérations :

  • i++ remplace i = i + 1;
  • i += k; remplace i = i + k;
  • a *= b; remplace a = a * b;
  • Les opérateurs disponibles sont : +=, -=, *=, /=, %=.

Conversions forcées (casting)

Le programmeur peut forcer la conversion d’une expression dans un type donné en utilisant le casting.

Exemple :

int n = 5, p = 2;
(double)(n / p);

Cette expression calcule n / p en entier (donc 2), puis convertit le résultat en double (2.0).

Exemple avec affichage :

#include <stdio.h>
void main() {
    int x = 2, y = 3;
    printf("la somme est %f", (float)(x + y));
}

Exécution : la somme est 5.000000

Exemple sans casting :

char A = 3;
int B = 4;
float C;
C = A / B;
printf("%f", C);

Exécution : 0.000000 (division entière 3/4 = 0)

Avec casting :

C = (float) A / B;
printf("%f", C);

Exécution : 0.750000 (A converti en float avant division)

Le contenu des variables ne change pas, seule la valeur utilisée dans le calcul est convertie.

Classes de priorité des opérateurs

PrioritéOpérateurs
1 (la plus forte)( )
2! ++ --
3* / %
4+ -
5< <= > >=
6== !=
7&&
8||
9 (la plus faible)= += -= *= /= %=

L’opérateur conditionnel

L’opérateur conditionnel ternaire permet d’écrire une instruction conditionnelle simple :

if (a > b) max = a; else max = b;

peut s’écrire :

max = a > b ? a : b;

Quelques fonctions prédéfinies de la bibliothèque math.h

FonctionExplication
exp(X)fonction exponentielle e^X
log(X)logarithme naturel (X > 0)
log10(X)logarithme en base 10 (X > 0)
pow(X, Y)X exposant Y (X > 0)
sqrt(X)racine carrée de X
fabs(X)valeur absolue de X
floor(X)arrondi inférieur
ceil(X)arrondi supérieur
fmod(X, Y)reste rationnel de X / Y (même signe que X), pour X différent de 0
sin(X), cos(X), tan(X)sinus, cosinus, tangente de X
asin(X), acos(X), atan(X)arcsinus, arccosinus, arctangente de X
sinh(X), cosh(X), tanh(X)sinus, cosinus, tangente hyperboliques de X

Glossaire des termes clés

  • Opérateur unaire : opérateur qui agit sur un seul opérande, par exemple -a.
  • Opérateur binaire : opérateur qui agit sur deux opérandes, par exemple a + b.
  • Modulo (%) : opérateur qui retourne le reste de la division entière de deux entiers.
  • Conversion implicite : transformation automatique d’un type en un autre lors d’une opération.
  • Casting : conversion forcée d’un type en un autre par le programmeur.
  • Opérateurs relationnels : opérateurs de comparaison (<, <=, >, >=, ==, !=).
  • Opérateurs logiques : opérateurs booléens && (et), || (ou), ! (non).
  • Opérateur d’affectation : opérateur = qui assigne une valeur à une variable.
  • Opérateurs d’incrémentation/décrémentation : ++ et -- pour augmenter ou diminuer une variable de 1.
  • Opérateurs d’affectation élargie : opérateurs combinant une opération et une affectation, comme +=, *=.
  • Priorité des opérateurs : ordre dans lequel les opérateurs sont évalués dans une expression.
  • Fonctions mathématiques prédéfinies : fonctions fournies par math.h pour les calculs avancés (exponentielle, racine carrée, trigonométrie, etc.).

Points clés à retenir

  • Les opérateurs arithmétiques de base sont +, -, *, /, %, avec des règles de priorité strictes.
  • Les conversions de types sont automatiques mais peuvent entraîner des pertes de précision.
  • Le type char est converti en int dans les expressions, et correspond à un code ASCII.
  • Les opérateurs relationnels et logiques permettent de construire des expressions conditionnelles.
  • L’opérateur d’affectation a une priorité faible et est associatif de droite à gauche.
  • Les opérateurs d’incrémentation et d’affectation élargie simplifient l’écriture des opérations courantes.
  • Le casting permet de forcer une conversion de type pour contrôler précisément les calculs.
  • La bibliothèque math.h offre de nombreuses fonctions utiles pour les calculs mathématiques avancés.

Partager

Commentaires

Aucun commentaire pour le moment. Posez la première question.

Les commentaires sont relus avant publication. Votre e-mail n'est jamais affiché.

← Toutes les révisions