Exercices programmation avec le langage C

Exercice (1) : Ecrire une commande

Ecrire une commande appelable soit avec 0, 1, 2 ou 3 arguments.

Appelée avec:

0 paramètre, elle donnera le calendrier de l'année en cours (et non l’année 2008),

1 paramètre, elle donnera le calendrier de l'année indiquée,

2 paramètres, elle donnera le mois de l'année indiquée,

3 paramètres, elle donnera deux mois de l'année indiquée, plus de trois paramètres message d'erreurs

Exemple d'utilisation:

Calendrier

Calendrier 2008

Calendrier 4 2008

Calendrier 3 9 202008

Solution : 

#/bin/tcsh
switch ($#argv)
case 0 :
set d = `date`
cal $d[6]
breaksw
case 1 :
cal $1
breaksw
case 2 :
cal $1 $2
breaksw
case 3 :
cal $1 $3
cal $2 $3
breaksw
default
echo trop de parametres
endsw

Exercice (2) : Pointeur

pi est un pointeur sur un entier;  pi vaut 0x5000 et son contenu vaut 300.
Ecrire le programme correspondant ().
L'opérateur de "cast", permet d'autre part, à des pointeurs de types différent de pointer sur la même adresse.

Exemple :
char *pc;/* pc pointe sur un objet de type caractère */
int *pi;/* pi pointe sur un objet de type entier */
pi = (int*)malloc(4) ;  /* allocation dynamique pour i */
pc = (char*)i;/* c et i pointent sur la même adresse, c sur un caractère  */

Solution :

#include
#include
#include
void main()
{
int *i;
i = (int*)malloc(4);
*i = 300;
printf(" adresse = %p variable = %d\n",i,*i);
free(i);
printf("\nPOUR CONTINUER FRAPPER UNE TOUCHE ");
getch();
}

Exercice (3) : Boucles Complexes

Cet exercice a pour but de vérifier les points techniques suivants :

  • Utilisation des boucles for.
  • Imbrication de boucles.

Travail à faire :

Ecrire un programme qui demande à l'utilisateur de saisir un entier N et qui affiche la figure suivante.

N=1

*

N=2

**

*

N=3

***

**

*

Et ainsi de suite

Solution :

#include
using namespace std;
int main()
{
int i,j,N;
cout>N;
for(i=1;i{
for(j=1;jfor(j=1;jcout}
return 0;
}

Exercice (4) : Utilisation des Commandes

Objectif :

Travailler avec les Procédures et Fonctions

Travail à Faire :

Ecrire une commande utilisant la commande vi, pico, ou joe de façon à avoir trois versions d'un même fichier. Chaque fichier a une extension:

fic.1 dernière version

fic.2 avant dernière version

fic.3 avant dernière version

L’ouverture ou la création des fichiers se fait sans extension

Solution :

#/bin/tcsh
if (! -f $argv[1].1) then
vi $1.1
else
cp $argv[1].1 temp
vi $argv[1].1
cmp -s $argv[1].1 temp
switch ($status)
case 0 :
rm temp
breaksw
case 1 :
if (-f $argv[1].2) then
cp $argv[1].2 $argv[1].3
endif
mv temp $argv[1].2
breaksw
endsw
endif

Exercice (5) : Pointer sur des nombres Réels

adr1 et adr2 sont des pointeurs pointant sur des réels.

Le contenu de adr1 vaut -45,78; le contenu de adr2 vaut 678,89.

Travail à Faire:

Écrire un programme qui affiche les valeurs de adr1, adr2 et de leur contenu.

Solution :


#include
#include
#include
void main()
{
float *adr1,*adr2;
adr1 = (float*)malloc(4);
adr2 = (float*)malloc(4);
adr1 = -45.78;
**adr2 = 678.89;
printf("adr1 = %p adr2 = %p r1 = %f r2 = %f\n",adr1,adr2,*adr1,*adr2);
free(adr1);
free(adr2);
printf("\nPOUR CONTINUER FRAPPER UNE TOUCHE ");
getch();
}

Exercice (5) : Tassage et Fusion de suites ordonnées

  1. TASSAGE. Etant donné un tableau U de I nombres positifs ou nuls, écrivez le programme qui le tasse, c’est à dire qui détecte les éléments nuls du tableau et qui récupère leur place en décalant vers le début du tableau tous les autres éléments.
  2. FUSION DE SUITES ORDONNEES.
    1. Soient A et B deux tableaux triés de nombres entiers. 
      1. Ecrivez le programme qui les fusionne en un unique tableau C trié, constitué des éléments de A et de ceux de B.

Solution :

1.

[1] Première solution (juste mais onéreuse) :

#include
#define N 20
int i, j, n,
/* pour la mise au point */
t[N] = { 1, 2, 0, 3, 0, 0, 4, 5, 0, 6, 0, 7, 0, 0, 8, 9, 0, 0, 0, 10 };
main(void) {
n = N;
i = 0;
while (i if (t[i] == 0) {
for (j = i + 1; j t[j - 1] = t[j];
n--;
} else
i++;
for (i = 0; i printf("%d ", t[i]);
printf("\n");
}

C'est sans doute la première idée qui vient à l'esprit : parcourir le tableau (i représente ce parcours) et lorsque t[i] est nul : avancer d'une position tous les éléments entre t[i+1] et t[n - 1], decrémenter n et ne pas incrémenter i, car l'élément qui était à la position i+1 et qui est maintenant à la position i est peut-être nul lui aussi.

[2] Cela est juste mais pas très efficace : une boucle imbriquée dans une autre, cela implique souvent des opérations répétées de l'ordre de n2 fois. [ Par exemple, ici, si on suppose qu'un élément sur deux est nul, l'opérationt[j - 1] = t[j] sera exécutée n-2 fois, puis n-4 fois, ensuite n-6 fois, etc. et, au total, un nombre de fois proche de la moitié de la somme des n-2 premiers entiers. Soit (n-2)(n-1)/4, c'est bien de l'ordre de n2. ]

Pourquoi ne pas faire un seul parcours du tableau, en plaçant chaque élément non nul directement à sa place finale ? Le programme obtenu est d'un coût linéaire, c'est à dire de l'ordre de n obtenu (En fait, la bonne question est : pourquoi on n'a pas eu cette idée en premier ?) :

#include
#define N 20
int i, j, n,
/* pour la mise au point */
t[N] = { 1, 2, 0, 3, 0, 0, 4, 5, 0, 6, 0, 7, 0, 0, 8, 9, 0, 0, 0, 10 };
main(void) {
n = N;
j = 0;
for (i = 0; i if (t[i] != 0)
t[j++] = t[i];
n = j;
for (i = 0; i printf("%d ", t[i]);
printf("\n");
}

2.

#include
#define NA 12
#define NB 8
int c[NA + NB], ia, ib, ic, i,
/* pour la mise au point */
a[NA] = { 1, 3, 4, 8, 9, 11, 12, 14, 17, 18, 19, 20},
b[NB] = { 2, 5, 6, 7, 10, 13, 15, 16 };
main(void) {
ia = 0;
ib = 0;
ic = 0;
while (ia if (a[ia] c[ic++] = a[ia++];
else
c[ic++] = b[ib++];
while (ia c[ic++] = a[ia++];
while (ib c[ic++] = b[ib++];
for (i = 0; i printf("%d ", c[i]);
printf("\n");
system("pause");
}

Il s'agit de l'algorithme classique de la fusion de deux suites triées : tant qu'il reste des éléments à examiner dans l'un et l'autre tableau, on compare l'élément du premier tableau dont c'est le tour avec celui du second tableau dont c'est le tour également, et on fait passer le plus petit des deux dans le tableau résultat. Quand un des deux tableaux est épuisé il faut recopier ce qui reste dans l'autre tableau.

Observez que les deux tableaux donnés doivent être triés, et que le tableau résultat est alors trié.

Le sujet n'en dit rien, mais s'il avait fallu réduire les doublons alors il aurait fallu écrire la partie centrale comme ceci :

...
while (ia if (a[ia] = b[ib]) {
c[ic++] = a[ia++];
ib++;
} else if (a[ia] c[ic++] = a[ia++];
else
c[ic++] = b[ib++];
...

Exercice (6) : Validation des données saisies par l'utilisateur


Cet exercice a pour but de vérifier les points techniques suivants :

  • Utilisation simple du while.
  • Validation des données saisies par l'utilisateur.

Travail à Faire :

Ecrire un programme qui demande à l’utilisateur de taper un entier N entre 0 et 20 bornes incluses et qui affiche N+17.
Si on tape une valeur erronée, il faut afficher "erreur" et demander de saisir à nouveau l'entier.

Solution :

#include
using namespace std;
int main()
{
int N;
bool ok;
do
{
cout>N;
ok= N=0;
if(!ok)cout}
while(!ok);
N=N+17;
coutreturn 0;
}

Exercice (7) : programme affiche les statistique des notes

Ecrire un programme qui lit les points de N élèves d'une classe dans un devoir et les mémorise dans un tableau POINTS de dimension N.

* Rechercher et afficher:

- la note maximale,

- la note minimale,

- la moyenne des notes

* A partir des POINTS des élèves, établir un tableau NOTES de dimension 7 qui est composé de la façon suivante:

NOTES[6] contient le nombre de notes 60

NOTES[5] contient le nombre de notes de 50 à 59

NOTES[4] contient le nombre de notes de 40 à 49

...

NOTES[0] contient le nombre de notes de 0 à 9

Etablir un graphique de barreaux représentant le tableau NOTES. Utilisez les symboles pour la représentation des barreaux et affichez le domaine des notes en dessous du graphique.

Idée: Déterminer la valeur maximale MAXN dans le tableau NOTES et afficher autant de lignes sur l'écran. (Dans l'exemple ci-dessous, MAXN = 6). 

Exemple:

La note maximale est 58
La note minimale est 13
La moyenne des notes est 37.250000


6 > #######
5 > ####### #######
4 > ####### ####### #######
3 > ####### ####### ####### #######
2 > ####### ####### ####### ####### #######
1 > ####### ####### ####### ####### #######
+-------+-------+-------+-------+-------+-------+-------+
I 0 - 9 I 10-19 I 20-29 I 30-39 I 40-49 I 50-59 I 60 I

Solution :

#include
main()
{
int POINTS[50]; /* tableau des points */
int NOTES[7]; /* tableau des notes */
int N; /* nombre d'élèves */
int I, IN; /* compteurs d'aide */
int SOM; /* somme des points */
int MAX, MIN; /* maximum, minimum de points */
int MAXN; /* nombre de lignes du graphique */

/* Saisie des données */
printf("Entrez le nombre d'élèves (max.50) : ");
scanf("%d", &N);
printf("Entrez les points des élèves:\n");
for (I=0; I{printf("Elève %d:", I+1);
scanf("%d", &POINTS[I]);
}
printf("\n");
/* Calcul et affichage du maximum et du minimum des points */
for (MAX=0, MIN=60, I=0; I{if (POINTS[I] > MAX) MAX=POINTS[I];
if (POINTS[I] }
printf("La note maximale est %d \n", MAX);
printf("La note minimale est %d \n", MIN);
/* Calcul et affichage de la moyenne des points */
for (SOM=0,I=0 ; ISOM += POINTS[I];
printf("La moyenne des notes est %f \n", (float)SOM/N);
/* Etablissement du tableau NOTES */
for (IN=0 ; INNOTES[IN] = 0;
for (I=0; INOTES[POINTS[I]/10]++;
/* Recherche du maximum MAXN dans NOTES */
for (MAXN=0,IN=0 ; INif (NOTES[IN] > MAXN)
MAXN = NOTES[IN];
/* Affichage du graphique de barreaux */
/* Représentation de MAXN lignes */
for (I=MAXN; I>0; I--)
{
printf("\n %2d >", I);
for (IN=0; IN{
if (NOTES[IN]>=I)
printf(" #######");
else
printf(" ");
}
}
/* Affichage du domaine des notes */
printf("\n +");
for (IN=0; INprintf("-------+");
printf("\n I 0 - 9 I 10-19 I 20-29 "
"I 30-39 I 40-49 I 50-59 I 60 I\n");
return 0;
}

Exercice (8) : Procédure commande

Objectif :

Travailler avec les Procédures et Fonctions

Travail à Faire :

Ecrire une Procédure commande qui permet d’afficher le contenu du répertoire courant. Cette procédure peut être appelée avec trois options:

  • C affiche seulement les fichiers cachés,
  • F  affiche seulement les fichiers ordinaires,
  • D  affiche seulement les fichiers répertoires, sans option affiche tous les fichiers (les trois types).

Solution :

#/bin/tcsh
if ( $argv == 0 ) then
ls –la
else
if ( $argv == 1 ) then
switch ($1)
case ‘-c’ :
set fic = `ls .[a-z]*`
foreach f ($fic)
if ( -f $f ) ls –l $f
end
breaksw
case ‘-f’ :
set fic = `ls`
foreach f ($fic)
if ( -f $f ) ls –l $f
end
breaksw
case ‘-d’ :
set fic = `ls -a`
foreach f ($fic)
if ( -f $f ) ls –l $f
end
breaksw
endsw
endif
endif

Exercice (9) : Programme qui affiche tous les couples ( x , y)

Travail à Faire :

Ecrivez un programme qui affiche tous les couples ( x , y), où x est un entier compris entre 1 et p et y un entier compris entre 1 et q ; p et q sont deux entiers lus au clavier.

L’affichage doit se faire comme sur l’exemple suivant, qui correspond à  p = 3 et ? q = 5 :

( 1 , 1 ) ( 1 , 2 ) ( 1 , 3 ) ( 1 , 4 ) ( 1 , 5 )

( 2 , 1 ) ( 2 , 2 ) ( 2 , 3 ) ( 2 , 4 ) ( 2 , 5 )

( 3 , 1 ) ( 3 , 2 ) ( 3 , 3 ) ( 3 , 4 ) ( 3 , 5 )

Solution :

#include
int p, q, i, j;
main() {
printf("p q ? ");
scanf("%d%d", &p, &q);
for (i = 1; i for (j = 1; j printf("( %d , %d ) ", i, j);
printf("\n");
}
}

Ne cherchez pas la matrice, il n'y en a pas. Cet exercice est une plaisanterie, un entraînement basique sur les boucles imbriquées et la manière d'obtenir un affichage en lignes et colonnes (cela nous servira plus tard). Ce qui se fait par

  • une boucle interne dont chaque itération fait un affichage élémentaire sans aller à la ligne,
  • une boucle externe, dont chaque itération se compose d'une exécution complète de la boucle interne (dont l'affichage de toute une ligne) puis un saut à la ligne suivante.

Exercice (10) : Ouverture d'un fichier en écriture

Cet exercice a pour but de vérifier les points techniques suivants :

  • L'ouverture d'un fichier en écriture
  • Tester si un fichier est ouvert (en particulier si vous avez les droits d'écriture sur le fichier)
  • Fermer le fichier une fois l'écriture terminée

Travail à Faire:

Ecrire un programme qui écrit dans le fichier example.txt le texte:

Voici un programme illustrant l'écriture dans un fichier

Solution :

#include
#include
int main (int argc, char * argv[]) {
std::ofstream myfile;
char * filename = "example.txt";
myfile.open (filename, std::ios::out);
if(myfile.is_open())
{
myfile myfile }
else
{
std::cout }
myfile.close();
return 0;
}

Article publié le 22 Février 2012 Mise à jour le Lundi, 07 Novembre 2022 19:07 par Babachekhe Mohamed