IUP2 : TP informatique 2

les fonctions et leurs arguments, les pointeurs

Question 1 : comprendre le passage d'arguments

Créer une fonction qui affiche un flottant (on n'a qu'à lui transmettre une valeur) et une fonction qui saisit un flottant (ici la fonction doit modifier la valeur : soit elle retourne la nouvelle valeur (saisie1), soit on utilise un passage d'arguments par adresse (saisie2)
/* proposé par Stoos */
/*On définit des fonctions qui affichent et saisissent des nombres*/

#include<stdio.h>

float affiche(float a)
 {
 printf("Le nombre est:%f\n",a);
 return(a);
 }

float saisie1(void)   /*Le void est mis car on ne peut pas déclarer
                        avec rien dans les () */
 {
 float a;
 puts("Entrer un nombre:");
 scanf("%f",&a);
 return(a);
 }

float saisie2(float *a)    /*utilisation de pointeur*/
 {
 puts("Entrez nbre:");
 scanf("%f",a); /*équivalent à scanf("%f",&(*a)); car le & et le * s'annulent.*/
 return(*a);
 }

void main(void)
 {
 float x2,x1;
 saisie2(&x1);
 x2=saisie1();
 affiche(x1);
 affiche(x2);
 }

Question 2 : gestion des pointeurs

En utilisant saisie1 et saisie2 de la question précédente :
  1. créer un pointeur p1 pointant sur la variable x1, et un pointeur p2 pointant sur x2.
  2. saisir x1 et x2 (saisie1 pour x1, saisie2 pour x2) mais sans utiliser x1 et x2, en utilisant par contre p1 et p2
  3. vérifier (en les affichant) si x1 et x2 sont bien modifiés comme prévu
  4. affecter à z1 et z2 la somme et le produit de x1 et x2 (toujours avec les pointeurs).
  5. pour ceux qui vont plus vite, créer pp qui est un pointeur qui pointe sur p1 et s'en servir
/* proposé par Stoos */
#include<stdio.h>

float affiche(float a)
 {
 printf("Le nombre est:%f\n",a);
 return(a);
 }

float saisie1(void)                    /*On reprend les fonctions*/
 {                                     /*  du programme "fct01.c"*/
 float a;
 puts("Entrer un nombre:");
 scanf("%f",&a);
 return(a);
 }

void saisie2(float *a)    
 {
 puts("entrez nbr:");
 scanf("%f",a);
 }

void main(void)
 {
 float x1,x2,z1,z2;
 float *p1,*p2;
 p1=&x1;
 p2=&x2;
 *p1=saisie1();
 saisie2(p2);
 affiche(x1);
 affiche(x2);
 z1=*p1+*p2;
 z2=(*p1)*(*p2); /*Utiliser les () pour y voir clair*/
 affiche(z1);
 affiche(z2);
 }

récursivité

  1. que fait la fonction somme ?
  2. à partir de la fonction somme, définir une fonction somme1 plus simple (non récursive mais itérative)
  3. calculer la fonction factorielle (récursive) et factoriel1(itérative)
#include<stdio.h>

int somme(int n);
int somme1(int n);
int factoriel(int n);
int factoriel1(int n);

void main(void)
 {
 int i;
 puts("entrez i");
 scanf("%d",&i);
 printf("%d\n",factoriel1(i));
 }

int somme(int n)
 {
 if(n>0)return(somme(n-1)+n);
 return(0);
 }
                               /*Ou*/
int somme1(int n)       /* int somme1(int n)    */
 {                      /*  {                   */
 int s=n;               /*  int s=0;            */
 do                     /*  for(;n>0;n--) s+=n; */
  {                     /*  return(s);          */
  s=s+(n-1);            /*  }                   */
  n--;
    }
 while(n>0);
 return(s);
 }
 /* somme&somme1 calculent i=n + la somme des (n-1) tant que n>0 */

int factoriel(int n)
 {
 if(n>0)return(factoriel(n-1)*n);
 return(1);
 }
                                          /*Ou*/
int factoriel1(int n)           /* int factoriel1(int n) */
 {                              /*  {                    */
 int s=n;                       /*  int s=1;             */
 do                             /*  for(;n>0;n--) s*=n;  */
  {                             /*  return(s);           */
  s=s*(n-1);                    /*  }                    */
  n--;
  }
 while(n>1);
 return(s);
 }
 /*factoriel et factoriel1 calculent la factorielle de n*/

Question 4 : passage en flottants

On ne sait pas dépasser factorielle 7 !! c'est peu : essayez de faire mieux.
En fait les factorielles sont souvent utilisées dans les calculs de probabilités, où seul l'ordre de grandeur compte, le 7ème chiffre après la virgule est sans intérêt Puis calculer C(i,j)=j!/(i!(j-i)!), prévoir une saisie de i,j, me dire combien j'ai de possibilités différentes de tirer 8 cartes parmi 32, calculer le nombre de possibilités de choisir 6 chiffres parmi les 49 du loto...
/* Fonction factoriel et factoriel1 pour avoir une réponse en réels.*/

#include<stdio.h>
float factoriel(int n);

void main(void)
 {
 int i;
 puts("entrez i");
 scanf("%d",&i);
 printf("%f\n",factoriel(i));
 }


float factoriel(int n)
 {
 if(n>1)return(factoriel(n-10)*n);
 return(1);
 }

float factoriel1(int n)           /*  float facteur1(int n) */
 {                                /*  {                     */
 float s=n;                       /*  float s=1;            */
 do                               /*  for(;n>0;n--) s*=n;   */
  {                               /*  return(s);            */
  s=s*(n-1);              
  n--;
  }
 while(n>1);
 return(s);
 }
 

récursivité et dichotomie

La racine de (3x)/4 - 2 est 8/3=2.666, donc entre 2 et 3.
Rechercher cette racine à 10-3 près, par dichotomie, en utilisant une fonction récursive (au TP1 on avait utilisé une méthode itérative).

float f(float x)
 {return(0.75*x -2);}
float divise_intervale(float *deb, float*fin)
{
 float milieu;
 milieu=(deb+fin)/2;
 if((fin-deb)<1E-3)return(milieu);
 else if(f(*deb)*f(milieu)<=0)return(divise_intervale(deb,milieu));
 else return(divise_intervale(milieu,fin));
}
void main(void)
{printf(divise_intervalle(2,3));}


Patrick TRAU,ULP - IPST 20/11/97