Serie 6 Corrigé Exercice 1 (niveau 1):Tailles des variables des types

publicité
Serie 6 Corrigé
Exercice 1 (niveau 1):Tailles des variables des types de base avec sizeof()
Voici le résultat de l'exécution du programme (depuis la VM 2015-16):
Taille
Taille
Taille
Taille
Taille
Taille
Taille
Taille
Taille
d'un
d'un
d'un
d'un
d'un
d'un
d'un
d'un
d'un
char : 1
short int : 2
int : 4
long int : 8
long long int : 8
int8_t : 1
float : 4
double : 8
long double : 16
1.1 : Puisqu'une variable de type float occupe 4 bytes, on peut stocker 1024 / 4 = 256
variables de type float dans 1024 bytes. Pour les double, on peut y stocker
seulement 128 variables
1.2 : La taille du type int en bits est de 4 bytes * 8 = 32 bits, car il y a 8 bits par byte.
1.3 : Oui, depuis la VM 2015-16 le type int est codé sur 4 octets tandis que long int
est codé sur 8 octets. Par contre il n’y a pas de différence entre long int et long long
int car les deux types sont sur 8 octets.
Exercice 2 (niveau 1): Conséquences d'un overflow avec des nombres entiers
Les résultats, qu'il fourmit, sont :
500 + 2500 = 3000
1000000000 + 1000000000 = 2000000000
1500000000 + 1500000000 = -1294967296 (overflow)
Comme un type int est codé sur 32 bits (avec signe), l'intervalle des valeurs admises
est [-2​31​...2​31​-1] = [-2147483648...2147483647]. C'est beaucoup, mais pas suffisant
pour faire le calcul demandé.
Exercice 3 (niveau 1): Le compteur entier détraqué
Le programme incrémente bien la variable, jusqu'à ce que celle-ci atteigne la valeur
entière positive maximum 2147483647, qui est équivalente à 2​31​ -1.
Si on ajoute une unité, la retenue modifie le bit de signe qui passe alors à 1. Cela est
interprété comme un nombre négatif. Il s’agit du plus petit nombre négatif
représentable dans la représentation choisie. C’est un cas ​d’overflow​.
Ensuite à chaque ajout de une unité on revient vers vers les nombres positifs. Donc
la boucle va recommencer à faire un overflow plus tard.
Exercice 4 (niveau 1): opérateur de division avec des nombres entiers
L'erreur est faite quand on affecte à la variable ​f​ le résultat d'une division entière (​a
et ​b​ étant de type int) car la division de 2 entiers donne un quotient ​entier​ sans partie
fractionnaire.
Par exemple : 5 / 9 = 0.
Il faut donc demander explicitement une conversion en type ​float​ de l'une des deux
variables (au moins).
// faire include de stdio.h et stdlib.h
#include​ ​<stdio.h>
#include​ ​<stdlib.h>
int​ main (​void​)
{
​int​ a, b;
​float​ f;
printf (​"Entrez deux nombres entiers: "​);
scanf (​"%d %d"​, &a, &b);
f = (​float​) a / b;
printf (​"La fraction %d / %d est egale a %f\n"​, a, b, f);
}
​return​ EXIT_SUCCESS;
Exercice 5 (niveau 1): Conversion de degrés Fahrenheit (°F) en degrés Celsius
(°C)
L'erreur classique est de recopier la formule mathématique sans faire attention aux
types des constantes. En particulier, si on recopie la fraction ​5/9​ celle-ci est
interprétée par le compilateur ​comme une division de deux entiers​, c'est à dire
une division entière qui donne comme résultat ​zéro​... Or ce qu'on veut est bien sûr le
quotient avec une partie fractionnaire ; pour cela il faut indiquer qu'on travaille avec
des constante de type double (ou float) comme ceci: ​5.0/9.
// faire include de stdio.h et stdlib.h
#include​ <
​ stdio.h>
#include​ <
​ stdlib.h>
int​ main (​void​)
{
​float​ f, ​/* Temperature en degres Fahrenheit */
c; ​/* Temperature en degres Celsius */
printf(​"Entrez la temperature en degres Fahrenheit :"​);
scanf (​"%f"​, &f);
c = (f - 32.) * (5./9.);
​if​ (c > -273.15)
printf (​"La temperature en degres Celsius vaut %f\n"​, c);
​else
printf(​"Votre valeur doit etre superieure au zero absolu\n"​);
}
​return​ EXIT_SUCCESS;
Exercice 6 (niveau 1): Conversion en heures minutes-secondes d'un nombre
de secondes et l'opérateur modulo %
C'est une application typique de l'opérateur de division entière et du modulo de
nombres entiers.
// faire include de stdio.h et stdlib.h
#include​ ​<stdio.h>
#include​ ​<stdlib.h>
int​ main (​void​)
{
​int​ s;
printf (​"entrez le nombre de secondes: "​);
scanf (​"%d"​, &s);
printf (​"cela correspond a : %u h %u min %u secondes"​,
s / 3600, (s % 3600) / 60, s % 60);
​return​ EXIT_SUCCESS;
}
Exercice 7 (niveau 1): Conversion d'un float en int le plus proche
La conversion automatique d'un float ou d'un double en int est faite en supprimant la
partie fractionnaire: ​on obtient la partie entière​. Ce n'est pas un arrondi à l'entier le
plus proche. Sachant cela, pour obtenir l'arrondi à l'entier le plus proche il suffit de
prendre la partie entière du ​nombre augmenté de 0.5​ .
// faire include de stdio.h et stdlib.h
#include​ ​<stdio.h>
#include​ ​<stdlib.h>
int​ main (​void​)
{
}
​float​ f;
printf (​"Donnez un nombre reel: "​);
scanf (​"%f"​, &f);
printf (​"Nombre entier le plus proche: %d\n"​, (​int​) (f + 0.5));
​return​ EXIT_SUCCESS;
Exercice 8 (niveau 1): Opérateurs bit à bit
Voici le program, qui affiche un message indiquant si le bit ​p ​du nombre ​n ​est à ​1 ​ou
pas :
#include​ <
​ stdio.h>
#include​ <
​ stdlib.h>
int​ main (​void​)
{
​unsigned​ n ;
​int​ p;
printf (​"nombre unsigned: "​);
scanf(​"%u"​,&n);
printf (​"indice du bit [0, 31]:"​);
scanf(​"%d"​,&p);
printf (​"Le bit %d est à %d\n"​, p,((1<<p)&n)?1:0);
}
​return​ EXIT_SUCCESS;
NOTE : l’​opérateur conditionnel​ (?:) évalue une expression retournant une valeur si
cette expression est vraie et une autre si l'expression est faux, donc l’expression :
printf (​"Le bit %d est à %d\n"​, p,((1<<p)&n)?1:0);
est équivalent à:
int​ isEqual;
if​ ((1<<p)&n)
isEqual = 1;
else
isEqual = 0;
printf (​"Le bit %d est à %d\n"​, p, isEqual);
Pour qu'il affiche le nombre total de bits à ​1 ​et à ​0 ​du nombre ​n​, il faut le modifier
comme ci-dessous :
#include​ ​<stdio.h>
#include​ ​<stdlib.h>
int​ main (​void​)
{
​unsigned​ n, mask;
​int​ count_1 =0;
printf (​"nombre unsigned: "​);
scanf(​"%u"​,&n);
mask = 1;
​do
{
count_1 += ((mask&n)?1:0);
mask = mask << 1 ;
}​while​(mask);
}
printf (​"Le nombre de bits à 1 est à %d\n"​, count_1);
printf (​"Le nombre de bits à 0 est à %d\n"​, 32-count_1);
​return​ EXIT_SUCCESS;
Téléchargement