panne logiciel (bug), Masque binaire, Sapin, nombres premiers, suite de Fibonacci , nombre d'OR.
Prérequis
TP précédents
Utilisation Gcc, Gdb
Cours sur les boucles
Utilisation de la suite Monia
Cours sur les masques.
But
Coder en C
Réaliser des masques binaire
Suites mathématique avec l'aide du langage (C)
nombre d'or avec l'aide d'un langage (C)
Envoyer votre compte rendu sur ciela1@workboot.fr
Pour tous les tp de programmation en langage C il faut utiliser GDB vu en cours , qui permet de trouver les bugs de vos codes.
C'est un outil qui permet de bien comprendre ce qu'il se passe dans votre code:
ici il faut juste noter qu'il faudra l'utiliser et savoir l'utiliser pour les exercices suivant.
Nous allons découvrir les boucles.
donner les pseudos codes des différents programmes , un .algo de chaque programme. (Pseudo langage avec Monia)
un répertoire pour chaque programme.
projet panne / panne.c / panne.xmo / panne.pl
(répertoire panne et fichier source panne.c et travaux avec monia)
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int compteur =0;
do
printf("%d \n",compteur);
while(compteur<=10);
return EXIT_SUCCESS;
}
Ce code , ne fonctionne pas comme il faut !!
Pour en sortir il faut appuyer sur les touches ctrl et c (^c) (envoi un signal au prg pour l’arrêter)
A l'aide du débogueur trouver ce qui manque dans ce code pour pouvoir en sortir?
Expliquer votre démarche avec gdb.
Pour ce tp il faut maîtriser les bases hexadécimale et binaire et décimale
qui se dit décalage à gauche de , il existe un décalage à droite de >>
LSB : least significant bit , bit de poids faible
MSB: most significant bit , bit de poids fort
0x17 << 1 => 0001 0111 (décalage a gauche de l'octet 0x17
projet : dec_gauche / dec_gauche.c
faire afficher en décimal et en hexadécimal , donnez les résultats ?
/* dans un répertoire dec_gauche dans TP2C */
#include <stdio.h>
#include <stdlib.h>
int main(int argc , char **argv)
{
printf ("1<<10 = %d en décimal et en hexa %x \n", 1<<10 ,1<<10 );
return EXIT_SUCCESS;
}
projet: dec_droite / dec_droite.c
Expliquer ..
vous avez compris ? donc on peut continuer
/* dans un répertoire dec_droite dans TP2C */
#include <stdio.h>
#include <stdlib.h>
int main(int argc , char **argv)
{
printf ("16>>2 = %d et en hexa : %x \n", 16>>2, 16>>2);
return EXIT_SUCCESS;
}
la lampe X est allumée si a et b sont activés.
a b c d e f g h i
& 1 0 1 0 0 0 0 0 0
= a 0 c 0 0 0 0 0 0
on voit que la fonction ET (&) bit a bit
filtre les bits a et c avec ce masque
le masque est 10100000 ou 0xA0
projet binaire (répertoire binaire)
binaire.xmo (avec monia)
binaire.pl (avec monia)
code source : binaire.c
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
long int masque=0x0001; /* 0000 0000 0000 0001 en binaire */
int valeur;
int compteur;
if (argc==2)
{
valeur=atoi(argv[1]);
for (compteur=0; compteur < 16 ; compteur ++)
{
if (valeur & (masque<<compteur))
printf ("1");
else
printf ("0");
}
printf("\n");
}
else {
printf ("Donnez moi une valeur\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Exemple d'utilisation :
./binaire 255
1111111100000000
sachant que 255 c'est : 0000000011111111
(donc a l'envers pour ceux qui ne l'ont pas vu !)
Analyse avec Monia de ce code. (installer pour le faire ! )
Faire le pseudo code de binaire.c , binaire.algo ou binaire.pl (avec Monia) pl qui veut dire pseudo langage .
ici c'est donné en exemple , et il faudra savoir faire pour les exercices suivants.
l'algorigramme (organigramme) et Pseudo langage (Pl)
# ----------------------------------------------------------------------------
# Nom : binaire.pl
# Sujet : valeur est la valeur a convertir en binaire , ici c'est un passage de paramètre en C
# Version : 0.1
#
# Auteur : BOGT
# Création : 29/11/2022
# Mise à jour : 29/11/2022
# ----------------------------------------------------------------------------
# source généré par MoniaOrg version 0.38
Programme nom_du_programme ;
##FORWARDCOMMENT##
VAR masque : entier long = 1 ; # masque pour selectionner un bit
valeur : entier = valeur passée au pg ; # valeur a convertir
compteur : entier = 0 ; # position du bit à tst
DEBUTPROG
masque=1 ;
valeur argument passé ;
compteur=0 ;
REPETER
SI ( valeur & (masque<<compteur) ) ALORS
afficher 1 ;
SINON
afficher 0 ;
FINSI
compteur=compteur+1 ;
JUSQU'A CE QUE ( compteur<=16 ) ;
FINPROG
Améliorer le code pour le faire dans le bon sens !! car j'ai bien l'impression que c'est a l'envers !:)
Essayer de pousser les limites du programme , des gros nombres en binaires , sur 32 bits par exemple.
Donner l'algo et le code / ou Monia , organigramme et PL
>./sapin 4
*
***
*****
*******
ici 4 est un exemple .. il accepte de 1 à 25 (ligne est égal à 4 ici)
dans cet exemple : nb_ligne est 4
il faut déterminer l’équation qui donne le nombre d'espace en fonction de nb_ligne et ligne , à afficher devant nb etoile '*' fonction de nb_ligne et ligne.
nb_ligne : nombre de ligne max du sapin
ligne : variable désignant pour la ligne
équations à résoudre:
nb_espace= f(nb_ligne,ligne)
ici nb_ligne est donné en argument. (dans notre exemple 4)
et l’équation suivante :
nb_etoile = f (nb_ligne, ligne)
Quand vous avez trouvé ces 2 équations le plus gros du travail est fait !
brouillon à réflexion .. pour déduire les équations
nb_ligne:
1
2
3
4
résultat stdout
___*
__***
_*****
*******
3 Espaces 1 étoile
2 Espaces 3 étoiles
1 Espace 5 étoiles
0 Espace 7 étoiles
nb_espace= (nb_ligne - ligne)
Vérification:
ligne va varier de 1 à 4 (nb_ligne)
nb_ligne=4 et que ligne=1 => nb_espace=3 (4-1)
nb_ligne=4 et que ligne=2 => nb_espace=2 (4-2)
nb_ligne=4 et que ligne=3 => nb_espace=1 (4-3)
nb_ligne=4 et que ligne=4 => nb_espace=0 (4-4)
CQFD!
nb_etoile= ((ligne -1)*2+1)
on note ici que nb_etoile depend uniquement de ligne !!
ligne va varier de 1 à 4 pour notre exemple !
Vérification:
ligne=1 => nb_etoile=1 (1-1)*2+1
ligne=2 => nb_espace=3 (2-1)*2+1
ligne=3 => nb_espace=5 (3-1)*2+1
ligne=4 => nb_espace=7 (4-1)*2+1
CQFD!
projet: sapin / sapin.xmo/sapin.pl/sapin.c
Prévoir un traitement des erreurs ..
./sapin
veuillez entrer une valeur entière.
pas d'erreur de segmentation acceptable! tester votre code pour que cela n'arrive pas!
L'erreur de segmentation est provoquée par un mauvais codage ! on ne doit pas utiliser des variables au delà de leur limites.
Souvent l'étudiant utilise des variable comme argv[2] par exemple ou d'autres sans avoir vérifier avant son existence dans le contexte de l'utilisation du code.
#include <stdlib.h>
#include <stdio.h>
int main (int argc , char *argv[])
{
int nb_ligne; /* compteur de ligne */
int nb_espace,nb_etoile;
int ligne; /* contient le nombre de ligne du sapin */
int compteur; /* variable pour compter */
/* on teste si il y a bien un argument */
if (argc!=2)
{
printf ("Pas content !! un paramètre svp \n");
return EXIT_FAILURE;
}
/* on determine la valeur entiere */
nb_ligne=atoi(argv[1]);
/* on doit avoir une valeur superieur a 25 et positive */
if ((nb_ligne > 25) | (nb_ligne < 0))
{
printf (" La valeur doit être comprise de 1 à 25 lignes maximum\n");
return EXIT_FAILURE;
}
for (ligne=1 ; ligne <= nb_ligne ; ligne ++)
{
nb_espace= (nb_ligne-ligne);
nb_etoile= ((ligne -1)*2+1);
for (compteur=0; compteur < nb_espace ; compteur++)
{
printf(" ");
}
for (compteur=0; compteur < nb_etoile ; compteur++)
{
printf ("*");
}
printf("\n");
}
return EXIT_SUCCESS;
}
Pour déterminer si un nombre entier naturel n est un nombre premier, on doit chercher un diviseur de n parmi les nombres premiers successifs (2, 3, 5, 7, 11 …) jusqu'à la valeur √n. Si le nombre n n'admet aucun diviseur parmi les nombres premiers successifs jusqu'à la valeur √n, c'est un nombre premier.
Concrètement, vous pouvez simplement diviser ce nombre par tous les entiers de 2 jusqu'à sa racine carrée. Si aucun de ces entiers ne le divise sans reste, alors le nombre est premier.
Avec Monia réaliser un algorithme et un pl qui va nous tester de 0 à 500 et nous donner la liste des nombres premiers <500
projet premier / premier.c /premier.xmo/premier.pl
Aide:
En C par exemple 5/2 = 2
Lire 5 division entière par 2 donne 2 (par défaut ou 3 par excès)
et 5%2 = 1
Lire 5 modulo 2 donne 1
1 étant le reste de la division entière de 5 / 2
pour tester un nombre si il est premier , il ne doit pas être divisible (division entière) pas un nombre entier entre 2 et lui même divisé par 2.
par exemple :
pour 13
=>13/2 , 6 reste 1
=>13/3 , 4 reste 1
=>13/4 , 3 reste 1
=>13/5 , 2 reste 3
=>13/6 , 2 reste 1
pas besoin d'aller plus loin ... on sait que 13 est premier !
Donner le pseudo code du programme. (Monia )
Un nombre est premier si il est divisible par lui et par 1 seulement !
./premier
2 3 5 .......
projet premier / premier.c
projet fibonacci / fibonacci.c /fibonacci.xmo /fibonacci.pl
Donner l'algorithme et pseudo code (monia) et le code
passer en paramètre le nombre d'élément de la suite à afficher.
./fibonacci 5
U0=1 U1=1 U2=2 U3=3 U4=5 U5=8
pour approfondir.
modifier le code précédent qui affichera la suite de Fibonacci.
nous approchons du nombre d'or quand
nombre d'OR = (Un-1+Un)/Un
./fibonacci 5
U0=0 U1=1 U2=1 U3=2 U4=3 U5=5 U6=8
le nombre d'or obtenu : 1.625
ici c'est le calcul (U5+U6)/U6 , (5+8)/8 = 1.625
donc plus nous irons loin dans la suite de Fibonacci plus nous tendrons vers le nombre d'OR qui est fini !
ici on a obtenu 1.625 qui est une approximation du nombre d'OR (1+SQR(5))/2 = 1.61803398
nombre d'OR
le nombre d'or se retrouve dans une des solutions de ce polynôme.
x²-x-1=0