Exercices programmation avec le langage C
Rédigé par GC Team, Publié le 22 Février 2012, Mise à jour le Lundi, 07 Novembre 2022 19:07Exercice (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
Exemple :
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<<"Tapez la valeur de N : ";cin>>N;
for(i=1;i<=N;i++)
{
for(j=1;j<i;j++)cout<<" ";
for(j=1;j<=N+1-i;j++)cout<<"*";
cout<<endl;
}
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
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
- 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.
- FUSION DE SUITES ORDONNEES.
- Soient A et B deux tableaux triés de nombres entiers.
- Ecrivez le programme qui les fusionne en un unique tableau C trié, constitué des éléments de A et de ceux de B.
- Soient A et B deux tableaux triés de nombres entiers.
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 < n)
if (t[i] == 0) {
for (j = i + 1; j < n; j++)
t[j - 1] = t[j];
n--;
} else
i++;
for (i = 0; i < n; 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 < n; i++)
if (t[i] != 0)
t[j++] = t[i];
n = j;
for (i = 0; i < n; 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 < NA && ib < NB)
if (a[ia] <= b[ib])
c[ic++] = a[ia++];
else
c[ic++] = b[ib++];
while (ia < NA)
c[ic++] = a[ia++];
while (ib < NB)
c[ic++] = b[ib++];
for (i = 0; i < ic; 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 < NA && ib < NB)
if (a[ia] = b[ib]) {
c[ic++] = a[ia++];
ib++;
} else if (a[ia] < b[ib])
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<<"Tapez N entre 0 et 20 :";cin>>N;
ok= N<=20 && N>=0;
if(!ok)cout<<"ERREUR RECOMMENCEZ"<<endl;
}
while(!ok);
N=N+17;
cout<<"La valeur finale est : "<<N<<endl;
return 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<N; 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<N; I++)
{if (POINTS[I] > MAX) MAX=POINTS[I];
if (POINTS[I] < MIN) MIN=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 ; I
SOM += POINTS[I];
printf("La moyenne des notes est %f \n", (float)SOM/N);
/* Etablissement du tableau NOTES */
for (IN=0 ; IN
NOTES[IN] = 0;
for (I=0; I<N; I++)
NOTES[POINTS[I]/10]++;
/* Recherche du maximum MAXN dans NOTES */
for (MAXN=0,IN=0 ; IN
if (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<7; IN++)
{
if (NOTES[IN]>=I)
printf(" #######");
else
printf(" ");
}
}
/* Affichage du domaine des notes */
printf("\n +");
for (IN=0; IN<7; IN++)
printf("-------+");
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 <= p; i++) {
for (j = 1; j <= q; 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 << "Exercices Gratuit \n";
myfile << "Voici un programme illustrant l'écriture dans un fichier \n";
}
else
{
std::cout << "Erreur à l'ouverture du fichier "<< filename << std::endl;
}
myfile.close();
return 0;
}