Programmation C — Trucs et astuces
Manipulation des char
¶
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* print_val() {
char* buf = malloc(20);
strcpy(buf, "Test");
printf("in-fct buf is %s\n", buf);
return(buf);
}
int main()
{
char *nbuf = print_val();
printf("Main buf is %s\n", nbuf);
return 0;
}
RĂ©-assignement d'un char array¶
char rtclib_buffer[] = "YYYY-MM-DD hh:mm:ss";
// Faire quelque chose avec rtclib_buffer
strcpy(rtclib_buffer, "YYYY-MM-DD hh:mm:ss"); // Et le ramener Ă sa valeur initiale
Binary operations¶
Masques rapides¶
D’après OpenClassrooms
var = var | ( (1<<2) | (1<<4) | (1<<5) ); // Soit var | 0b0011 0100
Note: pour visualisation avec Python.
"{:08b}".format((1<<4) | (1 << 2) | (1<<5))
#'00110100'
VĂ©rifier la valeur d’un bit¶
Il faut décaler la variable à tester vers la droite jusqu’à ce que le bit à tester soit devenu le bit de poids faible, puis faire un AND 1
.
uint8_t value = 0b10101010;
(value >> 3) & 1; // True, le bit 4 vaut 1
(value >> 4) & 1; // False, le bit 5 vaut 0.
Note : cette astuce peut être utilisée pour vérifier si un entier est pair. Un entier pair a son bit de poids faible égal à 0
, un entier impair a son bit de poids faible Ă©gal Ă 1
.
Modification de la valeur d’un bit¶
Les snippets suivants permettent de modifier sélectivement un unique bit parmi de nombreux autres. Ils sont inspirés par ce post sur Stackexchange
Mettre un bit Ă zĂ©ro¶
La mise à zéro se fait en combinant l’opérateur ET (&
) et l’opérateur NOT (~
).
uint8_t value = 0b11111111;
value = value & ~((uint8_t)1 << 4);
printf("%b\n", value);
// Doit renvoyer « 0b1110111 »
Explications
On exploite ici la table de vérité de la fonction ET.
Bit 1 | Bit 2 | Bit 1 & Bit 2 |
---|---|---|
0 | 0 | 0 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
(uint8_t)1 // Cast 1 vers un entier Ă 8 bits
// Renvoi = 0b0000 0001
(uint8_t)1 << 4 // Ce 1 est décalé de 4 bits vers la gauche
// Renvoi = 0b0001 0000
~((uint8_t)1 << 4) // On inverse tous les bits
// Renvoi = 0b1110 1111
value = 0b01010101
value & ~((uint8_t)1 << 4) // On applique ce masque sur la valeur de base
/*
0b01010101
&0b11101111
-----------
0b01000101
*/
Mettre un bit Ă 1¶
On utilise cette fois le simple opérateur OR (|
).
uint8_t value = 0b10000000;
value = value | ((uint8_t)1 <<5);
printf("%b\n", value);
// Doit renvoyer « 0b10100000 »
Explications
Cette fois ci, on utilise la table de vérité de la fonction OU, qui renvoie un 1 si au moins l’une des deux valeurs est 1.
Bit 1 | Bit 2 | Bit 1 & Bit 2 |
---|---|---|
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 1 |
Pour l’opération ci-dessus, on a :
1000 0000b
OR 0010 0000b
-------------
= 1010 0000b
Inverser un bit¶
On utilise le XOR / Ou Exclusif (^
);
uint8_t value = 0b10100000;
value = value ^ ((uint8_t)1 <<5);
printf("%b\n", value);
// Doit renvoyer « 0b10000000 »
Explications
La table de vérité utilisée est celle de la fonction OU EXCLUSIF, qui renvoie un 1 si et seulement si l’une des deux valeurs est 1, et renvoie 0 lorsque les deux valeurs sont identiques.
Bit 1 | Bit 2 | Bit 1 & Bit 2 |
---|---|---|
0 | 0 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
1 | 1 | 0 |
Pour l’opération ci-dessus, on a :
1010 0000b
XOR 0010 0000b
--------------
= 1000 0000b
Le 7ème bit de chaque nombre étant à 1, leurs valeurs « s’annulent » selon la table de vérité de la fonction XOR, et le bit est passé à zéro. On remarque que le 8ème bit du premier nombre est à 1, et celui du second est à 0. Le résultat est inchangé, on garde bien un 1.