Aller au contenu

Programmation C source/Bases du langage

Un livre de Wikilivres.
Programmation C source
Programmation C++
Programmation C++
Sommaire
Modifier ce modèle
/* 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 */
}