Exercices en langage C/Version imprimable

Un livre de Wikilivres.

Ceci est la version imprimable de Exercices en langage C.
  • Si vous imprimez cette page, choisissez « Aperçu avant impression » dans votre navigateur, ou cliquez sur le lien Version imprimable dans la boîte à outils, vous verrez cette page sans ce message, ni éléments de navigation sur la gauche ou en haut.
  • Cliquez sur Rafraîchir cette page pour obtenir la dernière version du wikilivre.
  • Pour plus d'informations sur les version imprimables, y compris la manière d'obtenir une version PDF, vous pouvez lire l'article Versions imprimables.


Exercices en langage C

Une version à jour et éditable de ce livre est disponible sur Wikilivres,
une bibliothèque de livres pédagogiques, à l'URL :
https://fr.wikibooks.org/wiki/Exercices_en_langage_C

Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la Licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans Texte de dernière page de couverture. Une copie de cette licence est incluse dans l'annexe nommée « Licence de documentation libre GNU ».

Préparation

La préparation consiste à installer un environnement de programmation suivant votre système d'exploitation.

En ligne de commande[modifier | modifier le wikicode]

Linux[modifier | modifier le wikicode]

Pour les distributions compatibles Debian (comme Ubuntu) :

 # apt-get install build-essential
 ...
 $ cc exox.c -o exox

Mac[modifier | modifier le wikicode]

Les systèmes d'exploitation Mac OS X fournissent en standard les compilateurs GCC. tapez la commande suivante pour vérifier :

gcc --version

donne par exemple :

i686-apple-darwin8-gcc-4.0.1 (GCC) 4.0.1 (Apple Computer, Inc. build 5367)

Si gcc n'est pas présent, installez-le depuis les disques systèmes fournis avec votre machine Mac OS X Install Disc 1 dossier Xcode Tools ou téléchargez la dernière version depuis le site Apple[1] et choisissez Tools Downloads et télécharger (1Gb) puis installer la version adaptée à votre système (10.4 ou 10.5).

Microsoft Windows[modifier | modifier le wikicode]

Le compilateur C est fourni dans la suite libre GNU Compiler Collection portée sous Windows dans le paquet MinGW (Minimalist GNU for Windows) [2]. Vous pouvez alors utiliser le compilateur gcc dans une fenêtre MS-DOS à condition d'avoir ajouté le chemin du répertoire bin de votre installation MinGW dans la variable d'environnement utilisateur nommée Path.

Vous pouvez aussi utiliser un environnement de développement avec le confort du shell Linux : MSys [2]. Vous pouvez utiliser le compilateur gcc dans une fenêtre ouverte grâce au script msys.bat situé dans un sous répertoire bin d'installation de Msys. MSys créé aussi un raccourci sur votre bureau.

 $ gcc hello.c -o hello
 $ ./hello

Remarque pour Windows[modifier | modifier le wikicode]

Sous Windows, MinGW et Msys[3] sont aussi nécessaires car ils fournissent le compilateur gcc et les outils comme GNU Make.

Pour un lien automatique avec Eclipse, mettre dans une variable d'environnement utilisateur nommée Path le chemin du répertoire qui contient les binaires de MinGW et Msys.

Eclipse[modifier | modifier le wikicode]

Eclipse est un environnement de développement intégré (EDI), générique et extensible (site officiel http://www.eclipse.org). Son système de plugins permet d'ajouter des fonctionnalités diverses.

Initialement prévu pour développer en Java, grâce aux plugins il peut maintenant également gérer des projets développés avec d'autres langages de programmation tels que :

  • Le C et le C++ grâce à l'ensemble de plugins CDT (C Development Toolkit)[4] (compilateur non intégré).
  • Le Python via PyDev[5].
  • Avant l'arrivée d'Android Studio, le développement pour Android se faisait avec Eclipse grâce à l'ensemble de plugins ADT (Android Development Toolkit).

Certains IDE sont basés sur Eclipse, et permettent par exemple le développement de logiciel embarqués pour des systèmes temps réel.

Installation de Eclipse

La page de téléchargement d'Eclipse permet de récupérer une version déjà adaptée au langage ciblé sur http://www.eclipse.org/downloads/. Mais pour installer un plugin manuellement, il faut :

  • Lancer Eclipse, puis dans le menu déroulant :Help>Software Updates>Find and Install...
  • Cocher Search for new features to install, bouton Next. Bouton New Remote Site..., entrer l'adresse de téléchargement :
Name: Nom du plugin
URL: adresse du plugin, ex : http://www.eclipse.org/cdt/downloads.php
  • Bouton Finish, choisir un miroir proche puis continuer l'installation.

Utilisation de Eclipse

L'interface de l'IDE Eclipse est basée sur différentes perspectives. Une seule perspective n'est visible à la fois, et se compose de plusieurs vues. Exemples :

  • La perspective "Java" se compose par défaut de la vue "Package Explorer", de la vue éditeur de code en Java avec un onglet par fichier ouvert, de la vue "Outline" donnant la hiérarchie des éléments composant la classe du fichier ouvert.
  • La perspective "Debug" est ouverte automatiquement au lancement d'une application en mode débogage et se compose par défaut de la vue "Debug" affichant la pile d'appel, de la vue des points d'arrêt nommée "Breakpoints", de la vue éditeur de code en Java avec un onglet par fichier ouvert, de la vue "Outline" donnant la hiérarchie des éléments composant la classe du fichier ouvert.
  • Deux ou plusieurs perspectives peuvent être affichées conjointement.

Chaque vue est une sous-fenêtre qui a un titre et se place dans un cadre particulier de la fenêtre de l'IDE. Les vues peuvent être déplacées à la souris par drag and drop pour changer la disposition de la perspective. Plusieurs vues peuvent partager le même cadre, auquel cas, une barre d'onglets permet de basculer entre les vues. Un double clic sur le titre d'une vue provoque l'affichage du cadre qui la contient en pleine fenêtre, réduisant les autres cadres à une icône sur les côtés. Un second double clic restaure les cadres.

Le menu "Window" permet de changer de perspective, et d'ajouter des vues à la perspective courante. Une vue peut également être retirée de la perspective affichée en utilisant la croix à droite du titre de la vue.

Eclipse

Édition de lignes

L'éditeur de code possède des raccourcis clavier pratiques rendant l'édition des lignes de code plus rapide :

Touches Effet
Shift ↵ Enter Ajouter une nouvelle ligne après la ligne courante.
Ctrl / Faire défiler la vue vers le haut/le bas.
CtrlShift / Déplacer le curseur sur le membre précédent/suivant de la classe.
Alt / Déplacer la ligne courante ou les lignes sélectionnées vers le haut/le bas dans le texte.
CtrlAlt / Dupliquer la ligne courante ou les lignes sélectionnées vers le haut/le bas.
CtrlShift : Commenter/Décommenter la ligne courante.

Complétion de code

L'éditeur de code peut compléter automatiquement le code là où se trouve le curseur :

Touches Effet
Ctrl Espace Ouvrir la liste des suggestions de complétion.

Une fois la suggestion choisie, la validation se fait par l'une des touches suivantes :

  • ↵ Enter, n'ajoute rien derrière la suggestion ;
  • Espace ou ., ajoute également le caractère produit derrière la suggestion.

Toute autre touche produit le caractère sans valider (annuler la complétion).

AltShift : Complète avec la seule possibilité, ou produit un bip s'il y a plusieurs possibilités.

Navigation et autres astuces

  • Dans les codes sources dépassant la hauteur de fenêtre de l'éditeur, placez le pointeur de la souris sur l'accolade fermante d'un bloc pour voir apparaître un résumé du code d'ouverture du bloc en bulle d'aide. Ceci est fort utile pour vérifier quel bloc est fermé par l'accolade sans avoir à faire défiler le code.
  • Placez le pointeur de la souris sur un identifiant de classe, méthode ou variable et enfoncez la touche Ctrl pour faire apparaître un lien cliquable vers la définition.
  • Cliquez sur un identifiant de membre de classe pour faire apparaître toutes les occurrences d'utilisation dans le fichier : à la fois dans le texte et dans la barre de défilement. Les blocs apparaissant dans la barre de défilement sont cliquables pour faire défiler le code à la position de l’occurrence. Il y a deux couleurs distinctes pour les occurrences utilisées en lecture (accès, appel, ...) et celles utilisées en écriture (affectation).
    Il peut arriver que cela ne semble pas fonctionner car l'éditeur peut être dans un mode autre que celui par défaut. Il faut dans ce cas appuyer une ou deux fois la touche Échap pour que cela fonctionne.


Première utilisation d'Eclipse[modifier | modifier le wikicode]

  • Créez un nouveau projet (File > New > Project) de type Standard Make C Project nommé "Exercices". Ensuite depuis l'arborescence de projet, rajoutez un nouveaux fichier source (New > Source File.
  • Après avoir modifié votre source, dans le menu déroulant Project > Build all.
  • L'exécution se lance depuis le menu déroulant Run.

Références[modifier | modifier le wikicode]

  1. Site Apple Xcode Tool : [1].
  2. 2,0 et 2,1 Le site du projet libre MinGW et MSys : [2].
  3. Page d'accueil des projets MinGW et Msys : MinGW - Home
  4. https://eclipse.org/cdt/
  5. (anglais) http://pydev.org/


Notions de base

Ces exercices sur les notions de base abordent :

  • définition de fonction
  • la fonction main
  • l'appel de fonction
  • la bibliothèques standard, l'inclusion avec le préprocesseur
  • la sortie formatée avec printf
  • les paramètres de main

Exercice 1 : programme minimal nop[modifier | modifier le wikicode]

Écrire un programme qui ne fait rien (nop signifie no operation, soit « aucune opération »).

Pour le compiler et l'exécuter :

> gcc -Wall -o nop.exe nop.c
> ./nop.exe
>

Remarque qualité :

  • L'option -Wall n'est pas obligatoire. Elle demande au compilateur de signaler toutes les fautes qu'il peut détecter. Cela produit quelquefois des warnings ou avertissement que le programmeur, désireux de produire un code de qualité, s'efforcera de comprendre la signification et de corriger.
  • Je donne l'extension .exe à l'exécutable produit pour l'identifier plus facilement. Sous Windows l'extension .exe est obligatoire et rajoutée par l'éditeur de lien si oubli.

Notions :

  • définition de fonction
  • fonction principale main servant de point d'entrée
  • valeur retournée par une fonction

Exercice 2 : programme false[modifier | modifier le wikicode]

Dans les faits, le programme précédent retourne toujours le code de succès 0 ; il correspond donc à la commande Unix true. La commande true retourne systématiquement le code de succès 0.

MacMini-TM:~ thierry$ true
MacMini-TM:~ thierry$ echo $?
0

Pour écrire faux (équivalent du programme UNIX false), cet exercice introduit une complication : l'appel d'une fonction contenue dans le même fichier source que la fonction principale main.

Écrire la fonction main() d'un programme faux qui appelle la fonction un suivante et retourne sa valeur à la sortie :

La fonction a appeler :

int un(void)
{
  return 1;
}

Pour compiler et exécuter :

> gcc -Wall -o faux.exe faux.c
> ./faux.exe
> echo $?
1

Notions :

  • déclaration de fonction
  • appel de fonction
  • prototype de fonction

Exercice 3 : programme hello, world[modifier | modifier le wikicode]

Écrire un programme qui affiche hello, world.

> gcc  -o hello.exe hello.c
> ./hello.exe
hello, world
>

Notions :

  • inclusion d'en-tête standard
  • passage de paramètres de fonction
  • printf
  • chaîne de caractères statique

Exercice 4 : programme comptant les arguments en ligne de commande[modifier | modifier le wikicode]

Écrire un programme qui affiche le nombre de paramètres en ligne de commande (en anglais, les arguments sont les données passées au programme, ou à une fonction).

Compilation et exécutions attendues :

> gcc -Wall -o arg.exe arg.c 
> ./arg.exe
0
> ./arg.exe foo bar
2

Notions :

  • paramètres de main
  • sortie formatée


Variables et constantes

Entrée d'une valeur[modifier | modifier le wikicode]

Écrivez un programme age.c qui demande l'âge de l'utilisateur, puis qui l'affiche.

Pour lire l'age , vous utiliserez la fonction scanf déclarée dans stdio.h sous la forme (void)scanf("%d", &ageLu);.

Calculer si un nombre est premier[modifier | modifier le wikicode]

p est premier si et seulement si quel que soit 2<=i<=p-1 on a : i ne divise pas p.


Types

Exercice 1 : longueurs en octet des types du langage C[modifier | modifier le wikicode]

Écrivez un programme taille.c qui affiche à l'écran la taille des différents types de données en octet du langage C sur votre architecture machine.

Vous utiliserez l'opérateur sizeof(type).

Exercice 2 : caractéristiques numériques des types du langage C[modifier | modifier le wikicode]

Écrivez un programme limites.c qui affiche à l'écran les caractéristiques numériques des différents types du langage C.

Vous utiliserez les constantes symboliques des includes limits.h et float.h.


Les opérateurs

Pour les besoins de certains exercices, on rappelle le tableau de priorité des opérateurs du C :

Catégorie d'opérateurs
Opérateurs
Associativité
fonction, tableau, membre de structure, pointeur sur un membre de structure ( ) [ ] . -> Gauche -> Droite
opérateurs unaires - ++ -- ! ~

* & sizeof (type)

Droite ->Gauche
multiplication, division, modulo * / % Gauche -> Droite
addition, soustraction + - Gauche -> Droite
décalage << >> Gauche -> Droite
opérateurs relationnels < <= > >= Gauche -> Droite
opérateurs de comparaison == != Gauche -> Droite
et binaire & Gauche -> Droite
ou exclusif binaire ^ Gauche -> Droite
ou binaire ǀ Gauche -> Droite
et logique && Gauche -> Droite
ou logique ǁ Gauche -> Droite
opérateur conditionnel ? : Droite -> Gauche
opérateurs d'affectation = += -= *= /= %=

&= ^= |= <<= >>=

Droite -> Gauche
opérateur virgule , Gauche -> Droite

La priorité des opérateurs va décroissante lorsqu'on se déplace du haut du tableau vers le bas du tableau. Quand les opérateurs ont même priorité, c'est la colonne de droite sur la distributivité qui est utilisée.

Analyse de programmes[modifier | modifier le wikicode]

Nous allons présenter dans cette section un ensemble d'exercices destinés à se familiariser avec les opérateurs du langage C.

Exercice 1[modifier | modifier le wikicode]

  • Quelle est la valeur de i après la suite d'instructions :
int i=10;
i = i-(i--);
  • Quelle est la valeur de i après la suite d'instructions :
int i=10;
i = i-(--i);

Exercice 2 : la priorité des opérateurs[modifier | modifier le wikicode]

Enlever les parenthèses des expressions suivantes lorsqu'elles peuvent être retirées.

a=(25*12)+b;
if ((a>4) &&(b==18)) { }
((a>=6)&&(b<18))||(c!=18)
c=(a=(b+10));

Évaluer ces expressions pour a=6, b=18 et c=24. On supposera que les valeurs données le sont pour chacune des lignes : il n'y a pas d'exécution séquentielle comme dans un programme.


Petit programme de calcul[modifier | modifier le wikicode]

Écrivez un programme calcul.c qui calcule la distance entre deux points d'un plan :

  • Lit les coordonnées de deux points : X1 (x1, y1) et X2 (x2, y2).
  • Affiche les données lues
  • Calcule la distance d entre les deux points X1 et X2, avec la formule :

  • Affiche le résultat à l'écran.


Structures de contrôle

Structures conditionnelles[modifier | modifier le wikicode]

Analyse de programme : choix multiple[modifier | modifier le wikicode]

Ces exercices d'analyses doivent être réalisés sans compilateurs, à la main à l'aide d'un crayon et d'une feuille de papier.

Soit le programme suivant :

#include <stdio.h>
#include <stdlib.h>
int main(void) {
  unsigned char i=7;
  i=i/2; //"/": division entière...
  switch(i) {
    case 1 : (void)printf("Premier\n");break;
    case 2 : (void)printf("Deuxième\n");break;
    case 3 : (void)printf("Troisième\n");break;
    default : (void)printf("Non classe\n");
  }
  return EXIT_SUCCESS;
}

Qu'est ce qui sera affiché à l'écran lors de l'exécution de ce programme ?

Même question pour le programme :

#include <stdio.h>
#include <stdlib.h>
int main(void) {
  int i=18;
  i=i-(--i);
  switch(i) {
    case 1 : (void)printf("Premier\n");
    case 2 : (void)printf("Deuxième\n");
    case 3 : (void)printf("Troisième\n");
    default : (void)printf("Non classe\n");
  }
  return EXIT_SUCCESS;
}

Test simple : programme non complet[modifier | modifier le wikicode]

Écrire la partie de programme réalisant la structure de contrôle demandée. On ne demande pas le programme en entier : pas les "include" pas le main()...

Un test sur une valeur dans la variable i : si i vaut 19 on écrit "OK" autrement on écrit "Rejet"

Tester votre âge[modifier | modifier le wikicode]

Écrire un programme testage.c contenant une fonction main qui :

  • lit sur le clavier l'âge de l'utilisateur avec la fonction scanf;
  • teste si la réponse est valide par analyse du code retour de scanf et teste si la valeur est comprise entre 0 et 130;
  • affiche si l'utilisateur est majeur (>= 18 ans) ou mineur.

Structures répétitives[modifier | modifier le wikicode]

Analyse de programme : boucle simple[modifier | modifier le wikicode]

Cet exercice d'analyse doit être réalisé sans compilateur, à la main à l'aide d'un crayon et d'une feuille de papier. Soit le programme suivant :

#include <stdio.h>
#include <stdlib.h>
int main(void){
  int i;
  for (i=0;i<5;i++) {// "/": division entiere
    (void)printf("Module EC%d\n",(i+9)/(i+1));
  }
  return EXIT_SUCCESS;
}

Qu'affichera à l'écran l'exécution de ce programme ?

Analyse de programme : boucle simple et tableau[modifier | modifier le wikicode]

Cet exercice d'analyse doit être réalisé sans compilateur, à la main à l'aide d'un crayon et d'une feuille de papier.

Soit le programme suivant :

#include <stdio.h>
#include <stdlib.h>
int main(void){
  unsigned char i;
  unsigned char tab[5];
//initialisation du tableau
  tab[0]=1;tab[1]=2;tab[2]=4;tab[3]=8;tab[4]=16;
  for (i=0;i<5;i++) {
    (void)printf("Le %d° elt est %d\n",i+1,tab[i]);
  }
  return EXIT_SUCCESS;
}

Qu'affichera à l'écran l'exécution de ce programme ?

Somme d'entiers (boucle simple)[modifier | modifier le wikicode]

Écrire un programme somme demandant à l'utilisateur de taper 10 entiers et qui affiche leur somme. Le programme ne devra utiliser que 3 variables et ne devra pas utiliser de tableau.

Analyse de programme (double boucle)[modifier | modifier le wikicode]

Ces exercices d'analyses doivent être réalisés sans compilateurs, à la main à l'aide d'un crayon et d'une feuille de papier.

  • Soit le programme suivant :
#include <stdio.h> // pour printf
#include <stdlib.h> // pour system
main() {
  int i,j;
    system("clear"); //efface ecran sous linux (system("cls"); sous Windows)
    for(i=0;i<5;i++){
      for(j=i;j<5;j++)
        (void)printf("**");
      (void)printf("\n");
    }
    return EXIT_SUCCESS;
}

Que sera-t-il affiché à l'écran lors d'une exécution de ce programme ?

  • Même question pour le programme suivant :
#include <stdio.h> // pour printf
#include <stdlib.h> // pour system
main() {
  int i,j;
    system("clear"); //efface ecran sous linux (system("cls"); sous Windows)
    for(i=0;i<5;i++){
      for(j=5-i;j<5;j++)
        (void)printf("++");
      (void)printf("\n");
    }
    return EXIT_SUCCESS;
}

Triangle d'étoiles (double boucles)[modifier | modifier le wikicode]

Compléter la fonction afficherTriangle dans le programme ci-dessous : cette fonction devra afficher un triangle rempli d'étoiles (*) sur un nombre de lignes donné passé en paramètre, exemple :

*
**
***
****
*****
******
*******
********
  • 1ère version  : sans utiliser de tableau à l'aide de deux boucles for imbriquées.
  • 2ème version : avec une seule boucle for et un tableau de chaîne de caractère où vous accumulerez des étoiles.
/*
Nom : etoile.c
Compilation : gcc -Wall -std=c99 -o etoile.exe etoile.c
Exécution : ./etoile.exe
*/
#include <stdio.h>
#include <stdlib.h>

/*
Nom ... : afficherTriangle
Role .. : Afficher un triangle d'etoiles
Parametre :
	nbLignes : nombre de lignes du triangle
*/
static void afficherTriangle(const int nbLignes)
{
// Partie à compléter
} // static void afficherTriangle(...

// Fonction principale pour test
int main(void)
{
	int nbLignes = 0;
	int nbChampsLu = 0;
	int codeRetour = EXIT_SUCCESS;

	(void)fputs("Lignes ? ", stdout);
	nbChampsLu = scanf("%u", &nbLignes);
	if (nbChampsLu == 1 && nbLignes > 0)
	{
		afficherTriangle(nbLignes);
	}
	else
	{
		(void)fputs("Erreur : Vous devez entrer un entier strictement positif !\n",
			stderr);
		codeRetour = EXIT_FAILURE;
    }

    return codeRetour;
} // int main(...



Tableaux statiques

Parcours d'un tableau[modifier | modifier le wikicode]

Écrire un programme nommé argv.c qui affiche :

  • son nom de lancement (argv[0]);
  • le nombre des ces arguments;
  • la valeur de chaque argument reçu.

Rappels : La fonction main d'un programme C reçoit en argument :

  • un entier argc indiquant le nombre d'élément du tableau argv;
  • un tableau de chaînes de caractère argv avec :
    • argv[0] : Nom d'appel du programme.
    • argv[i] : Valeur de l'argument de rang i.

Position d'un élément dans un tableau[modifier | modifier le wikicode]

Écrire un programme position.c contenant une fonction principale main déterminant si un entier est contenu dans un tableau statique par l'appel à une fonction position.

La fonction main :

  • définira et initialisera le tableau d'entier
  • récupérera dans son tableau d'argument argv le nombre à chercher.
  • appellera la fonction position.
  • affichera l'indice de l'élément dans le tableau ou un message indiquant que le nombre n'a pas été trouvé.

La fonction position :

  • aura pour prototype : static int position(int t[], int taille, int x).
  • donnera l'indice d'un élément x dans le tableau t, ou -1 si x n'est pas trouvé.


Fonctions

Ces exercices concernent l'utilisation des fonctions de la bibliothèque standard du langage C.

Filtre qui passe le texte en majuscule[modifier | modifier le wikicode]

Problème à résoudre[modifier | modifier le wikicode]

Écrivez un programme majuscule.c qui lit des données sur le flux stdin et écrits sur stdout après avoir transformé les caractères lus en majuscules. Vous utiliserez les fonctions getchar, putchar (stdio.h) et toupper (ctype.h).

Vous testerez votre programme en lui faisant convertir son propre fichier source majuscule.c.

majuscule.exe < majuscule.c

Solution proposée[modifier | modifier le wikicode]

Lire une ligne longue avec fgets[modifier | modifier le wikicode]

Problème à résoudre[modifier | modifier le wikicode]

La fonction fgets de la bibliothèque standard du langage C permet de lire une chaîne de caractère de longueur limitée dans un flux.

Vous allez compléter une fonction lire_ligne répondant au spécifications suivantes :

  • Retour d'une ligne lue dans un flux texte passé en paramètre.
  • Vous éliminerez les caractères de saut de ligne lus.
  • La longueur des lignes lues n'est pas limitée.
  • Contrôle des paramètres et retour des codes d'erreurs systèmes, détection de la fin du fichier.
  • Vous utiliserez au maximum les fonctions de la bibliothèque standard du langage C : allocation mémoire, chaînes de caractères...
  • Son prototype est donné par lire_ligne.h.
  • Vous utiliserez le programme de main_lire_ligne.c pour lire_ligne.
  • Vous devrez traiter le fichier test_lire_ligne.txt fourni.
  • Les instructions de compilation et d'édition de lien sont dans les commentaires des fichiers fournis.

Éléments fournis[modifier | modifier le wikicode]

Solution proposée[modifier | modifier le wikicode]

Remarques sur l'exercice[modifier | modifier le wikicode]

  • Le test des paramètres dans la solution est expéditif.
  • Pour obtenir des programmes robustes, le langage C oblige à une gestion pénible des erreurs. Avec le langage Java par exemple, les mécanismes d'exception facilitent la tâche du programmeur.
  • L'utilisation de l'allocation dynamique de mémoire est risquée : fuite mémoire. Avec le langage Java par exemple, le ramasse miettes (Garbage collector) se charge de la libération de la mémoire.
  • En Java des classes comme String et StringBuffer prennent en charge les chaines de caractères longues.

Test d'un générateur de nombre aléatoire[modifier | modifier le wikicode]

Problème à résoudre[modifier | modifier le wikicode]

La bibliothèque standard du langage C offre au programmeur plusieurs fonctions pour générer des nombres aléatoires. La plus connue est rand().

Vous allez écrire un programme verifrand.c qui estime la répartition des nombres aléatoires générés : moyenne et dispersion. Nous allons traiter l'ensemble des nombres générés comme une série discrète regroupée.

  1. Générez 1 million (NB_TIRAGE) notes (xi) entre 0 et 20 (N) comprises (NB_NOTE = 21) à l'aide de la fonction rand().
  2. Répartissez-les dans le tableau effectif (n) où ni représente l'effectif (nombre d'occurrences cumulées) de la note xi.
  3. calculez et affichez la moyenne arithmétique :
  4. calculez et affichez l'écart moyen de la série :

Solution proposée[modifier | modifier le wikicode]

Remarques sur l'exercice[modifier | modifier le wikicode]

  • La série générée avec rand() sur ma machine est bien centrée sur la moyenne théorique 10/20 : les nombres de notes en dessous et au dessus de 10 sont quasi-identiques. L'écart moyen de la série est proche de 5 ce qui indique que les notes sont bien réparties.
  • La fonction rand() est pseudo-aléatoire : deux exécutions du programme donnent exactement la même série de note.
  • Vous pouvez tester d'autres fonctions comme random() ou arc4random(). Cette dernière, de qualité cryptographique, utilise l'algorithme nommé ARC4. Elle est aléatoire.


Chaines

Longueur d'une chaîne de caractères (pour manipuler)[modifier | modifier le wikicode]

Écrire une fonction C calculant la longueur en octets d'une chaîne de caractères, donnée en argument.

À titre d'exercice, ne pas utiliser la fonction strlen() du fichier d'entête string.h.

Longueur d'une chaîne de caractères (par une fonction)[modifier | modifier le wikicode]

Écrire un programme lgChaine.c :

  • qui lit des chaînes de caractères tapées au clavier (flux stdin) ;
  • qui calcule la longueur de chaque chaîne entrée et l'affiche ainsi que sa longueur ;
  • qui s'arrête si l'utilisateur ne frappe que la touche Entrée ou si le fichier est fini (Ctrl-D tapé par l'utilisateur).

Vous utiliserez :

  • une des fonctions déclarée dans stdio.h.
  • la fonction strlen, ainsi que d'autres si nécessaire, déclarée dans string.h.


Pointeurs

Soit un texte donné par une chaîne de caractères. Le but est de compter le nombre d'occurrences de chaque lettre sans distinction entre minuscules et majuscules.

Exercice 1[modifier | modifier le wikicode]

Question 1[modifier | modifier le wikicode]

Déclarer le texte comme un tableau statique initialisé par une chaîne de caractères constante, un tableau d'entiers statique pour compter les occurrences dont la taille est fixée par une constante et un pointeur pour parcourir le texte.

Question 2[modifier | modifier le wikicode]

Initialiser le vecteur d'entiers avec un parcours par indice.

Question 3[modifier | modifier le wikicode]

Compter les occurrences en utilisant la conversion entre le type char et le type int (la conversion d'un caractère donne son code dans le standard américain).

Question 4[modifier | modifier le wikicode]

Afficher le résultat sur la sortie standard.

Exercice 2[modifier | modifier le wikicode]

Pointeurs et références[modifier | modifier le wikicode]

Donner et expliquer le résultat de l'exécution du programme suivant :

#include <stdio.h>
#define taille_max 5

void parcours(int *tab)
{
  int *q=tab;
  do
  {
    printf("%d:%d\n", q-tab, *q-*tab);
  }
  while (++q-tab < taille_max);
}


void bizarre(int **copie, int *source)
{
  *copie=source;
}

int main(void)
{
  int chose[taille_max] = {1,3,2,4,5}, *truc;
  printf("chose : \n");
  parcours(chose);
  bizarre(&truc, chose);
  printf("truc : \n");
  parcours(truc);

  return 0;
}


Préprocesseur

Exercice 1[modifier | modifier le wikicode]

Écrire un fichier source hello.c. Les résultats du programme exécutable seront différents selon les options passées au préprocesseur sur la ligne de commande de compilation. Ce programme affichera :

  • "Hello World", si la constante symbolique WORLD est définie.
  • "Hello Fof", si FOF est définie.
  • "Hello Nobody", si aucune de ces constantes n'est définie.

Lignes de Compilation avec gcc :

  • gcc -D WORLD -o hello.exe hello.c
  • gcc -D FOF -o hello.exe hello.c
  • gcc -o hello.exe hello.c

Exécution : ./hello.exe

GFDL GFDL Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans texte de dernière page de couverture.