IUP2 : TP informatique 2002/2003

table des matières - accès direct au TP

TP1 : découverte

A) l'environnement : Linux - mot de passe - commandes du shell (pwd ls rm cp cd mkdir) - chemin d'accès à un fichier (relatif, absolu, URL)- kde et le gestionnaire de fichiers - test ftp

B) Premier programme : Pour le créer, il faut trois phases :

C) l'ordinateur n'a d'intérêt que si l'on répète des instructions. Donc les boucles : for et do-while.

  do
    {
       instructions;
    }
  while (condition);  
  for(i=0;i<16;i++)
    {
       instructions;
    }  

précision : regardez bien où sont les point-virgules et les accolades.

solution :

#include 
int main(void)
 {
  int nb,i=0,base=2; //ou 10
  float res,mult=1;
  printf("combien de calculs ?");
  scanf("%d",&nb);
  for(i=0;i<nb;i++)
   {
    res=base*mult;
    printf("%d" puissance %d = %f\n",base,i+1,res);
    mult=res;
   }
 }

D) Modifiez le programme qui affiche les puissances de N successives (N entier, demandé à l'utilisateur), jusqu'à un nombre maxi donné (compris) également demandé à l'utilisateur. (solution : remplacer la boucle for par une while)

E) Faites un programme qui demande une valeur initiale vi, un pas p et un nombre nb, qui ajoute nb fois p à vi et affiche le résultat. Essayez par exemple vi=0, p=0.01 et nb 100, 10 000; 1 000 000, 100 000 000 (ne dépassez pas 109), conclusions sur le temps de calcul et la validité du résultat, tests pour d'autres vi (1000, 10 000,...) puis d'autres p.

#include<stdio.h>
int main(void)
{
 float somme,vrai,debut=1000,pas=0.001;
 int i,nb=10000;
 somme=debut;
 for(i=0;i<nb;i++) somme+=pas;
 vrai=debut+(pas*nb);
 printf("on trouve %f (au lieu de %f)\n",somme, vrai);
}

En conclusion : les entiers peuvent atteindre un peu plus que 109, mais le compilateur ne prévient pas en cas de dépassement de capacité. Pour les flottants, on peut monter jusque vers 1038, mais :

N'oubliez pas de vous déloger de votre machine avant de quitter. Il ne faut JAMAIS éteindre un PC en mode graphique, dans cette salle laissez le allumé.

TP2 : tests et boucles

A) résolution de ax2 + bx + c dans TOUS les cas

#include <stdio.h>
#include <math.h> /* pour sqrt, la racine carrée */
int main (void)
{
 float a,b,c;
 float delta,r1,r2;
 printf("résolution de ax2 + bx + c \n");
 printf("entrez la valeur de a : ");
 scanf("%f",&a);
 printf("entrez la valeur de b : ");
 scanf("%f",&b);
 printf("entrez la valeur de c : ");
 scanf("%f",&c);
 if (a==0) /* sinon diviser par 2*a risque de poser problème */
  {
   if (b!=0) printf("une racine simple x=%f\n",-c/b);
   else if (c==0) printf("il y a une infinité de solutions à Ox=0\n");
   else printf("aucune solution à l'équation %f=0\n",c);
  }
 else
  {
   delta=b*b-4*a*c; /* b*b : c'est comme cela qu'on calcule un carré */
   if (delta==0) printf("une racine double : %f\n",-b/(2*a));
   else if (delta<0) puts("aucune racine réelle (mais complexes)");
   else
    {
     r1=(-b-sqrt(delta))/(2*a);
     r2=(-b+sqrt(delta))/(2*a);
     printf("il y a 2 racines réelles : x1=%f et x2=%f\n",r1,r2);
    }
  }
}

pour la compilation, il faut inclure la librairie mathématique : gcc prog.c -o prog -lm
Rappel : à chaque fois que vous effectuez un division, il faut analyser le cas du dénominateur nul.

recherche d'une racine positive de ax3+bx2+cx+d=0

attention, ce n'est pas la bonne méthode, ce problème est uniquement posé pour vous faire travailler les boucles. On cherche d'abord à encadrer la première racine positive (f(x) change de signe) par pas de 1 (si on arrive à 10000) on abandonne. Puis dans un second temps on restreind l'encadrement de moitié jusqu'à ce qu'on ait une précision de 10-3 (dichotomie)

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

float f(float a,float b,float c,float d,float x)
{return( a*x*x*x+b*x*x+c*x+d);}

void main(void)
{
float a, b, c, d,x,yprec,gauche,droite,y;
printf("ax3+bx2+cx+d=0");
printf("\nEntrez la valeur de a ?");
scanf("%f",&a);
printf("\nEntrez la valeur de b ?");
scanf("%f",&b);
printf("\nEntrez la valeur de c ?");
scanf("%f",&c);
printf("\nEntrez la valeur de d ?");
scanf("%f",&d);

yprec=f(a,b,c,d,0);
for (x=1;((y=f(a,b,c,d,x))*yprec>0 && x<1000);x+=1) yprec=y;
if(x==1000)
   {puts ("pas de solution"); exit(0);}
printf("la solution est comprise entre %f et %f",x-1,x);
gauche=x-1;
droite=x;
do
 {
  x= (gauche+droite)/2;
  if (f(a,b,c,d,x)==0) gauche=droite=x;
  elseif ((f(a,b,c,d,gauche)*f(a,b,c,d,x))<0) droite=x;
  else gauche=x;
 }
while ((droite-gauche)>0.01) ;
printf("\nla solution est comprise entre %f et %f",gauche,droite);
}

jeu du plus ou moins

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main (void)
     {
        int nbatrouver,proposition,compteur=0;
        int min=1,max=100;
        printf("Vous devez deviner un nombre entre %d et %d \n",min,max);
        srand(time(NULL));
        nbatrouver=(rand()%(max+1))+min;
        do
             {
                compteur++;
                printf("entrez votre proposition :");
                scanf("%d",&proposition);
                if(proposition<nbatrouver) 
                  if(proposition>min)
                    {
                     puts("trop petit");
                     min=proposition;
                    }
                   else puts("donnée incohérente");
                else if(proposition!=nbatrouver) 
                  if(proposition<max)
                    {
                     puts("trop grand");
                     max=proposition;
                    }
                   else puts("donnée incohérente");
             }
        while (proposition!=nbatrouver);
        printf("gagné en %d essais \n",compteur);
        if (compteur<2)puts("tricheur !");
        else if (compteur<5)puts ("bravo");
        else if (compteur<10) puts("pas mal");
        else puts("espèce de gros nul");
     }

TP3 : les tableaux

Soient les déclarations :

#define DIM 100
typedef float tableau[DIM];

.... etc .....

 tableau t;
 int nb;
  1. demander le nombre de valeurs
    afficher les valeurs
    afficher le tableau
  2. calculer la moyenne
  3. boucle - menu
    nb=0;
    répéter
    	que voullez vous faire ?
    	1 -> saisir le tableau
    	2 -> l'afficher
    	3 -> moyenne
    	0 -> quitter le programme
    
  4. ajouter une note (derrière les autres)
  5. supprimer une note (demander sa position)
  6. ajouter une note à un endroit précis
  7. rotation (dans les deux sens)
  8. trier (optionnel)

Proposition de solution :

#include <stdio.h>
#define DIM 100
typedef float tableau[DIM];

int main (void)
{
 tableau t;
 int nb,i,j,choix,min;
 float somme,moy,rot;
 nb=0;
 do
  {
   printf("que voulez vous faire?\n\n1 : saisir\n2 : afficher\n");
   printf("3 : calcul moyenne\n4 : ajout valeur\n5 : supprimer valeur\n");
   printf("6 : rotation vers le bas\n7 : rotation vers le haut\n");
   printf("8 : Trier par ordre croissant\n0 : quitter\n-> ");
   scanf("%d",&choix);
   switch(choix)
    {
     case 1:
       do
         {
          printf("combien de valeurs (entre 1 et %d) ? ",DIM);
          scanf("%d",&nb);
         }
       while(nb<0 || nb>DIM);
       for(i=0;i<nb;i++)
         {
           printf("entrez valeur %d :",i);
           scanf("%f",t+i);
          }
       break;
     case 2:
       for(i=0;i<nb;i++)
          printf("valeur %d : %f\n",i,t[i]);
       break;
     case 3:
       somme=0;
       for(i=0;i<nb;i++)somme+=t[i];
       moy=somme/nb;
       printf("moyenne : %f\n",moy);
       break;
     case 4:
       if(nb>=DIM)printf("plus de place !\n");
       else
        {
         printf("Entrez la valeur à rajouter : ");
         scanf("%f",&t[nb]);
         nb++;
        }
       break;
     case 5:
       if(nb<=0)printf("déja vide !\n");
       else
        {
         printf("Quelle valeur voulez vous supprimer ?");
         scanf("%d",&j);
         if (j<nb && j>=0)
          {
           nb--;
           for(i=j;i<nb;i++)
                 t[i]=t[i+1];
          }
        }
       break;
     case 6:
       rot=t[0];
       for(i=0;i<nb;i++)
            t[i]=t[i+1];
       t[nb-1]=rot;
       break;
     case 7:
       rot=t[nb-1];
       for(i=nb;i>0;i--) /*il faut commencer par la fin ! */
            t[i]=t[i-1];
       t[0]=rot;
       break;
     case 8:
       for(i=0;i<nb-1;i++) /* on les classe tous sauf le dernier */
        {
         min=i;
         for(j=i+1;j<nb;j++) /* recherchons le plus petit */
           if(t[j]<t[min]) min=j;
         rot=t[i]; /* on les échange */
         t[i]=t[min];
         t[min]=rot;
        }
       break;
    }
  }
 while(choix);
}

TP4

solution :

     #include <stdio.h>
     #define DIM 100
     typedef float tableau[DIM];

     void saisie (tableau t,int *nb,int dim)
         {
            int i;
            do
              {
               printf("combien de valeurs (entre 1 et %d) ? ",dim);
               scanf("%d",&*nb);
              }
            while(*nb<0 || *nb>dim);
            for(i=0;i<*nb;i++)
              {
                printf("entrez valeur %d :",i);
                scanf("%f",t+i);
              }
         }

     void affichage (tableau t, int nb)
    	 {
    	    int i;
            for(i=0;i<nb;i++)
            printf("valeur %d : %f\n",i,t[i]);
         }

     float moyenne (tableau t, int nb)
     	{
     	    float somme;
     	    int i;
            somme=0;
            for(i=0;i<nb;i++)somme+=t[i];
            return(somme/nb);
        }

     void ajouter (tableau t, int *nb,int dim)
     	{
            if(*nb>=dim)printf("plus de place !\n");
            else
             {
              printf("Entrez la valeur à rajouter : ");
              scanf("%f",&t[*nb]);
              (*nb)++;
             }
        }

     void supprimer (tableau t, int *nb)
     	{
            int i,j;
            if(*nb<=0)printf("déja vide !\n");
            else
             {
              printf("Quelle valeur voulez vous supprimer ?");
              scanf("%d",&j);
              if (j<*nb && j>=0)
               {
                (*nb)--;
                for(i=j;i<*nb;i++)
                      t[i]=t[i+1];
               }
             }
     	}

     void rotbas (tableau t, int nb) 	
     	{     	
         int i,rot;
         rot=t[0];
         for(i=0;i<nb;i++)
               t[i]=t[i+1];
         t[nb-1]=rot;
     	}

     void rothaut (tableau t, int nb)
     	{
     	 int i,rot;
     	 rot=t[nb-1];
         for(i=nb;i>0;i--) /*il faut commencer par la fin ! */
               t[i]=t[i-1];
         t[0]=rot;
     	}

     void trier (tableau t, int nb)
     	{
     	 int i,j, min,rot;
     	 for(i=0;i<nb-1;i++) /* on les classe tous sauf le dernier */
             {
              min=i;
              for(j=i+1;j<nb;j++) /* recherchons le plus petit */
                if(t[j]<t[min]) min=j;
              rot=t[i]; /* on les échange */
              t[i]=t[min];
              t[min]=rot;
             }
         }
     void tri_recursif (tableau t, int nb)
	{
	 float pivot;
	 tableau p,g;
	 int i,nbp,nbg;
	 nbp=nbg=0;
	 pivot=t[0];
	 for(i=1;i<nb;i++)
	   if(t[i]>pivot) g[nbg++]=t[i];
	             else p[nbp++]=t[i];
         //affiche(p,nbp);
	 //affiche(g,nbg);
	 if(nbp>1)tri_recursif(p,nbp);
	 if(nbg>1)tri_recursif(g,nbg);
	 i=0;
	 for(i=0;i<nbp;i++) t[i]=p[i];
	 t[nbp]=pivot;
	 for(i=0;i<nbg;i++) t[i+nbp+1]=g[i];
	}
         	  		
     int main (void)
     {
      tableau tab;
      int nb,i,choix;
      nb=0;
      do
       {
        printf("que voulez vous faire?\n1 : saisir\n2 : afficher\n");
        printf("3 : calcul moyenne\n4 : ajout valeur\n5 : supprimer valeur\n");
        printf("6 : rotation vers le bas\n7 : rotation vers le haut\n");
        printf("8 : trier\n9 : tri récursif\n0 : quitter\n-> ");
        scanf("%d",&choix);
        switch(choix)
        	{
      case 1:  saisie(tab,&nb,DIM);break;
      case 2:  affichage(tab,nb);break;
      case 3:  printf("La moyenne vaut %f\n",moyenne(tab,nb));break;
      case 4:  ajouter(tab,&nb,DIM);break;
      case 5:  supprimer(tab,&nb);break;
      case 6:  rotbas(tab,nb);break;
      case 7:  rothaut(tab,nb);break;
      case 8:  trier(tab,nb);break;
      case 9:  tri_recursif(tab,nb);break;
        	}
       }
     while(choix);
     }

Patrick TRAU,ULP - IPST novembre 2002. Cliquez pour retourner vers le sommaire programmation.