IUP2 – TP programmation informatique n° 3

1) Etude de la récursivité. Soit la fonction

  int f(int n)
   {
    int p;

if(n<2) return 1; else { p=n*f(n-1); return p } }

testez son résultat pour quelques valeurs simples. Essayez de comprendre comment elle fonctionne. Vous pouvez insérer des printf pour mieux comprendre son déroulement.

2) Ecrire un programme demandant deux nombres flottants (par scanf), puis qui calcule leur somme et l'affiche. (le programme doit être très simple)

3) Améliorer le programme pour qu'il sache traiter les 4 opérations . On demandera le premier nombre, puis le signe opératoire que l'on stockera dans une variable de type char, puis on demandera le second nombre.

4) Ajout d'une boucle : on veut maintenant faire une suite d'opérations : par exemple on veut entrer 5 * 3 (le programme affiche 15) puis + 2 (le programme affiche 17), etc jusqu'à ce qu'on donne le signe opératoire = qui termine le programme.

5) fonction factorielle : on désire également pouvoir calculer des factorielles. Exemples : !5=, ou 3+!5= . Vous décomposerez bien évidement votre programme en plusieurs fonctions.

6) dernière proposition : vous pouvez tenter de rajouter des parenthèses, mais c'est plus compliqué. Si vous vous limitez à un seul niveau de parenthèses (pas d'imbrications) il suffit de prévoir une variable supplémentaire pour stocker le résultat intermédiaire.

proposition de solution

pour une version pdf voyez ici.

1) F calcule (récursivement) une factorielle.

f(1) ou tout nb <1 donnent 1. f(2) donne 2*f(1)=2. f(3) donne 3*f(2)=6. f(4) donne 4*f(3)=4*6=24.

2) version que tous doivent savoir faire (question 4)

#include 
int main(void)
 {
 float n2,res;
 char signe;
 printf("premier nombre ?");
 scanf("%f",&res);
 do
  {
  printf("signe opératoire ?");
  do signe=getchar(); while(signe<=' '));
  if(signe!='=')
   {
   printf("prochain nombre ?");
   scanf("%f",&n2);
   if(signe=='+')res=res+n2;
   else if(signe=='-')res=res-n2;
   else if(signe=='*')res=res*n2;
   else if(signe=='/')res=res/n2;
   else printf("signe non conforme\n"); 
   printf("résultat intermédiaire : %f\n",res);
  }
 }
 while(signe!='=');
 printf("le résultat vaut %f\n",res);
 }

3) version avec parenthèses et ! (question 6)

#include 
// on est obligé de prototyper au moins la fonction calculer
char lire_un_signe(void);
float lire_un_nb(void);
float calculer(void);
int fact(int);

int fact(int n)
   {
    int p;
    if(n<2) return 1;
    else
     {
      p=n*fact(n-1);
      return p;
     }
   }

char lire_un_signe(void)
 {
  //lit un signe, qui devrait être +, -, *, /, (, ) ou =
  char s;
  do s=getchar(); while (s<=' ');  //on élimine les espace et CR
  return(s);
 }

float lire_un_nb(void)
 {
 float n;
 int nb;
 char c;
 nb=scanf("%f",&n);
 if(nb==0) //on n'a pas pu lire, ne peut être que (, ! ou une erreur
  {
  c=lire_un_signe();
  if(c=='!') n=fact(lire_un_nb());
  else if(c!='(')printf("erreur dans vos parenthèses !!!\n");
  else n=calculer();    //on calcule jusqu'à la prochaine )
  }
 return(n);
}

float calculer(void)
{
 float res,n2;
 char signe;
 res=lire_un_nb();
 do
  {
  signe=lire_un_signe();
  if(signe=='+'||signe=='*'||signe=='-'||signe=='/')
   {
   n2=lire_un_nb();
   if(signe=='+')res+=n2;
   else if(signe=='-')res-=n2;
   else if(signe=='*')res*=n2;
   else if(signe=='/')res/=n2;
   }
  }
 while(signe!='='&&signe!=')');
 return(res);
}

int main(void)
 {
 float res;
 printf("entrez votre équation, terminée par = (sur une ou plusieurs lignes)\n");
 printf("vous pouvez utiliser des parenthèses (bien appairées) et des nombres signés\n");
 printf("!5 ou !(2+3) donnent factorielle(5), alors que !2+3 donnde factorielle(2)+3\n");
 printf("exemple : (2*(-1))+(-1*-3)*(1/(4*0.5))+1)  (doit donner 1.5)\n?");
 res=calculer();
 printf("le résultat vaut %f\n",res);
}


retour TP IUP2

(c) P. TRAU IPST - ULP