La Syntaxe du C
La syntaxe du C lui est propre, comme à tous les autres
langages. Si elle n'est pas respectée, le compilateur ne peut
pas comprendre le fichier source, et ne le traduit pas.
Un programme C est composé de lignes successives, non numérotées (comme en BASIC), chacune terminée par un point-virgule (;). Chaque ligne peut être :
Une déclaration de variable : int variable;
Une déclaration de fonction : int fonction1(void);
Une instruction : x=y+5*z;
Un appel de fonction : sousprog();
Un commentaire : /* Ceci est un commentaire */
Les commentaires sont ignorés par le compilateur, mais ils
sont utiles à la lecture du code source. N'hésitez pas à
utiliser abondamment les commentaires. Un commentaire commence
par /* et finit par */. Attention à bien fermer votre
commentaire, c'est une erreur classique.
En C, les instructions sont rangés en blocs de programmes. Un bloc est délimité par des crochets { et }. Il peut être une fonction en entier, un sous-bloc de condition, etc...
En C, il existe quelques mots-clés, reservés par le langage,
qui ont une fonction bien particulière.
asm | Permet d'inserer un bloc en assembleur à l'interieur du programme |
break | "Casse" une itération (boucle) |
case | Permet de choisir lors d'une condition à choix multiples |
char | Type de données caractères |
const | Déclare une variable comme constante. Sa valeur ne peut être modifiée |
continue | Reprend une boucle |
default | Choix par défaut dans une condition à choix multiples |
do | Point d'ouverture d'une boucle do..while |
double | Type de données double flottant |
else | Indique le choix négatif dans une condition IF..ELSEIF..ELSE |
enum | Démarre une énumération |
float | Type de données à virgule flottante (réél) |
for | début d'une boucle FOR |
goto | branchement à un point du programme : ne pas utiliser si possible |
if | Déclare une condition |
int | Type de donnée entiers |
interrupt | déclare une fonction comme fonction d'interruption |
long | Type de donnée entier long |
pascal | Déclare une fonction comme respectant le passages de paramètres du pascal |
return | Point de sortie d'une fonction |
short | Type de données entier court |
signed | Déclare une variable comme signée |
sizeof | renvoie la taille de l'objet concerné |
static | Déclare une variable comme statique |
struct | Type de données structure |
switch | Entrée d'une condition à choix multiples |
typedef | Définition d'un nouveau type |
union | Type de données union |
unsigned | déclare une variable comme non signée |
void | Type de données vide (sans type) |
volatile | Déclare une variable comme volatile |
while | Condition while |
Mot-clé | Type | Taille (en bits) | valeurs | |
char | caractère (lettre) | 8 | signée de -128 à 127 |
non signée de 0 à 255 |
short int ou short | entier court | 16 | signée de -32768 à 32767 |
non signée de 0 à 65535 |
int | entier | 32 | signée de - 2147483648 à + 2147483647 |
non signée de 0 à 4294967295 |
long int | entier long | 64 | signée de - 2^63 à 2^63 |
non signée de 0 à 2^64-1 |
float | réel simple précision | 32 | de 3.4 * (10^-38) à 3.4 * (10^38) | |
double | réel double précision | 64 | de 1.7 * (10^-308) à 1.7 * (10^308) | |
long double | réel haute précision | 80 | de 3.4 * (10^-4932) à 1.1 * (10^4932) |
Le type chaîne est un peu particulier. Une châine de caractères n'existe pas en C. Il s'agit d'un ensemble de plusieurs caractères, contigüs en mémoire, se terminant par un caractère nul (0). Cela forme un tableau, et on accède à la chaîne par un pointeur. C'est un peu compilqué, et c'est la source de nombreux bugs en C.
Une variable est un objet, occupant une certaine place mémoire, d'un certain type, avec un identificateur (son nom) et une valeur. Comme son nom l'indique, la valeur d'une variable est susceptible de changer au cours du programme.
En C, une variable doit être déclarée pour être valide. Cela permet au compilateur de determiner son type. La déclaration d'une variable dans un programme, une fonction, un bloc de programme se fait toujours au début. Voici des exemples de déclaration :
int varEntiere;
float x,y;
Vous remarquez d'abord que chaque ligne se termine par un point-virgule (;). En C, le ; signifie la fin d'une instruction. IL EST OBLIGATOIRE car sans lui, le compilateur est incapable de comprendre votre source.
La première variable est varEntiere. Son type est int, c'est donc un entier (par défaut, signé. Si l'on désire un entier non signé, on déclarera unsigned int varEntiere; ) La seconde ligne comprend la déclaration de deux variables x et y. Elles sont séparés par une virgule. On peut comme cela déclarer autant de variables du même type que l'on veut, en les séparant par des virgules.
Lorsque votre variable est déclarée, vous pouvez l'utiliser. Mais attention : sa valeur d'origine n'est pas encore fixée. Vous pourriez penser qu'elle part de 0, mais c'est faux. Sa valeur est quelconque, non prévisible, il est donc obligatoire d'initialiser cette variable avant de s'en servir. Vous pouvez l'initialiser comme ceci :
int varEntiere;
......
varEntiere=2;
ou comme cela, ce qui est plus rapide :
int varEntiere=2;
En tout cas, il faut l'initialiser.
Une variable est valable uniquement dans le bloc ou elle a été
déclarée. Le reste du programme l'ignore. Par exemple :
void fonc1(void) /* une des fonctions du programme */
{
int i;
....
/* i peut être utilisé ici */
....
}
....
void fonc2(void) /* une autre fonction */
{
....
/* i ne peut pas être utilisé là : erreur du compilateur */
}
void fonc3(void)
{
int i;
/* ce i ci n'a rien à voir avec celui de fonc1. C'est une autre variable.*/
}
La variable déclarée dans un bloc appartient à ce bloc et n'existe
plus une fois le bloc terminé. Sa valeur est perdue à la sortie
d'une fonction, par exemple.
En C, les fonctions regroupent à la fois la notion de fonction et de sous-programme (procédure en pascal). Normalement, une fonction nécessite des paramètres en entrée, et renvoie une valeur en sortie. Mais on peut écrire des fonctions sans l'un ni l'autre, et donc créer un sous-programme.
La syntaxe d'une fonction se présente comme suit :
type_sortie nom_fonction(paramètres...)
{
}
Où type est le type du retour de la fonction, nom_fonction le nom de cette fonction, et paramètres les paramètres d'entrée. Voyons par exemple une fonction calculant le carré d'un nombre :
float carre(float x)
{
float y;
y=x*x;
return y;
}
Le type de retour est float, c'est à dire réel simple précision. La fonction s'appelle carre (notez que le nom de la fonction ne peut pas contenir d'accents) et elle a besoin d'un paramètre, un float nommé x. La fonction va donc calculer x*x (l'étoile * est le symbole pour l'opération de multiplication), affecter cette valeur à y, et renvoyer au programme la valeur de y par l'instruction return. Celle-ci doit se trouver à la fin de la fonction. Toute instruction suivante serait ignorée.
A l'interieur du programme, on pourrait trouver ces lignes, pour appeler la fonction :
float a,b;
a=5;
b=carre(a);
Après ces quelques lignes, la valeur de a sera toujours 5, mais b vaudra 25 (le carré de 5).
Une fonction doit être déclarée. En début du programme, on doit trouver une ligne comme :
float carre(float);
On explique ainsi au compilateur que l'on écrira plus bas une fonction renvoyant un float et prenant un float comme paramètre, s'appelant carre. Cette ligne doit être au début du programme. Le corps de la fonction lui-même peut être n'importe où après la déclaration.
Si vous désirez que votre fonction ne renvoie rien, son type de retour doit être void (vide) :
void beep(int n_b)
{....}
La fonction beep a besoin d'un paramètre (de type int) mais ne renvoie aucune valeur : elle n'a donc pas besoin d'instruction return.
Une fonction peut aussi n'avoir aucun paramètre :
int nombre_aleatoire(void);
Celle-ci renvoie un entier, mais n'a pas de paramètre : on le déclare du type void.
Une fonction peut avoir un nombre quelconque de paramètres, de types différents.
void fonc_a(int a, float b,char c,double z)
{...}
Une fonction ne peut renvoyer qu'une seule valeur (ou aucune).
La fonction main peut ne renvoyer aucune valeur
void main(void)
{....}
Elle peut renvoyer une valeur de type int qui sera transmise au système (par exemple, un code d'érreur pouvant être utilisé par ERRORLEVEL du DOS...)
int main(void)
{
int i;
.....
return i;
}
Elle peut soit n'avoir aucun paramètre (type void donc, comme plus haut) où avoir les paramètres de la ligne de commande, ce que nous verrons plus tard.
En C, on peut donner au compilateur des directives (des ordres) avant la compilation. On peut, par exemple, lui indiquer d'inclure un fichier, de créer une macro, etc...Toutes les directives commencent par # et ne se terminent pas par un ;
La directive #include permet d'inclure un fichier. Elle est souvent utilisée pour inclure les fichiers d'en-tête (fichiers .h) où se trouvent les déclarations des fonctions standard du C (souvenez-vous, toutes les fonctions doivent être déclarées). Par exemple, le fichier stdio.h regroupe les déclarations des fonctions d'entrées/sorties standard (clavier, écran, fichiers). Pratiquement à chaque fois vous devrez l'inclure. Les inclusions se font en début de fichier, comme ceci :
#include <stdio.h>
La directive #define permet de définir une valeur ou une macro. Par exemple,
#define PI 3.1415
indiquera au compilateur que chaque fois qu'on tape PI, il faut en fait comprendre 3.1415 . Ce n'est pas une création de variable ou de constante, mais l'indication d'un remplacement.
Regardez ce petit programme en C comme exemple.
La version executable (pour PC/Windows) si vous n'avez pas de compilateur.