Vous êtes sur la page 1sur 7

TD Programmation des microcontrôleurs 2019/2020

Travaux dirigés N°1


Introduction au langage C

Exercice 1
Enlever les parenthèses des expressions suivantes lorsqu'elles peuvent être
retirées.

a = (25 * 12) + b;
if ((a>4) &&(b==18)) { }
((a>=6)&&(b<18))||(c!=18)
c = (a = (b+10));
Évaluer ces expressions pour a=6, b=18 et c=24.

Exercice 2
Si une variable p1 de type signed char (8 bits signés) est déclarée écrire les
expressions en C permettant de :
• mettre à 1 le bit b2
• mettre à 1 le bit b3 et b6
• mettre à 0 le bit b0
• mettre à 0 le bit b4 et b5
• inverser le bit b3 (se fait facilement avec un ou exclusif)
• mettre à 1 le bit b2 et à 0 le bit b0
• mettre à 1 les bits b0 et b7 et à 0 les bits b3 et b4

Exercice 3
On donne le sous-programme suivant (tiré d'un ancien projet inter-semestre) :
void conversion(char nb,char result[8]){
char i;
for(i=7;i>=0;i--)
if ((nb & (1<<i)) == (1<<i))
result[i]=1;
else result[i]=0;
}
dont l'objectif est de convertir du décimal en binaire.
1) Peut-on retirer des parenthèses dans l'expression booléenne du if ?
2) Peut-on écrire (nb & (1<<i)) au lieu de ((nb & (1<<i)) == (1<<i))?
3) Construire l'expression booléenne qui permettrait l'écriture
for(i=7;i>=0;i--) if (E.B.?????) result[i]=0;
else result[i]=1;

Hmaied Sarhene Page 1


TD Programmation des microcontrôleurs 2019/2020

en donnant toujours le même le même résultat de conversion.


4) Modifier le programme pour qu'il fasse une conversion d'entier (16 bits) vers
le binaire.
5) Est-ce que l'algorithme suivant donne le même résultat de conversion :

for(i=7;i>=;i--) {
result[i]=nb%(2);
nb = nb / 2;
}

Exercice 4
Soit une variable :
char nb;
Écrire les expressions permettant de calculer les centaines, les dizaines et les
unité de cette variable.

Exercice 5
Différence entre && et & Évaluer les expressions :
•a&b
• a && b
pour a= 0xF0 et b=0x0F
En déduire les valeurs booléennes correspondantes (si ces expressions étaient
utilisées dans un if par exemple).
Construire des expressions booléennes sur les tests suivants
expression vraie si :
• le bit b6 est à 1
• le bit b3 est à 0
• le bit b2 est à 1 et le bit b4 est à 0
• le bit b2 est à 1 ou le bit b7 est à 0
• le bit b6 est l'inverse du bit b3 (sans utiliser de décalages)

Exercice 6
Quelle opération arithmétique est réalisée par un décalage ? Évaluer pour cela
les expressions suivantes (avec a=12
et b=23) :
• a = a >> 1 (ou a >>= 1)
• a = a >> 2 (ou a >>= 2)
• b = b << 1 (ou b <<=1)
• b = b << 2 (ou b <<=2)
Généralisation.
Construire une vraie expression booléenne avec opérateur de décalage, & et ^
qui reprend le test de l'exercice précédent : le bit b6 est l'inverse du bit b3

Hmaied Sarhene Page 2


TD Programmation des microcontrôleurs 2019/2020

Solutions
Exercice 1
a = 25 * 12 + b;

if (a>4 && b==18) { } // impossible d'enlever les parenthèses restantes

a>=6 && b<18 || c!=18

c = a = b+10;

Evaluation :

a reçoit 318

l'expression booléenne dans le if est vraie

l'expression complète est vraie car c est différent de 18

b+10 = 28 sera affecté à a puis à c

Exercice 2
signed char p1;

p1 = p1 | 0x04; // mettre à 1 le bit b2

p1 = p1 | 0x48; // mettre à 1 le bit b3 et b6

p1 = p1 & 0xFE; // mettre à 0 le bit b0

p1 = p1 & 0xCF; // mettre à 0 le bit b4 et b5

p1 = p1 ^ 0x08; // inverser le bit b3 (se fait facilement avec un ou exclusif)

p1 = p1 & 0xFE | 0x04 ; // mettre à 1 le bit b2 et à 0 le bit b0

p1 = p1 & 0xE7 | 0x81 ; // mettre à 1 les bits b0 et b7 et à 0 les bits b3 etb4

Exercice 3

1°)void conversion(char nb,char result[8]){

char i;
Hmaied Sarhene Page 3
TD Programmation des microcontrôleurs 2019/2020

// version avec le moins de parenthèses possibles

for(i=7;i>=0;i--)

if (nb & 1<<i == 1<<i)

result[i]=1;

else result[i]=0;

2°) Oui même si cette pratique est déconseillée. On peut même écrire : (nb &
1<<i). On ne peut pas retirer les dernières parenthèses car elles appartiennent au
if.

3°) Ce que l'on demande est d'inverser l'expression booléenne. Une façon simple
de procéder est :

for(i=7;i>=0;i--)

if (!(nb & (1<<i)) == (1<<i)) // ! est le complément logique

result[i]=0;

else result[i]=1;

Mais on peut aussi écrire :

for(i=7;i>=0;i--)

if (nb & 1<<i == 0x00) // ou 0 tout simplement

result[i]=0;

else result[i]=1;

Hmaied Sarhene Page 4


TD Programmation des microcontrôleurs 2019/2020

ou encore

for(i=7;i>=0;i--)

if (nb & 1<<i != (1<<i)) // remplacer == par !=

result[i]=0;

else result[i]=1;

4°)void conversion16(unsigned int nb,char result[8]){

char i;

for(i=15;i>=0;i--) // 15 au lieu de 7

if ((nb & (1<<i)) == (1<<i)) // ! est le complément logique

result[i]=1;

else result[i]=0;

5°) C'est la technique classique de changement de base : on calcule le reste et on


divise par la nouvelle base (2 ici)

Exercice 4
unsigned char cent,diz,unit;

char nb;

cent = nb / 100; // division entière par défaut

diz = (nb / 10)%10;

unit = nb % 10;

Hmaied Sarhene Page 5


TD Programmation des microcontrôleurs 2019/2020

Exercice 5
a & b est un calcul bit à bit :

a = 11110000

& b = 00001111

---------------

00000000

a && b se calcule en se demandant :

est-ce qu'a est vrai ? oui car il est différent de 0

est-ce que b est vrai ? oui car il est différent de 0

On fait donc un et logique entre deux valeurs vraies ce qui est vrai donc donne
00000001 (ou 1)

Les expressions maintenant :// on suppose que les bits appartiennent à une
variable p1

(p1 & 0x70) == 0x70 // le bit b6 est à 1

(p1 & 0x08) == 0x00 // le bit b3 est à 0

(p1 & 0x04) == 0x04 && (p1 & 0x10) == 0x00 // le bit b2 est à 1 et le bit b4 est
à0

(p1 & 0x04) == 0x04 || (p1 & 0x80) == 0x00 // le bit b2 est à 1 ou le bit b7 est à
0

(p1 & 0x40)== 0x40 && (p1 & 0x08)== 00 || (p1 & 0x40)==0x00 && (p1 &
0x08)==08 // le bit b6 est l'inverse du bit b3

Exercice 6
a = 6 car 12 = 00001100 donc (12 >> 1) = 00000110 = 6

a = 3 car 12 = 00001100 donc (12 >> 2) = 00000011 = 3

Hmaied Sarhene Page 6


TD Programmation des microcontrôleurs 2019/2020

b = 46 car 23 = 00010111 donc (23 << 1) = 00101110 = 46

b = 92 car 23 = 00010111 donc (23 << 2) = 01011100 = 92

On retient :

un décalage vers la droite est équivalent à une division par 2. Quand vous avez
une division par une puissance de 2 à faire, préférez le décalage à l'opération de
division.

un décalage vers la gauche est équivalent à une multiplication par 2. Quand vous
avez une multiplication par une puissance de 2 à faire, préférez le décalage à
l'opération de multiplication.

Construction de l'expression booléenne :// on suppose que les bits appartiennent


à une variable p1

//Utiliser un ou exclusif bit à bit en C

(p1 & 0x40)>>6 ^ (p1 & 0x08)>>3 // le bit b6 est l'inverse du bit b3

Le principe de la dernière ligne est de décaler les bits testés au poids faible et de
faire un ou exclusif qui donne un résultat vrai si et seulement si les deux valeurs
sont différentes.

Hmaied Sarhene Page 7

Vous aimerez peut-être aussi