Utilisation de Switch a la place de if else if else (Arduino
Résolu/Fermé
A voir également:
- Arduino switch case string
- Télécharger switch - Télécharger - Conversion & Extraction
- Cannot access offset of type string on string - Forum PHP
- Mod minecraft switch - Forum minecraft
- Samsung smart switch pc - Télécharger - Divers Bureautique
- Uninitialized string offset ✓ - Forum PHP
6 réponses
mamiemando
Messages postés
32298
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
23 mars 2023
7 575
Modifié le 6 déc. 2021 à 12:18
Modifié le 6 déc. 2021 à 12:18
Bonjour,
C'est simple, tu ne peux pas, à moins d'énumérer toutes les valeurs de ta plage :-) De plus un switch nécessite que la valeur testée soit un type entier (e.g.
En fait c'est assez normal, c'est inhérent à la manière dont
Note enfin que dans la version
Après, une manière plus élégante d'écrire ton code qui associe à chaque intervalle la donnée qui nous intéresse un arbre d'intervalles, mais comme ici les intervalles sont disjoints, on peut directement utiliser un arbre binaire de recherche. Comme aucune de ces structure n'est implémentée directement en C, et vu qu'il y a peu de notes, tu peux te contenter d'une structure moins efficace mais plus simple à coder, par exemple un bon vieux tableau.
Ton code pourrait du coup ressembler à ceci :
... ce qui donne :
Bonne chance
C'est simple, tu ne peux pas, à moins d'énumérer toutes les valeurs de ta plage :-) De plus un switch nécessite que la valeur testée soit un type entier (e.g.
char,
int,
uint, ...), donc si ton code doit marcher avec un
floatou un
double, tu ne peux pas t'en sortir avec un
switch.
En fait c'est assez normal, c'est inhérent à la manière dont
switchfonctionne : c'est relativement proche de la notion de labels et de
goto.
Note enfin que dans la version
if ... else if ...il faut être vigilant à l'ordre dans lequel tu fais tes tests si tu ne contrôle que l'une des deux bornes de chaque plage de valeurs.
Après, une manière plus élégante d'écrire ton code qui associe à chaque intervalle la donnée qui nous intéresse un arbre d'intervalles, mais comme ici les intervalles sont disjoints, on peut directement utiliser un arbre binaire de recherche. Comme aucune de ces structure n'est implémentée directement en C, et vu qu'il y a peu de notes, tu peux te contenter d'une structure moins efficace mais plus simple à coder, par exemple un bon vieux tableau.
Ton code pourrait du coup ressembler à ceci :
#include <stdio.h> typedef struct _note_t { unsigned short min; unsigned short max; const char * name; } note_t; static const note_t NOTES[] = { {495, 528, "Do4"}, {470, 495, "Si3"}, // ... }; const char * find_note(double freq) { const note_t * note = &(NOTES[0]); unsigned num_notes = sizeof(notes) / sizeof(note_t); for (unsigned i = 0; i < num_notes; i++, note++) { if (note->min <= freq && freq < note->max) { return note->name; } } return NULL; } int main(){ double freqs[] = {400, 470, 475, 495, 500, 530}; unsigned num_freqs = sizeof(freqs) / sizeof(double); const double * pfreq = &freqs[0]; for (unsigned i = 0; i < num_freqs; i++, pfreq++) { double freq = *pfreq; printf("find_note(%lf) = %s\n", freq, find_note(freq)); } return 0; }
... ce qui donne :
(mando@silk) (~) $ gcc notes.c && ./a.out
find_note(400.000000) = (null)
find_note(470.000000) = Si3
find_note(475.000000) = Si3
find_note(495.000000) = Do4
find_note(500.000000) = Do4
find_note(530.000000) = (null)
Bonne chance
georges97
Messages postés
10385
Date d'inscription
lundi 31 janvier 2011
Statut
Contributeur
Dernière intervention
24 mars 2023
2 266
6 déc. 2021 à 12:24
6 déc. 2021 à 12:24
Bonjour,
Sauf erreur de ma part, l'exemple suivant permet de tester une condition correspondant à un intervalle et de la traiter dans un switch:
https://stackoverflow.com/questions/45645087/if-else-and-string-in-a-switch-case
voir également:
https://www.locoduino.org/spip.php?article23
Ce serait bien de revenir nous dire si cela convient ou si je me suis complètement fourvoyé concernant votre demande.
Sauf erreur de ma part, l'exemple suivant permet de tester une condition correspondant à un intervalle et de la traiter dans un switch:
https://stackoverflow.com/questions/45645087/if-else-and-string-in-a-switch-case
voir également:
https://www.locoduino.org/spip.php?article23
Ce serait bien de revenir nous dire si cela convient ou si je me suis complètement fourvoyé concernant votre demande.
mamiemando
Messages postés
32298
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
23 mars 2023
7 575
Modifié le 6 déc. 2021 à 12:29
Modifié le 6 déc. 2021 à 12:29
Bonjour georges,
Non, dans les deux exemples que tu donnes,
En particulier, cela signifie que si l'on passe une une valeur comprises entre deux de ces valeurs discrètes, le
Non, dans les deux exemples que tu donnes,
switchne fait pas un test permettant de vérifier si la valeur appartient ou non à un intervalle, mais s'il coïncide avec certaines valeurs discrètes.
En particulier, cela signifie que si l'on passe une une valeur comprises entre deux de ces valeurs discrètes, le
switcht'enverra dans le bloc
default:.
georges97
Messages postés
10385
Date d'inscription
lundi 31 janvier 2011
Statut
Contributeur
Dernière intervention
24 mars 2023
2 266
>
mamiemando
Messages postés
32298
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
23 mars 2023
6 déc. 2021 à 13:45
6 déc. 2021 à 13:45
Bonjour mamiemando,
Merci pour l'explication. Je continue mon apprentissage.
A bientôt
Merci pour l'explication. Je continue mon apprentissage.
A bientôt
Whismeril
Messages postés
18290
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 mars 2023
888
6 déc. 2021 à 11:35
6 déc. 2021 à 11:35
Bonjour
Les exemples c’est bien.
La doc aussi
https://docs.microsoft.com/fr-fr/cpp/c-language/switch-statement-c?view=msvc-170
En C, le case est une valeur unique, constante (ça ne peut pas être une variable) et de type integral (entier, caractère…)
Les exemples c’est bien.
La doc aussi
https://docs.microsoft.com/fr-fr/cpp/c-language/switch-statement-c?view=msvc-170
En C, le case est une valeur unique, constante (ça ne peut pas être une variable) et de type integral (entier, caractère…)
Oui ! D'après cette documentation, j'ai bien l'impression qu'il s agisse toujours de tests de "pure" égalite !! (ou de progression de 1 en 1 ! on n'est pas rendu ...)
donc, l ordre switch ne répond sans doute pas à ma problématique ?
Je cherchais l'équivalent comme dans d autres langages, il y avait
Sinon, je ne suis pas abonné au
Merci de vos retours
a++
donc, l ordre switch ne répond sans doute pas à ma problématique ?
Je cherchais l'équivalent comme dans d autres langages, il y avait
CASEQ,
CASLT,
CASGTpar exemple...
Sinon, je ne suis pas abonné au
switch, si une autre instruction fait le job, je suis preneur. ;-)
Merci de vos retours
a++
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Merci à tous pour vos réponses. Je pensais "simplifier" la structure de mes tests (fort heureusement indentés !), mais le code propose reste assez "complexe" pour quelqu'un comme moi qui aborde tout juste le C++ pour Arduino. Je "lis" via une cellule photosensible pour "'retranscrire" sur un buzzer. Je vais donc conserver mon ancien code mais vous remercie encore pour vos idées de code.
Prenez soin de vous
Prenez soin de vous
Whismeril
Messages postés
18290
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
24 mars 2023
888
6 déc. 2021 à 13:35
6 déc. 2021 à 13:35
Juste une petite remarque, tu as posté ta question dans le forum C, donc on a tous répondu en fonction.
C++ pour ce cas précis c’est pareil, mais pas toujours.
Je déplace dans le bon forum
C++ pour ce cas précis c’est pareil, mais pas toujours.
Je déplace dans le bon forum
Pardon en cliquant sur la rubrique, j ai vu "C" ... je me suis dit que ca allait pile poil ! Un grand merci à tous les intervenants, en tous cas, ça m'a bien aidé ! J ai "quand même" poussé, non pas la chansonnette, mais le code pour les tableaux.
Ça simplifie vachement le code (et le nombre de lignes !!) ;-)
Encore merci
Ça simplifie vachement le code (et le nombre de lignes !!) ;-)
Encore merci
// Recherche dans le tableau [0,7] (frequence & nom de la note) for (int i = 0 ; i < Tab_Max; ++i) { // Si la recherche n a pas abouti, on compare if ((sensorValue >= Tab_Notes[i]) && (Trouve == 0)) { Frequence = Tab_Notes[i]; Note = Lib_Notes[i]; Trouve = 1; } } // Si Trouve = 0... (pas abouti) // la frequence est plus basse que Do3 ( <264 ), // forcer a Do3 inferieur if (Trouve == 0) { Frequence = Tab_Notes[Tab_Max] - 64; // frequence = 200 Note = "en dessous"; }
6 déc. 2021 à 12:36
N'est-ce pas plutôt la méthode choisie pour parcourir le tableau qui est peu efficace?
Modifié le 6 déc. 2021 à 12:55