Le C a très peu de syntaxe à apprendre - environ 32 mots-clés et une poignée de règles de ponctuation. Presque tous les programmes que vous écrirez ont la même forme extérieure, il vaut donc la peine de démonter cette forme une fois, soigneusement.
Le plus petit programme complet
Ceci compile, s'exécute et ne fait rien :
Aucune inclusion, aucune sortie, aucune classe ni module obligatoire. main est le point d'entrée : quand le système d'exploitation démarre votre programme, il appelle main. Quand main retourne, le programme se termine, et la valeur renvoyée est le code de sortie.
Ajoutez de la sortie et il vous faut une inclusion :
Les directives du préprocesseur
Les lignes commençant par # sont traitées avant la compilation proprement dite, par le préprocesseur. Ce ne sont pas des instructions C, et elles ne prennent aucun point-virgule.
#include <stdio.h> /* en-tete de la bibliotheque standard - chevrons */
#include "myutils.h" /* votre propre en-tete - guillemets, cherche d'abord localement */
#define MAX 100 /* une macro - MAX est remplace par 100 partout en dessous */
#include est un collage de texte littéral : tout le contenu du fichier nommé est déposé à cet endroit. stdio.h contient la déclaration de printf, c'est ainsi que le compilateur sait quels arguments printf prend. Omettez l'inclusion et vous obtenez implicit declaration of function 'printf'.
La distinction chevrons contre guillemets porte sur l'endroit où le compilateur cherche : <...> désigne les répertoires d'inclusion du système, "..." signifie « regarde d'abord à côté de ce fichier ».
La fonction main
int main(void) {
return 0;
}
Quatre parties, toutes chargées de sens :
int- le type de retour de main. La valeur part vers le système d'exploitation comme code de sortie, où 0 signifie succès.main- le nom réservé que l'environnement d'exécution appelle. Tout programme C hébergé en a exactement un.(void)- la liste de paramètres.voidsignifie ici « ne prend aucun argument ». Écriremain()est légal mais plus faible : des parenthèses vides en C signifient « paramètres non spécifiés », ce qui désactive la vérification des arguments.{ ... }- le corps de la fonction.
L'autre forme standard prend les arguments de ligne de commande :
int main(int argc, char *argv[]) { ... }
Utilisez int main(void) jusqu'à ce que vous en ayez besoin.
Instructions et points-virgules
Une instruction est une consigne unique, et elle se termine par un point-virgule.
Quatre instructions, quatre points-virgules. Le point-virgule est un terminateur, pas un séparateur - la dernière instruction d'un bloc en a besoin aussi.
Ce qui ne prend pas de point-virgule :
#include <stdio.h> /* ligne du preprocesseur - pas de point-virgule */
int add(int a, int b) { /* en-tete de definition de fonction - pas de point-virgule */
return a + b;
} /* accolade fermante d'une fonction - pas de point-virgule */
if (x > 0) {
...
} /* accolade fermante d'un bloc de controle - pas de point-virgule */
Le cas qui piège tout le monde est un point-virgule là où devrait se trouver un corps :
if (score > 90); /* BUG: ce ; est tout le corps du if */
printf("Excellent !\n"); /* s'execute toujours, quel que soit score */
C'est du C parfaitement légal. Le if contrôle une instruction vide, et le printf n'est que la ligne suivante dans l'ordre. -Wall le signale ; le compilateur ne vous arrêtera pas.
Blocs et accolades
Les accolades regroupent des instructions en un bloc, qui compte pour une seule instruction partout où une instruction est attendue.
Les accolades sont facultatives quand le corps est une instruction unique, mais les omettre est la source des bugs célèbres - ajoutez une seconde ligne plus tard et elle sort silencieusement du if. Mettez toujours des accolades.
Les blocs créent aussi une portée : une variable déclarée dans { ... } cesse d'exister à l'accolade fermante.
Sensibilité à la casse et espaces
Le C est sensible à la casse partout. total, Total et TOTAL sont trois noms distincts. Tous les mots-clés sont en minuscules, donc Int, Return et Printf sont tous des erreurs - et le message d'erreur pour Printf est déroutant, car le compilateur suppose que vous vouliez une fonction dont il n'a jamais entendu parler.
Les espaces, en revanche, sont presque entièrement libres. Le compilateur traite toute suite d'espaces, de tabulations et de sauts de ligne comme un seul séparateur. Ceci est valide :
int main ( void )
{
printf
( "Bonjour\n" ) ;
return 0 ;
}
Et ceci aussi :
int main(void){printf("Bonjour\n");return 0;}
Les deux compilent à l'identique. Puisque le compilateur s'en moque, la mise en forme est entièrement pour les humains - et la disposition conventionnelle (une instruction par ligne, quatre espaces ou une tabulation par niveau d'imbrication, accolade ouvrante sur la même ligne) mérite d'être suivie, car toutes les bases de code C que vous lirez utiliseront quelque chose d'approchant.
Deux endroits où les espaces comptent : vous ne pouvez pas couper un mot-clé ou un identifiant (in t n'est pas int), et vous ne pouvez pas mettre un saut de ligne dans un littéral de chaîne ordinaire.
Les identifiants : règles de nommage
Un identifiant est n'importe quel nom que vous choisissez - variables, fonctions, types. Les règles :
- Composé de lettres, de chiffres et de tirets bas.
- Ne doit pas commencer par un chiffre.
total2convient,2totalnon. - Ne peut pas être un mot-clé : pas de variable appelée
int,foroureturn. - La casse compte.
- Les noms commençant par un tiret bas, et tout ce qui comporte deux tirets bas à la suite, sont réservés à l'implémentation - n'en inventez pas.
int score; /* bien */
int total_items; /* bien - snake_case est la convention C */
int _hidden; /* legal mais reserve - a eviter */
int 2fast; /* erreur */
int float; /* erreur - mot-cle */
Un programme entièrement annoté
Tout ce qui précède, au même endroit :
L'ordre de lecture compte ici : with_tax est défini avant que main l'utilise. Le C lit le fichier de haut en bas, donc une fonction doit être déclarée avant d'être appelée. Définissez-la plus tôt, ou écrivez un prototype de fonction en haut et définissez-la plus loin.
Questions fréquentes
Quelle est la structure de base d'un programme C ?
D'abord les directives du préprocesseur (#include <stdio.h>), puis les définitions de fonctions, dont l'une doit être main. À l'intérieur d'une fonction, les instructions se terminent par un point-virgule et les blocs sont entourés d'accolades. Un programme minimal, c'est #include <stdio.h> plus int main(void) { return 0; }.
Pourquoi int main(void) et pas simplement main() ?
int est le type de retour de main - le code de sortie que le programme rend au système d'exploitation. (void) indique explicitement que main ne prend aucun argument. Écrire main() avec des parenthèses vides est un style plus ancien qui ne dit rien au compilateur sur les paramètres, il vérifie donc moins de choses.
Toutes les instructions C ont-elles besoin d'un point-virgule ?
Toute instruction en a besoin, mais pas toute ligne. Les directives du préprocesseur (#include, #define), les définitions de fonctions et l'accolade fermante d'un bloc ou d'un if/for/while n'en prennent pas. Un point-virgule égaré après if (x) est du C légal et fait silencieusement s'exécuter le corps sans condition.
Le C est-il sensible à la casse ?
Oui, totalement. count, Count et COUNT sont trois identifiants différents, et Int n'est pas le mot-clé int. Tous les mots-clés du C sont en minuscules, donc une majuscule dans Return ou Printf produit une erreur.