On l'a vu dans les exemples précédents, il est possible de définir des blocs conditionnel, c'est à dire dont l'entrée est conditionné par la valeur d'une expression.
La condition est évaluée, si elle vaut 1, les instruction du bloc 1 sont évaluées, sinon ce sont celles du bloc2.
Le else n'est pas obligatoire :
et les bloc 1 et 2 peuvent eux même contenir des branchements conditionnels :
les accolades ne sont obligatoires que si les blocs contiennent plusieurs instructions;
Pour la lisibilité du code, il est très fortement conseillé (cad obligatoire) d'indenter le code, c'est à dire d'ajouter les espace et retours à la ligne nécessaires pour faire ressortir à l'œil nu la logique du code(contrairement à ce que j'ai fait juste au dessus).
Remarquons enfin que si le bloc d'instructions correspondant à un if contient un return ou un exit, le else devient superflu :
Le switch est une facon d'écrire une imbrication de if(expr==val1)...else if(expr==val2)...else if(expr==val3)... etc. plus performante et plus concise. Plus performante car l'expression n'est évaluée qu'une seule fois.
Il existe trois façons de répéter du code en C : while(), for(...) et do...while(). Pour les débutants, il est conseillé de n'apprendre que la boucle for, car sa syntaxe force à bien réfléchir au conditions d'entrée dans la boucle, de continuation et à ce qui est fait systématiquement à chaque passage. Et ces trois informations sont visibles sur une seule lignes au début de la boucle, alors que dans le cas du while, par exemple, il faut parfois lire plusieurs lignes de code attentivement pour comprendre le fonctionnement de la boucle.
Si on a besoin de plusieurs variables de mêmes type, on peut les déclaré en une seule instruction :
Pour initialiser un tableau, on peut utiliser la notation :
En réalité, ce qui est masqué par l'écriture ci-dessus, c'est qu'un tableau n'est en fait qu'une variable particulière, qui contient l'adresse en mémoire du premier élément. Les éléments suivants sont retrouvés car on sait qu'ils sont consécutifs, et on connait la taille en mémoire d'un élément (ce sont tous les même).
Une variable qui contient une adresse en mémoire associée à un type (donc à une taille), s'appelle en C un pointeur.
On déclare un pointeur comme ceci : int * pointeur;
On réserve sur la pile la taille nécessaire pour stocker une adresse (32bits ou 64bits). On réserve un nom (ici "pointeur") associé à cette adresse sur la pile. Et on informe le compilateur, que la zone pointée, c'est à dire les données qui se trouvent à l'adresse codée dans la variable pointeur, est censé contenir un entier (donc au moins être de taille sizeof(int)).
Le compilateur comprend les opérations arithmétiques sur les pointeurs. pointeur+1, est compris car le compilateur sait que pointeur pointe sur un entier. Donc pointeur+1 veut dire : ajouter à l'adresse contenue dans pointeur sizeof(int).
Il existe deux opérateurs spéciaux pour manipuler les pointeurs : * et &
Enfin la dernière chose à savoir est qu'un pointeur peut pointer... sur un pointeur ! int ** tab; par exemple. tab est un pointeur, qui contient l'adresse d'un pointeur, qui contient l'adresse d'un entier.
Revenons à notre tableaux :
Il est tout à fait possible d'écrire le code suivant :
Voila pourquoi lorsqu'on veut parcourir un tableau, il faut savoir quand s'arrêter ! Un tableau intrinsèquement n'a pas de fin, puisqu'il s'agit simplement de l'adresse du premier élément. Il existe trois stratégies pour savoir quand s'arrêter. Je vous renvois au cours (ca vous fera une bonne occasion de le lire).
Comme les tableaux sont en fait des pointeurs déguisés, si une fonction prend en paramètre un tableau, elle prend en réalité l'adresse de la première case. Si elle effectue des changements sur le tableaux, ceux-ci seront alors répercutés sur le tableau de la fonction appelante !
exemple :