Programmation C source/Bases du langage
Apparence
/* 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 */
#include <stdio.h>
/* 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 */
}