0% ont trouvé ce document utile (0 vote)
10 vues30 pages

Exercices de C pour Ingénieurs en Prépa

Transféré par

Chaymae El maachi
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
10 vues30 pages

Exercices de C pour Ingénieurs en Prépa

Transféré par

Chaymae El maachi
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Travaux Dirigés

&
Tavaux Pratiques

Langage C

Rahmoune Mohammed

Ces exercices de travaux dirigés et travaux pratique sont dédiés pour les
élèves ingénieurs es classes préparatoires intégrés des Ecoles Nationales
des Sciences Appliquées
Sommaire

Les fonctions standards d’Entrées/Sorties- ................................................................................ 4

Rappel des functions d’entrées /sorties :............................................................................. 4

Les structures de contrôle conditionnelles ................................................................................. 5

Les structures de contrôle itératives ........................................................................................... 5

Conversion ................................................................................................................................. 7

Priorité ........................................................................................................................................ 8

Opérateurs bit à bit ................................................................................................................... 14

Tableaux ................................................................................................................................... 16

Chaîne de caractères ................................................................................................................. 18

Fonctions .................................................................................................................................. 20

Pointeurs................................................................................................................................... 22

Structures ................................................................................................................................. 25

2
3
Les fonctions standards d’Entrées/Sorties-

Rappel des functions d’entrées /sorties :


getchar() permet de renvoyer le code d’un caractère saisi à partir de l’organe standard d’entrée à
savoir le clavier.
Exemple : char c ; c=getchar( ) ;

putchar() permet d’afficher le caractère mis en paramètre sur l’organe standard de sortie à savoir
l’écran.
Exemple : char c ; c='a'; putchar(c) ;

scanf() permet d’affecter la valeur saisie à partir du clavier à la variable mise en paramètre
selon le type concerné.
scanf(<format>, <listes des adresses des variables>) ;
Une spécification de conversion commence par le caractère % suivi d’un type de conversion :
Exemple :
char c,y ;
float x ;
int i ;
scanf(³ %c ³, & c) ; /* saisir un caractère et le stocker dans la variable c */
scanf(³ %f %c %d ³,&x, &y, &i) ;
printf() permet d’afficher sur l’écran les variables mises en paramètre selon le type concerné.
printf(<format>, <listes des arguments>) ;
Exemple :
int i ;
char c ;
i=5 ;
c='a';
printf(³ %c %d ³ , c , i ) ; /* permet d’afficher l’entier 5 et le caractère a sur
l’écran */

Exercice 1.
Ecrire un programme C permettant de saisir 2 entiers a et b et d’afficher la somme, la
soustraction, le produit, la moyenne, le quotient et le reste de la division euclidienne de ces
deux entiers.

Corrigé :

#include "stdio.h "


main() {
int a, b;
scanf("%d%d",&a,&b) ;
printf("%d + %d = %d\n", a, b, a+b) ;
printf("%d - %d = %d\n", a, b, a-b) ;
printf("%d * %d = %d\n", a, b, a*b) ;
printf("%d % %d = %d\n", a, b, a%b) ;
printf("%d / %d = %d\n", a, b, a/b) ; }

4
Les structures de contrôle conditionnelles
Exercice 2.
Ecrire un programme C qui permet de tester si un caractère saisi à partir du clavier est une
voyelle en utilisant les différentes structures de contrôle conditionnelles.

Corrigé :

Solution 1: Utilisation de if

#include "stdio.h"
main() {
char c;
printf("Saisissez un caractère :");
scanf("%c",&c);
if(case: 'a'||case: 'e'||case: 'i'||case: 'o'||case: 'u'||case: 'y'||case: 'A'||case: 'E'||case:
'I'||case: 'O'|| case: 'U'||case: 'Y')
printf("%c est une voyelle", c);
else
printf("%c nest pas une voyelle", c);
}

Solution 2: Utilisation de switch


#include "stdio.h"
main() {
char c;
printf("Saisissez un caractère :");
scanf("%c",&c);
switch(c)
{case 'a' :
case 'e' :
case 'i' :
case 'o' :
case 'u' :
case 'y' :
case 'A' :
case 'E' :
case 'I':
case 'O' :
case 'U' :
case 'Y' : printf("%c est une voyelle", c);
default : printf("\n %c nest pas une voyelle", c);
}
}

Les structures de contrôle itératives


Exercice 3.
Calculez la somme des N premiers termes de la série harmonique : 1 + 1/2 + 1/3 + ... + 1/N .

5
Corrigé :

#include "stdio.h"
main()
{
int i, N;
float S = 0;
scanf("%d", &N);
for( i=1 ; i <= N ; i++) {
S = S +(float)1/i; }
printf ("la somme harmonique de ordre %d est %f ",N, S) ;
}

Exercice 4.

Soit le petit programme suivant :


#include <stdio.h>
main()
{
int i, n, som ;
som = 0 ;
for (i=0 ; i<4 ; i++)
{ printf ("donnez un entier ") ;
scanf ("%d", &n) ;
som += n ;
}
printf ("Somme : %d\n", som) ;
}
Écrire un programme réalisant exactement la même chose, en employant, à la place de
l’instruction for :
1- une instruction while,
2- une instruction do... while.

Corrigé :

1-
#include<stdio.h>
main()
{ int i, n, som ;
som = 0 ;
i = 0 ; /* ne pas oublier cette "initialisation" */
while (i<4)
{ printf ("donnez un entier ") ;
scanf ("%d", &n) ;
som += n ;
i++ ; /* ni cette "incrémentation" */
}

6
printf ("Somme : %d\n", som) ;}
2-
#include <stdio.h>
main()
{ int i, n, som ;
som = 0 ;
i = 0 ; /* ne pas oublier cette "initialisation" */
do
{ printf ("donnez un entier ") ;
scanf ("%d", &n) ;
som += n ;
i++ ; /* ni cette "incrémentation" */
}
while (i<4) ; /* attention, ici, toujours <4 */
printf ("Somme : %d\n", som) ;
}

Conversion

Exercice 5.

Soient les déclarations suivantes :


char c ='/x01' ;
short int p = 10 ;
Quels sont le type et la valeur de chacune des expressions suivantes :

p+3 ;
c+1 ;
p+c ;
3*p+5*c ;

Corrigé :

#include <stdio.h>
#include <stdlib.h>
main(int argc, char *argv[]) {
char c ='\x01' ;
short int p = 10 ;
printf("1- %d:\n",p+3);
printf("2- %d:\n",c+1);
printf("3-%d:\n",p+c);
printf("4-%d:\n",3*p+5*c);
}

1. p est d’abord soumis à la conversion systématique de short à int, avant d’être ajouté à
la valeur 3 qui est de type int. Le résultat de p+3 est 13 de type int.
2. C est d’abord soumis à la conversion systématique de char à int ce qui aboutit à une
valeur 1, avant d’être ajouté à la valeur 1 de type int. Le résultat de c+1 est 2 de type
int.

7
3. p est d’abord soumis à la conversion systématique de short à int, tandit que c est
soumis à la conversion implicite char ---> int , le résultat de p+c est 11 de type int.
4. p et c sont d’abord aux mêmes conversions implicite que ci-dessus ; le résultat est 35
de type int.

Exercice 6.

Soit les déclarations suivantes :

int n = 10 , p = 4 ;
long q = 2 ;
float x = 1.75 ;

Donner le type et la valeur de chacune des expressions suivantes :

a) n + q
b) n + x
c) n % p +q
d) n < p
e) n >= p
f) n > q
g) q + 3 * (n > p)
h) q && n
i) (q-2) && (n-10)
j) x * (q==2)
k) x *(q=5)

Corrigé :

a) long 12
b) float 11,75
c) long 4
d) int 0
e) int 1
f) int 1
g) long 5
h) int 1
i) int 0
j) float 1,75
k) float 8,75

Priorité

Exercice 7.

Etudier la priorité des parenthèses d ans les expressions suivantes :

1. a = (x+5)
2. a = (x=y) + 2

8
3. a = (x==y)
4. (a<b) && (c<d)
5. (i++) * (n+p)
Corrigé :

1. a = x+5 L'opérateur + est prioritaire par rapport à l'opérateur


d'affectation =.
2. a = (x=y) + 2 Ici, l'opérateur + étant prioritaire par rapport =, les parenthèses
sont indispensables.
3. a = x==y L'opérateur == est prioritaire par rapport =.
4. a<b && c<d L'opérateur && est prioritaire par rapport l’opérateur < .
5. i++ * (n+p) L'opérateur + + est prioritaire par rapport l’opérateur *; en
revanche * est prioritaire par rapport l’opérateur +; de sorte qu’on
ne peut pas éliminer les dernières parenthèses.

Exercice 8.

Afficher un triangle isocèle d’étoiles. La hauteur du triangle (le nombre de lignes) sera fournie
en donnée. On s’arrangera pour que la dernière ligne du triangle sur le bord gauche de l’écran.

Combien de lignes ? 10
*
***
*****
*******
*********
***********
*************
***************
*****************
*******************

Corrigé :

#include <stdio.h>
#include <stdlib.h>

#define car '*'


/* caractère de remplissage */
main()
{
int nlignes ; /* nombre total de lignes */
int nl ; /* compteur de ligne */
int nesp ; /* nombre d'espaces précédent une étoile */ int j ;

printf ("combien de lignes ? ") ;


scanf ("%d", &nlignes) ;
for (nl=0 ; nl<nlignes ; nl++){
nesp = nlignes - nl - 1 ;
for (j=0 ; j<nesp ; j++) putchar (' ') ;
for (j=0 ; j<2*nl+1 ; j++) putchar (car) ;

9
putchar ('\n') ;
}
}

Exercice 9.

Ecrire les programmes permettant de trouver le minimum de deux entiers, et le maximum de


trois entiers, la valeur médiane de trois réels. On utilisera d’abord les instructions de test, puis
les operateurs.

Corrigé :

Minimum de trois entiers

#include "stdio.h"
main ()
{
int x, y , z , resultat ;

/*saisie des valeurs de x, y et z */


printf("donnez les valeurs de x, y et z :") ;
scanf("%d %d %d",&x,&y,&z) ;
/* comparaisons */
if (x<y)
resultat=x ;
else
resultat = y ;
if (resultat > z)
resultat = z ;
printf("resultat %d : ",resultat) ;
}

Minimum de trois entiers avec des operateurs

#include "stdio.h"
main ()
{
int x, y , z , resultat ;
/*saisie des valeurs de x, y et z */
printf("donnez les valeurs de x, y et z :") ;
scanf("%d %d %d",&x,&y,&z) ;
resultat = x<y ? x : y ;
resultat = resultat<z ? resultat :z ;
printf("resultat %d : ",resultat) ;
}

Maximum de trois entiers

#include "stdio.h"
main ()
{
10
int x, y , z , resultat ;
/*saisie des valeurs de x, y et z */
printf("donnez les valeurs de x, y et z :") ;
scanf("%d %d %d",&x,&y,&z) ;
/* comparaisons */
if (x>y)
resultat=x ;
else
resultat = y ;
if (resultat < z)
resultat = z ;
printf("resultat %d : ",resultat) ;
}

Maximum de trois entiers avec des operateurs

#include "stdio.h"
main ()
{
int x, y , z , resultat ;
/*saisie des valeurs de x, y et z */
printf("donnez les valeurs de x, y et z :") ;
scanf("%d %d %d",&x,&y,&z) ;
resultat = x>y ? x : y ;
resultat = resultat>z ? resultat :z ;
printf("resultat %d : ",resultat) ;
}

La valeur médiane

#include "stdio.h"
main ()
{
int x, y , z , resultat ;
/*saisie des valeurs de x, y et z */
printf("donnez les valeurs de x, y et z :") ;
scanf("%d %d %d",&x,&y,&z) ;
/* comparaisons */
if (x<y)
if (y>z)
if(x<z)
resultat=z ;
else
resultat = x ;
else
resultat = y ;
else if(x>z)
if (y<z)
resultat = z ;
else
resultat = y ;
11
printf("resultat %d : ",resultat) ;
}

2ème proposition :

#include "stdio.h"
main ()
{
int x, y , z , resultat ;

/*saisie des valeurs de x, y et z */


printf("donnez les valeurs de x, y et z :") ;
scanf("%d %d %d",&x,&y,&z) ;
/* comparaisons */
if (x<y && x>z)
resultat = x ;
else if(y<x && y>z)
resultat = y ;
else
resultat = z ;

printf("resultat %d : ",resultat) ;
}

La valeur médiane

#include "stdio.h"
main ()
{
int x, y , z , resultat ;
/*saisie des valeurs de x, y et z */
printf("donnez les valeurs de x, y et z :") ;
scanf("%d %d %d",&x,&y,&z) ;
resultat = x<y ? (y>z ? (x<z ? z :x) :y) : (x>z ? (y<z ? z :y) : x ) ;
printf("resultat %d : ",resultat) ;
}

Exercice 10.
Ecrire le programme permettant de calculer N !

#include "stdio.h"
main ()
{
int n ; /* ordre */
int i,fact ; /* indice de boucle et resultat */
printf("introduire n= ") ;
scanf("%d",&n) ;
fact =1 ;
i =1 ; /*init. Var. de boucle */
12
while(i<n){
fact *=i ;
i++ ;
}
printf("factorie (%d)=%d\n",n,fact) ;
}

Exercice 11.
n
Ecrire le programme permettant de calculer x .

#include "stdio.h"
main ()
{
int n,x ; /* ordre */
int i,puis ; /* indice de boucle et resultat */
printf("introduire x et n= ") ;
scanf("%d, %d ",&n,&x) ;
puis=1 ;
i =1 ; /*init. Var. de boucle */
while(i<=n){
puis *=x;
i++ ;
}
printf("%d eleve a la puissence %d=%d\n",x,n,puis) ;
}

Exercice 12.

Ecrire un programme qui affiche sous forme binaire le résultat d’un OU, d’un ET, ou
d’un OU EXCLUSIF entre deux entiers entrés au clavier, selon le choix de l’utilisateur.
Cet exercice utilise la fonction putch(char) d’affichage d’un caractère de la librairie
standard std.
Il donne aussi un exemple d’utilisation de l’opérateur sizeof()
Il convient d’afficher les bits dans le bon ordre !

’algorithme
Exemple d’

Entrer le choix de l’utilisateur (1,2 ,3) selon le choix, calculer l’opération logique
AND OR ou XOR afficher le résultat en binaire.

Corrigé
#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input
loop */

main(int argc, char *argv[]) {


int nb1,nb2 ; /*opérandes*/
13
int choix ; /*choix de l'utilisateur*/
int nombre ; /*résultat de l'opération logique */
int mem,i ; /* variables intermédiaire et de boucle */
/*choix de l'utilisateur */
printf("Entrer nb1, nb2 : ") ;
scanf("%d %d",&nb1,&nb2);

printf("votre choix(AND=1, OR=2, XOR=3) : ") ;


scanf("%d",&choix);
/*opération logique*/
if(choix==1)
nombre =nb1&nb2 ;

else if (choix==2)
nombre =nb1|nb2 ;
else
nombre =nb1^nb2 ;
/* affichage binaire */
i=0 ;
while(i<8*sizeof(int)) {
mem=nombre<<1 ;
mem>>=1 ;
putch(nombre==mem ? '0' :'1') ;
nombre<<=1 ;
i++ ;
}

Opérateurs bit à bit

Exercice 13.

Écrire une fonction qui renvoie le premier nombre pair qui est inférieur à un
nombre impair passé en paramètre, si on envoie un nombre pair à la fonction, elle
doit renvoyer ce nombre pair en utilisant les opérateurs bit à bit.

Corrigé :

#include <stdio.h>
unsigned long pair_o_matic(unsigned long nombre) {
return (nombre | 1) ^ 1;}
main()
{ int n ;
printf ("donnez un un nombre : ") ;
scanf("%d", &n);
printf("le nombre paire %d est %d",n,pair_o_matic(n));
}

14
nombre | 1 remplace le dernier bit du nombre par un 1, ce qui rend le nombre impair,
ensuite le ^ 1 remplace le dernier bit par un 0 ce qui le rend pair.

Exercice 14.

Ecrire une fonction qui renvoie le xième bit d'un nombre en partant de la droite (la
position du bit à récupérer étant passée en paramètre).

Corrigé :

Solution 1

#include <stdio.h>
unsigned int recupererBit(unsigned int position, unsigned long nombre)
{
return ((1 << position) & nombre) >> position;
}

main()
{ int n,p ;
printf ("donnez un un nombre : ") ;
scanf("%d\n%d", &p,&n);
printf("le nombre paire est %d",recupererBit(p,n));
}

Solution 2 :

#include <stdio.h>
unsigned int recupererBit(unsigned int position, unsigned long nombre)
{
unsigned int i = 0;
unsigned int puissanceDeDeux = 1;
for (i = 0; i < position; i++)
{
puissanceDeDeux = puissanceDeDeux << 1;
}
return (nombre & puissanceDeDeux) >> i;
}

main()
{ int n,p ;
printf ("donnez un un nombre : ") ;
scanf("%d\n%d", &p,&n);
printf("le nombre paire est %d",recupererBit(p,n));
}

15
Tableaux

Exercice 15.
Ecrire une fonction calculant la moyenne des éléments d’un tableau de réels.
Ecrire la fonction de recherche du maximum dans un tableau de réels.

Corrogé :

La moyenne :
#include <stdio.h>
#include <stdlib.h>

float moyenne (float tab[],int dim)


{
int i ;
float moy =0 ;
for(i=0 ;i<dim ;i++)
moy+=tab[i] ;
return moy/dim ;
}

main(int argc, char *argv[]) {


float t[5]={1,2,3,4,5};
printf("la moyenne est %f:", moyenne(t,5));
}

Le maximum
#include <stdio.h>
#include <stdlib.h>

/* run this program using the console pauser or add your own getch, system("pause") or input
loop */
float maximum (float tab[],int dim)
{

int i ;
float max =0 ;
for(i=0 ;i<dim ;i++)
max< tab[i] ?max=tab[i] :1 ;
return max ;
}
main(int argc, char *argv[]) {
float t[5]={1,2,3,4,5};
printf("la moyenne est %f:", maximum(t,5));
}

16
Exercice 16.

Ecrire un programme qui permet de remplir un tableau de 10 entiers et de remplacer toute


occurrence d’un entier saisi x par 0.

Corrigé :
#include<stdio.h>
main()
{
int tab[10], i, x;
// Remplissage du tableau
for(i = 0; i < 10 ; i ++)
{
printf(" Saisir lelement Numero:\n %d", i);
scanf("%d",&tab[i]);
}
printf(" Saisir un entier : \n");
scanf("%d",&tab[i]);
// Modification du tableau
for(i = 0; i < 10 ; i ++)
{
if(tab[i] == x) tab[i] = 0;
}
// Affichage du tableau
for(i = 0; i < 10 ; i ++)
{
printf(" %d ", tab[i]);
}
}

Exercice 17.

Ecrire une fonction calculant le produit scalaire de deux vecteurs.

float produit (float vec1 [], float vec2[], int dim)


{
int i ;
float prod =0 ;
for(i=0 ;i<dim ;i++)
prod=prod+vec1[i]*vec2[i] ;
return prod ;
}

Exercice 18.

Ecrire un programme qui calcul le produit scalaire de deux vecteurs d’entiers U et V de même
dimension.

Corrigé :

#include <stdio.h>

17
#include <stdlib.h>
#define MAX 5
long ProduitScalaire(int *,int *, int) ;
int main(int argc, char *argv[]) {
/* Déclarations */
int U[MAX]={1,2,3,4,5}, V[MAX]={1,2,3,4,5}; /* tableaux donnés */
int N; /* dimension */
int I; /* indice courant */
long PS; /* produit scalaire */
PS = ProduitScalaire(U,V,MAX) ;
/* Edition du résultat */
printf("Produit scalaire : %ld\n", PS);
}

long ProduitScalaire(int *U, int *V,int N)


{
int i ;
int prod ;
for(i=0 ;i<N;i++ ) prod=prod+U[i]*V[i];
return prod ;
}

Chaîne de caractères

Exercice 19.

Ecrire la fonction LONG_CH qui retourne la longueur d'une chaîne de caractères CH comme
résultat. Implémentez LONG_CH sans utiliser de variable d'aide numérique.

Corrigé :
#include <stdio.h>
int LONG_CH(char *CH)
{
char *P;
for (P=CH ; *P; P++) ;
return P-CH;
}
main()
{ char *p="le cout" ;
printf("le nombre de caracters est %d",LONG_CH(p));
}
Exercice 20.

Ecrire un programme qui demande à l'utilisateur de lui fournir un nombre entier entre 1 et 7 et
qui affiche le nom du jour de la semaine ayant le numéro indiqué (lundi pour 1, mardi pour 2,
... dimanche pour 7).

Corrigé :

18
Une démarche consiste à créer un "tableau de 7 pointeurs sur des chaines", correspondant
chacune au nom d'un jour de la se m aine. Comme ces chaines sont ici constantes, il est
possible de créer un tel tableau par une déclaration comportant une initialisation de la forme:

char * jour [7] = { "lundi", "mardi", ...

N'oubliez pas alors que jour[0] contiendra l'adresse de la première chaîne, c'es t-à-dire
l'adresse de la chaîne constante "lundi" ; jour[1] contiendra l'adresse de "mardi", ...
Pour afficher la valeur de la chaîne de rang i, il suffit de remarquer que son adresse est
simplement jour [i-1]. D'où le program m e de mandé :

#include <stdio.h>
#include <stdlib.h>
main()
{
char * jour [7] = { "lundi", "mardi", "mercredi", "jeudi",
"vendredi", "samedi", "dimanche"
};
int i ;
do
{ printf ("donnez un nombre entier entre 1 et 7 :\n ") ; scanf ("%d", &i) ;
}while ( i<=0 || i>7) ;
printf ("le jour numéro %d de la semaine est %s\n", i, jour[i-1]) ;
}

Exercice 21.

Ecrire un programme déterminant le nombre de lettre e (minuscule) contenues dans un texte


fourni en donnée sous forme d'une seule ligne ne dépassant pas 128 caractères. On cherchera,
ici, à n'utiliser aucune des fonctions de traitement de chaîne.

Corrigé

Compte tenu des contraintes imposées par l'énoncé, nous ne pouvons pas faire appel à la
fonction strlen. Pour "explorer" notre chanîe, nous utiliserons le fait qu'elle est terminée par
un caractère nul(\0].
D' où le programme proposé:
#define LG_LIG 128
#include <stdio.h>

main()
{
char ligne [LG_LIG+1] ; /* pour lire une ligne au clavier +1 pour \0 */
int i ; /* pour explorer les différents caractères de ligne */
int ne ; /* pour compter le nombre de 'e' */
printf ("donnez un texte de moins d'une ligne : \n") ; gets (ligne) ;

ne = 0 ; i = 0 ;
while (ligne[i]) if (ligne[i++] == 'e') ne++ ;
printf ("votre texte comporte %d lettres e", ne) ;
19
}

Exercice 22.

Écrire un programme qui supprime toutes les lettres « e » (minuscules) d’un texte de moins
d’une ligne (supposée ne pas dépasser 132 caractères) fourni au clavier. Le texte ainsi modifié
sera créé, en mémoire, à la place de l’ancien.

Corrigé :
#include <stdio.h>
#include <string.h>
#define CAR 'e'
#define LGMAX 132
main()
{ char texte[LGMAX+1] ;
char * adr ;
printf ("donnez un texte terminé par return\n") ;
gets (texte) ;
adr = texte ;
while ( adr=strchr(adr,CAR) ) strcpy (adr, adr+1) ;
printf ("voici votre texte privé des caractères %c\n", CAR) ;
puts (texte) ;
}
Exercice 23.

Écrire un programme qui lit au clavier un mot (d’au plus 30 caractères) et qui l’affiche à
l’envers.

Corrigé :

#include <stdio.h>
#include <string.h>
#define NBCAR 30
main()
{ char nom[NBCAR+1] ;
int i ;
printf ("donnez un nom d’au plus %d caractères : ", NBCAR) ;
gets(nom) ;
for ( i=strlen(nom) ; i>=0 ; i--)
putchar (nom[i]) ;
}

Fonctions

Exercice 24.

Ecrire une fonction qui reçoit en arguments 2 nombres flottants et un caractère et qui fournit un
résultat correspondant à l'une des 4 opérations appliquées à ses deux premiers arguments, en fonction
de la valeur du dernier, à savoir: addition pour le caractère +, soustraction pour -, multiplication pour

20
* et division pour / (tout autre caractère que l'un des 4 cités se ra interprété comme une addition). On
tiendra compte des risques de division par zéro.
Ecrire un petit program me (main) utilisant cette fonction pour effectuer les 4 opérations sur deux
nombres fournis

Corrigé :

#include <stdio.h>
#include <stdlib.h>
float oper (float v1, float v2, char op)
{ float res ; switch (op)
{ case '+' : res = v1 + v2 ;
break ;
case '-' : res = v1 - v2 ;
break ;
case '*' : res = v1 * v2 ;
break ;
case '/' : res = v1 / v2 ;
break ;
default : res = v1 + v2 ;
}
return res ;
}
main()
{
float oper (float, float, char) ;
/* prototype de oper */
float x, y ;
printf ("donnez deux nombres reels : ") ;
scanf ("%e %e", &x, &y) ;
printf ("leur somme est : %e\n", oper (x, y, '+') ) ;
printf ("leur différence est : %e\n", oper (x, y, '-') ) ;
printf ("leur produit est : %e\n", oper (x, y, '*') ) ;
if ( y!=0) printf ("leur quotient est : %e\n", oper (x, y, '/')) ;

Exercice 25.

Exécuter le programme suivant et construire les grilles correspondantes. Implémenter le


programme ensuite en C.

programme PARAMETRES
| entier A,B
| en A ranger 0
| en B ranger 0
| P(A,B)
| écrire A,B
fprogramme (* fin PARAMETRES *)
procédure P(X,Y)
| donnée: entier X
| résultat: entier Y
| en X ranger X+1
| en Y ranger Y+1
| écrire X,Y

21
fprocédure (* fin P *)

Corrigé :
#include <stdio.h>
main()
{
void P(int X, int *Y); /* Prototype de la fonction appelée */
int A,B;
A=0;
B=0;
P(A, &B);
printf("%d %d \n", A, B);
return 0;
}
void P(int X, int *Y)
{
X = X+1;
*Y = *Y+1;
printf("%d %d \n", X, *Y);
}

Exercice 26.

Ecrire une fonction qui permet de convertir un caractère minuscule (s’il l’est) en majuscule.
Utiliser cette fonction pour convertir un texte en majuscule.

Corrigé :
#include "stdio.h"
int est_miniscule(char c)
{
return(c >= 'a' && c<= 'z') ;
}
char min_maj(char c)
{
return('A'-'a'+ c);
}
main( )
{
char c ;
while((c=getchar()) !='#')
{
if (est_miniscule(c))
c=min_maj(c);
putchar(c) ;
}
}

Pointeurs

Exercice 27.

22
Expliquer les différences entre (*p)++,*p++,*(p++)

Corrigé :
(*p)++ : le contenu de l’adresse sur laquelle pointe p est incrémenté.
*p++ : équivalent au précédent car * est prioritaire par rapport à l’opérateur ++
*(p++) : c’est la valeur de l’adresse qui est incrémentée (p +sizeof(type)).

Exercice 28.

Ecrire une fonction d’échange de valeurs de deux variables réelles données en argument.

Corrigé :

void echange(double *var1,double *var2)


{ double tmp ;

tmp=*var1 ;
*var1=*var2 ;
*var2=tmp ;
}

Exercice 29.

Inverser un tableau de réels en utilisant les pointeurs. On n’utilisera pas la notation pointeur
pour passer l’adresse du tableau en argument de la fonction.

Corrigé :

void inverse (double tab[], int n)


{
double tmp ;
int i ;
for(i=0 ;i<n/2 ;i++){
tmp=*(tab+i) ;
*(tab+i)=*(tab+n-i) ;
*(tab+n-i) =tmp;
}
}

Exercice 30.

Reprendre la question précédente en utilisant cette fois la notation pointeur pour passer
l’adresse du tableau en argument.

Corrigé :

void inverse (double *tab, int n)


{
double tmp ;

23
int i ;
for(i=0 ;i<n/2 ;i++){
tmp=*(tab+i) ;
*(tab+i)=*(tab+n-i) ;
*(tab+n-i) =tmp;
}
}

Exercice 31.

Ecrire une fonction de saisie des éléments d un tableau de réels. Le nombre d éléments du
tableau sera donne en argument de la fonction qui retournera l’adresse du tableau. Ce
tableau devra être alloué dynamiquement. Une gestion des erreurs permettra de renvoyer le
pointeur NULL en cas d’erreur d’allocation mémoire.

Corrigé :

double *tab_nouv (int n)


{
double *t ;

t=(double *) malloc (n*sizeof(double) );

if (t !=NULL)
for(i=0 ;i<n ;i++){
printf("tapez la valeur N. %d du tableau :",i) ;
scanf("%lf",t+i) ;
printf(" /n") ;
}
return t ;
}

Exercice 32.
Ecrire la fonction qui affiche puis libère la mémoire d’un tableau alloue dynamiquement
comme dans l’exercice précédent.

Corrigé :

double *tab_term (double *t , int n)


for(i=0 ;i<n ;i++){
printf("tableau[ %d]=%lf",i,*(t+i)) ;
free(t) ;
}

Exercice 33.

Ecrire une fonction qui fournit en valeur de retour la somme des éléments d'un tableau de
flottants transmis, ainsi que sa dimension, en argument.
Ecrire un petit programme d'essai.

24
Corrigé :

En ce qui concerne le table au de flottants reçu en argument, il ne peut être transis que par
adresse. Quant au nombre d'élément (de type int), nous le transmettrons classiquement par
valeur. L'en-tête de notre fonction pourra se présente r sous l'une des formes suivantes :

float somme (float t[], int n)


float somme (float * t, int n)
float somme (float t[5], int n) /* déconseillé car laisse croire que t */
/* est de dimension fixe 5 */

En effet, la dimension réelle de t n'a aucune incidence sur les instructions de la fonction elle -
même (elle n'intervient pas dans le calcul de l'adresse d 'un élément du table au 2 e t elle ne
sert pas à "allouer" un emplacement puisque le table au e n question aura é té alloué dans la
fonction appelant somme ).
Voici ce que pourrait être la fonction de mandée :

float somme (float t[], int n) /* on pourrait écrire somme (float * t, ... */
/* ou encore somme (float t[4], ... */
/* mais pas somme (float t[n], ... */
{ int i ;
float s = 0 ;
for (i=0 ; i<n ; i++)
s += t[i] ; /* on pourrait écrire s += * (t+i) ; */ return s ;
}

Pour ce qui es t du program m e d’utilisation de la fonction somme, on peut, là encore,


écrire le "prototype " sous différentes formes :

float somme (float [], int ) ; float somme (float * , int ) ;


float somme (float [5], int ) ; /* déconseillé car laisse croire que t */
/* est de dimension fixe 5 */

Voici un e xe m ple d' un te lprogram m e :

#include <stdio.h> main()

{
float somme (float *, int) ; float t[4] = {3, 2.5, 5.1, 3.5} ;
printf ("somme de t : %f\n", somme (t, 4) ) ;
}

Structures

Exercice 34.
Définir un type structuré permettant de représenter un étudiant comportant son nom, et son
prénom et sa date de naissance. Le mois sera une chaîne de caractères telle que « janvier », «
février », etc.

25
Corrigé

typedef struct date {


int jour; /* entre 1 et 31 */
char mois[20]; /* nom du mois "janvier", "fevrier", ... */
int annee; /* 1999, 2000, ... */
} date;
typedef struct {
char nom[32];
char prenom[32];
date date_naissance; } etudiant;

Exercice 35.
Écrire un programme qui :
1- lit au clavier des informations dans un tableau de structures du type point défini
comme suit :
struct point { int num ;
float x ;
float y ;
}

Le nombre d’éléments du tableau (courbe) sera fixé par une instruction #define.
2- affiche à l’écran l’ensemble des informations précédentes.
3- Réaliser la même chose que dans l’exercice précédent, mais en prévoyant, cette fois,
une fonction pour la lecture des informations et une fonction pour l’affichage.

Corrigé :

struct point { int num ;


float x ;
float y ;
}
void affiche (struct point []) ; /* ou void lit (struct point *) */
main()
{
struct point courbe[NPOINTS] ;
lit (courbe) ;
affiche (courbe) ;
}
void lit (struct point courbe []) /* ou void lit (struct point * courbe) */
{
int i ;
for (i=0 ; i<NPOINTS ; i++)
{ printf ("numéro : ") ; scanf ("%d", &courbe[i].num) ;
printf ("x : ") ; scanf ("%f", &courbe[i].x) ;
printf ("y : ") ; scanf ("%f", &courbe[i].y) ;
}
}

26
void affiche (struct point courbe []) /* ou void affiche (struct point * courbe) */
{
int i ;
printf (" **** structure fournie ****\n") ;
for (i=0 ; i<NPOINTS ; i++)
printf ("%d %f %f\n", courbe[i].num, courbe[i].x, courbe[i].y) ;
}

Exercice 36.
Déclarer deux variables pers1 et pers2 de type structure et que chaque personne dispose de
quatre informations :
- nom : tableau de caractère de dimension 20
- numer_tel : tableau de caractère de dimension 10
Corrigé :

Solution 1

Si nous déclarons La structure suivante:

struct personne
{
char[20] nom;
char[11] tel;
} ;
Pour déclarer des variables de type struct personne, nous somme obliger à chaque déclaration
répéter struct personne,

struct personne pers1, pers2 ;


Ce qui très lourd.

Solution 2

typedef struct {

char[20] nom;
char[11] tel;

} Personne ; /* personne est le nom du type */

Nous pouvant déclarer des variables de type struct personne, de la manière suivante :

Personne pers1, pers2 ;

Exercice 37.
Nous souhaitons mettre en ouvre un répertoire téléphonique (contenant les noms et numéros
de téléphones de personnes).

1. définir un type de structure PERS qui contient deux champs : le nom d'une personne et son
numéro de téléphone

27
2. écrire une fonction saisir_personne qui permet de saisir une personne (une structure de
type PERS)
3. écrire une fonction saisir_repertoire qui permet de saisir un tableau de personnes
4. écrire une fonction afficher_repertoire qui permet d'afficher le contenu du répertoire
5. écrire une fonction chercher_personne qui permet de chercher un numéro d'une personne
donnée dans le répertoire
6. écrire une fonction main qui saisit un répertoire téléphonique et propose le dialogue
suivant :
 1- afficher le contenu du répertoire
 2- chercher le numéro de téléphone d'une personne
 3- quitter le Programme

Corrigé

#include
#include

struct personne
{
char nom[20]; /* Le nom de la personne */
char numero[11]; /* le numero de telephone */
};

typedef struct personne PERS;

void saisir_personne(PERS *pp);


void saisir_repertoire(PERS rep[], int nb);
void afficher_repertoire(PERS rep[], int nb);
char *chercher_personne(PERS rep[], int nb, char *nom);

int main()
{
PERS monRep[5];
int choix;
char nom[20], *pnum;
saisir_repertoire(monRep, 5);
do
{
do
{
printf("\nMenu:\n");
printf("1-afficher le contenu du répertoire\n");
printf("2-chercher le numéro d'une personne\n");
printf("3-quitter le programme\n");
printf("Votre choix : ");
scanf("%d", &choix);
}
while (choix < 1 || choix > 3);
switch (choix)
{
28
case 1 : afficher_repertoire(monRep, 5);
break;
case 2 : printf("nom a rechercher : ");
scanf("%s", nom);
pnum = chercher_personne(monRep, 5, nom);
if (pnum == NULL)
{
printf(" Personne inexistante\n");
}
else
{
printf("--> Numero de %s: %s\n", nom, pnum);
}
break;
default : break;
}
}
while (choix != 3);
return 0;
}

void saisir_personne(PERS *pp)


{
printf("Nom : "); scanf("%s", pp->nom);
printf("Numero : "); scanf("%s", pp->numero);
}

void saisir_repertoire(PERS rep[], int nb)


{
int i;
printf("Saisie du repertoire de %d personnes :\n", nb);
for (i=0; i<nb; i++)
{
saisir_personne(&rep[i]);
}
}

void afficher_repertoire(PERS rep[], int nb)


{
int i;
printf("Affichage du repertoire\n");
printf("%20s ...... Numero\n", "Nom");
for (i=0; i<nb; i++)
{
printf("%20s ...... %s\n", rep[i].nom, rep[i].numero);
}
}

char *chercher_personne(PERS rep[], int nb, char *nom)


{
int i;
29
for (i=0; i<nb; i++)
{
if (strcmp(nom, rep[i].nom) == 0)
{
return rep[i].numero;
}
}
return NULL;
}

30

Vous aimerez peut-être aussi