Sommaire
- La syntaxe (vous êtes ici)
- Les blocs
Temps de lecture estimé : 45min-1h
Avertissement
Le C est sensible à la casse : Truc
, truc
et TRUC
sont trois mots différents.
Le code suivant ne compile pas :
int truc = 5;
printf("%d", TrUc);
Identificateurs
= peut être utilisé pour nommer quelque chose (variable, fonction, structure, ...)
Peut contenir des lettres (A-Z
, a-z
), des chiffres (0-9
) et des tirets bas (_
) mais ne peut pas commencer par un chiffre.
Nombres
Entiers
Type : int
Notation décimale : 1
, 41
, 123
Notation hexadécimale : 0x1
, 0xA0
Notation octale : 0777
, 0123
Flottants
Type : float
, double
Se note avec un point : 41.123
, 0.123
.
Notation scientifique : 3e-8
= $3*10^{-8}$.
Attention : les types float
et double
ne sont pas interchangeables directement. Les litéraux float
doivent se terminer par un f
.
Le type double
est un surensemble du type float
, donc une valeur float
peut être utilisée dans un double
mais pas l'inverse.
Exemples :
2.5
est undouble
2.5f
est unfloat
Booléens
Contrairement au Java, le C ne possède pas de type booléen natif, on utilise le plus souvent des nombres ordinaires.
Ainsi, la valeur 0
correspond à "faux" et toute autre valeur correspond à "vrai".
Caractères
Type : char
Se note entre guillemets simples: 'A'
, 'a'
, ' '
.
Caractères spéciaux :
'\n'
: saut de ligne'\t'
: tabulation
Chaînes de caractères
Le C ne possède pas de type "chaîne de caractère", on utilise à cet effet des tableaux de caractères.
Ils sont notés char[]
ou char*
, éventuellement const
:
const char* maChaine = "Bonjour tout le monde";
Les chaînes se notent entre guillemets doubles : "abc"
, "Bonjour"
.
Utilisation possible des caractères spéciaux dans une chaîne :
"Bonjour\nAu revoir"
Donne :
Bonjour
Au revoir
Attention : pour comparer deux chaînes, il faut utiliser strcmp(.., ..)
et pas ==
:
const char* a = "abc";
const char* b = "abc";
if (a == b) // INCORRECT
{
...
}
if (!strcmp(a, b)) // CORRECT
{
...
}
(on reviendra plus tard sur strcmp
)
Commentaires
Un commentaire est un bout de code qui sert à mettre des infos supplémentaires dans le code à destination des humains qui vont le lire.
Les commentaires sont ignorés par le compilateur.
Il en existe 2 types :
- commentaires sur une ligne :
// commentaire
- commentaires sur plusieurs lignes :
/* début bonjour au revoir */ fin
Variables
Syntaxe : type nom;
ou type nom = valeur;
où type
est le type et nom
le nom.
Exemples :
int a;
déclare une variablea
de typeint
(nombre entier).int* a;
déclare une variablea
de typeint*
(pointeur vers un nombre entier).double b = 2.5;
déclare et initialise une variableb
de typedouble
(flottant double-précision) avec la valeur 2,5.
Déclarer c'est dire "la variable existe".
Initialiser c'est affecter la valeur à la variable.
Attention : une variable non initialisée peut contenir n'importe quelle valeur. int x;
ne dit absolument rien sur ce que contient x
, il ne faut pas donc pas lire dedans.
Tableaux
On déclare un tableau en mettant [N]
après le nom, où N
est le nombre d'éléments (fixe).
Exemples :
int a[10];
:a
est un tableau de 10 entiersfloat b[5];
:b
est un tableau de 5 flottants
On accède à l'élément N (en partant de 0) d'un tableau avec l'opérateur []
:
a[5]
est le sixième élément dea
a[8] = 123;
met 123 dans le neuvième élément dea
On peut déclarer un tableau à plus d'une dimension en mettant plusieurs []
:
int maMatrice[5][3];
Le code ci-dessus crée une matrice 2D de 5 par 3, où chaque case est un entier.
Attention : comme les variables normales, les tableaux ne sont pas initialisés par défaut à l'inverse du Java où ils sont remplis de zéros. Il ne faut jamais lire dans une variable non initialisée.
Fonctions
Syntaxe :
type nom(paramètre, paramètre, ...)
{
...
}
Où type
est le type de retour de la fonction (ce que la fonction renvoie). Si la fonction ne renvoie rien (c'est alors une procédure), on écrit void
;
nom
est le nom de la fonction, et paramètre
= type nom
(cf Variables).
Dans une fonction qui renvoie une valeur, on écrit return valeur;
pour renvoyer une valeur. Cette valeur peut être un litéral (un nombre, une chaîne), une variable, ou un appel à une autre fonction.
Dans une fonction ne renvoyant pas de valeur, on peut écrire return;
.
Dans les deux cas, tout code se trouvant après le return
ne sera pas exécuté (sauf cas rares, on verra ça plus tard).
Exemple :
int nombreAuCarre(int leNombre)
{
return leNombre * leNombre; // met leNombre au carré et renvoie le résultat
int b = 123; // incorrect, car il y a un return plus haut donc la ligne ne serait jamais atteinte
}
.
.
.
int resultat = nombreAuCarre(7);
// resultat contient maintenant 49
Autre exemple :
int main()
{
puts("bonjour");
}
Opérateurs
Arithmétique
a + b
: additiona - b
: soustractiona * b
: multiplicationa / b
: division- Attention : si
a
etb
sont entiers, alors le résultat sera entier 3 / 2
vaut1
car le1.5
est tronqué à l'entier inférieur.- Pour avoir le bon résultat, il faudrait faire
3.0 / 2
par exemple.
- Attention : si
a % b
: reste de la division euclidiennea % 2
donne la parité dea
(0 si pair, 1 si impair)a % b == 0
équivaut à "a
est divisible parb
"
-a
: négation
Logique
a && b
: conjonction (a
ETb
), vrai si les deux sont vraisa || b
: disjonction (a
OUb
), vrai si au moins un des deux est vrai!a
: négation : vrai sia
est faux
Comparaison
a == b
: égal À NE PAS UTILISER POUR LES CHAÎNES !a != b
: différenta > b
: strictement supérieura >= b
: supérieur ou égala < b
: strictement inférieura <= b
: inférieur ou égal
Binaire (bit-à-bit)
a & b
: ET binaire (les deux sont vrais)a | b
: OU binaire (au moins un des deux est vrai)a ^ b
: OU exclusif binaire (exactement un des deux est vrai)
a |
b |
ET | OU | OU excl |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
Typedef (début)
En C, il est possible de créer des "raccourcis" de types, par exemple si on se sert souvent d'un type tableau en particulier.
Exemple : vous écrivez un programme qui traite des matrices 3x3 et vous avez donc beaucoup de fonctions prenant de telles matrices en entrée.
int fonc1(int matrice[3][3])
{
...
}
etc. Au lieu de devoir taper int ...[3][3]
à chaque fois, on préfère faire :
typedef int MAT[3][3];
Cette ligne "crée" un raccourci appelé "MAT" qui représente une matrice 3x3 d'entiers.
On peut donc réécrire la fonction :
int fonc1(MAT matrice)
{
...
}
Sur le long terme, ça peut faire économiser beaucoup de code. La syntaxe formelle est :
typedef type nomRaccourci;
Ça se déclare pour ainsi dire comme les variables, excepté qu'au lieu de créer une variable on crée un raccourci.
Suite dans la page sur les blocs.