Programmation C source/Bases du langage
/* marche à suivre
 1) Tapez le code source du programme dans un éditeur de texte
 2) Sauvegardez-le sous un nom en .c, exemple : bonjour.c,
 l'extension .c est usuelle pour un fichier source en C
 3) Compilez !
 cc bonjour.c
 le résultat est un fichier exécutable nommé a.out sous Gnu/Linux
 et a.exe sous Windows,
 qui peut être exécuté en tapant ./a.out sous Unix, a sous Windows
 ou mieux compilez avec cc -Wall bonjour.c -o bonjour
 -Wall pour afficher tous les messages d'avertissement
 -o bonjour le résultat est un fichier exécutable nommé bonjour */
/* inclut stdio.h (STanDard Input Output) qui contient
 - la déclaration de la fonction printf */
/* fonction main,
 point d'entrée du programme,
 executée pour démarrer le programme par le système d'exploitation */
int main(void)
 printf("Bonjour !\n");
 /* fonction printf (print formated),
 affiche la chaine "Bonjour !\n",
 \n est le caractère de retour à la ligne */
 printf("------------------------------\n");
 printf(" Identificateurs\n");
 printf("------------------------------\n");
 int var1;
 int Var2;
 int _var3;
 /* exemples d'identificateurs var1, Var2 et _var3, 3 variables entières
 un identificateur commence par une lettre ou un caractère souligné */
 int _abc_ABC_123;
 // un identificateur contient des lettres, des chiffres, des caractères soulignés
 #if 0
 /* #if et #endif langage préprocesseur,
 0 vaut faux donc les lignes entre #if et #endif sont ignorées */
 __reserve
 _Reserve
 /* les identificateurs commençant par
 deux caractères soulignés, ou un caractère souligné suivi d'une majuscule
 sont réservés au compilateur */
 #endif
 printf("\n------------------------------\n");
 printf(" Mots réservés du langage\n");
 printf("------------------------------\n");
 /* Le langage C, norme C90, possède 32 mots réservés
 la norme C99 ajoute 5 mots-clés
 en voici la liste, avec la mention (C99) pour ceux de la norme C99
 auto break case char const continue default do
 double else enum extern float for goto if
 inline (C99) int long register restrict (C99) return short signed
 sizeof static struct switch typedef union unsigned void
 volatile while _Bool (C99) _Complex (C99) _Imaginary (C99) */
 printf("\n------------------------------\n");
 printf(" Commentaires\n");
 printf("------------------------------\n");
 /* ceci est un commentaire */
 /* ceci
 est
 un
 commentaire sur plusieurs lignes */
 /* /* ceci est encore un commentaire */
 #if 0
 // les commentaires ne peuvent pas être imbriquées
 /* /* */ ceci n est pas un commentaire */
 #endif
 // commentaire sur une ligne en C norme C99
 printf("\n------------------------------\n");
 printf(" Instructions\n");
 printf("------------------------------\n");
 int i = 1;
 // une instruction se termine par un point-virgule
 i = 12; int j = 2; printf("bonjour\n");
 // plusieurs instructions sur la même ligne (déconseillé)
 int k;
 k = 5;
 int l = 6;
 /* un bloc d'instuctions commence par une accolade ouvrante {
 et se termine par une accolade fermante } */
 // l'instruction vide (qui ne fait rien)
 #if 0
 /* Les instructions doivent obligatoirement être déclarées dans une fonction
 il est impossible d'appeler une fonction pour initialiser une variable globale
 le compilateur ne se soucie pas des blancs (espaces et retours à la ligne),
 vous pouvez donc formater votre code comme vous l'entendez
 concernant le style d'indentation, je vous conseille une tabulation
 par niveau d'imbrication de bloc
 lorsqu'une erreur est détectée, les compilateurs ignorent tout
 jusqu'au prochain point-virgule ! */
 int traite_arguments(int nb, char * argv[])
 // ...
 return 0
 } // <-- Erreur ; attentu donc la ligne est ignoré par le compilateur !
 int main(int nb, char * argv[]) // <-- ignoré !
 { // <-- ignoré !
 int retour; // <-- ignoré jusqu'au ; !
 retour = traite_arguments(nb, argv);
 #endif
 printf("\n------------------------------\n");
 printf(" Déclarations de variables\n");
 printf("------------------------------\n");
 #if 0
 // exemple de code source d'un programme :
 int jour;
 /* jour est une variable globale, de type entier
 (jour est définie en-dehors de toutes fonctions) */
 int main(void)
 double prix;
 /* prix est une variable locale à la fonction main, de type réel
 (prix est définie à l'intérieur de la fonction main) */
 return 0;
 #endif
 printf("\n------------------------------\n");
 printf(" Variables locales\n");
 printf("------------------------------\n");
 #if 0
 /* Les variables locales (aussi appelées automatiques) ne sont visibles
 que dans le bloc dans lequel elles sont définies,
 et n'existent que durant ce bloc */
 int fonction(int n)
 int i;
 // i est visible dans toute la fonction
 i = n + 1;
 { // début d'un nouveau bloc
 int j;
 // j est visible dans le nouveau bloc *seulement*
 j = 2 * i;
 // i est accessible ici
 i = j; /* ERREUR !
 j n'est plus accessible */
 return i;
 #endif
 int n;
 printf("La variable n vaut %d\n", n);
 /* Erreur ! Les variables locales ne sont pas initialisées automatiquement
 et contiennent donc, après leur déclaration, une valeur aléatoire */
 /* Avant la normalisation ISO C99,
 les déclarations de variables locales devaient obligatoirement être placées
 juste au début d'un bloc et s'arrêtaient à la première instruction rencontrée. */
 int ma_fonction(int n)
 puts("Bonjour !");
 int a; // Valide en C99, invalide en C90
 return a;
 printf("\n------------------------------\n");
 printf(" Variables globales\n");
 printf("------------------------------\n");
 #if 0
 /* limitez leur usage au seul fichier où elles sont déclarées,
 en les déclarants statiques. */
 static int ma_variable_globale;
 /* Si le programmeur ne fournit pas de valeur initiale explicitement
 - un nombre (entier, réel ou complexe) est initialisé à 0
 - les pointeurs sont initialisés à NULL
 - pour une structure, l'initialisation se fait récursivement,
 chaque membre étant initalisé suivant les mêmes règles
 - pour une union, le premier membre est initialisé suivant ces règles.
 Pour initialiser explicitement une variable globale,
 on ne peut utiliser que des constantes;
 on ne peut appeler de fonction, contrairement à d'autres langages.
 exemple : */
 int jour_courant(void)
 // retourne le n° du jour courant
 int jour = jour_courant(); // ERREUR !
 int main(void)
 // ...
 return 0;
 // exemple corrigé :
 int jour_courant(void)
 // retourne le n° du jour courant
 int jour; // jour est initialisé à 0 *avant* le début de main
 int main(void)
 jour = jour_courant();
 return 0;
 #endif
 printf("\n------------------------------\n");
 printf(" Traitements des ambiguïtés\n");
 printf("------------------------------\n");
 #if 0
 /* Le C utilise un mécanisme élégant pour lever des constructions syntaxiques
 en apparence ambiguës. L'analyse des mots (lexèmes, token en anglais) se fait
 systématiquement de la gauche vers la droite. Si plusieurs lexèmes peuvent
 correspondre à une certaine position, le plus grand aura priorité. */
 a+++b;
 (a ++) + b;
 #endif
 return 0;
 /* retourne la valeur 0,
 la valeur 0 est reçu par le système d'exploitation
 normalement pour 0, elle lui indique que le programme s'est terminé normalement
 sinon une valeur différente de 0 indique une erreur */