<?xml version="1.0" encoding="ISO-8859-1"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
	<channel>
		<title>Forum du club des développeurs et IT Pro - Blogs - Bktero</title>
		<link>https://www.developpez.net/forums/blogs/313209-bktero/</link>
		<description>Developpez.com, le Club des Développeurs et IT Pro</description>
		<language>fr</language>
		<lastBuildDate>Sat, 25 Apr 2026 16:37:24 GMT</lastBuildDate>
		<generator>vBulletin</generator>
		<ttl>15</ttl>
		<image>
			<url>https://forum.developpez.be/images/misc/rss.jpg</url>
			<title>Forum du club des développeurs et IT Pro - Blogs - Bktero</title>
			<link>https://www.developpez.net/forums/blogs/313209-bktero/</link>
		</image>
		<item>
			<title><![CDATA[Comment tester de manière élégante l'appartenance à des plages de valeurs en C ?]]></title>
			<link>https://www.developpez.net/forums/blogs/313209-bktero/b48/tester-maniere-elegante-l-appartenance-plages-valeurs-c/</link>
			<pubDate>Mon, 27 Oct 2014 19:41:28 GMT</pubDate>
			<description>Je cherchais une idée...</description>
			<content:encoded><![CDATA[<blockquote class="blogcontent restore">Je cherchais une idée d'article pour tester cette nouvelle fonctionnalité de Developpez.com (au passage, saluons Anomaly et les personnes l'ayant aidé !). J'ai répondu à cette <a href="http://www.developpez.net/forums/d1477584/c-cpp/c/switch-case-c/" target="_blank">discussion</a> sur les forums aujourd'hui et cela m'a donné une idée : comment gérer de manière élégante des tests d'appartenances à des plages de valeurs, en C ?<br />
<br />
Le problème exposé par le PO (posteur initial ^^) est le suivant :<br />
<div class="bbcode_container">
	<div class="bbcode_quote">
		<div class="quote_container">
			<div class="bbcode_quote_container"></div>
			
				Ecrire un programme qui demande l'âge de l'utilisateur et affiche sa catégorie :<br />
<ul><li style="">Poussin : 6-7 ans</li><li style="">Pupille : 8-9 ans</li><li style="">Minime : 10-11 ans</li><li style="">Cadet : 12+</li><li style="">Pas de catégorie : 5 ans et -</li></ul>
			
		</div>
	</div>
</div>De manière plus large, on raisonnera sur l'appartenance d'une valeur donnée à des plages possibles. Le titre parle de C mais les principes sont génériques et applicables à d'autres langages.<br />
<br />
La technique qui ressort de cette discussion est de passer par de longues listes de cases à l'intérieur d'un switch sur l'âge. Comme je le dis dans mon message en #18, je pense que cette technique est mauvaise. La maintenance est quasiment impossible quand on rajoute des plages et qu'on souhaite changer les bornes, il est beaucoup trop facile d'avoir des cas en double, la gestion de plages non continues est très compliquée.<br />
<br />
GCC propose une extension intéressante, comme montrée au message #12 : <a href="https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html" target="_blank">les Case Range</a>s. Elle peut rendre élégante et compacte la solution switch / case et donc acceptable. Elle a l'inconvénient de perdre la portabilité...<br />
<br />
La meilleure solution est sans doute de passer par une structure if / else if / else et de multiplier les else if au fur et à mesure que des plages se rajoutent. A l'indentation près, on obtient quelque chose de semblable avec des if / else imbriqués mais la différence est que le code devient illisible et donc dur à maintenir si des plages s'ajoutent ; il faut donc bien utiliser des else if.<br />
<br />
Pour être encore plus élégant, on peut déléguer les tests à des fonctions. La structure devient alors très claire à lire, proche d'un énoncé humain : si c'est un poussin, si c'est un minime, etc. Si un jour les tests deviennent un peu plus complexes que deux inégalités (par exemple, si une catégorie est est l'union de deux plages non continues ou si les catégories diffèrent selon si on est une fille ou un garçon), il est aisé de changer les fonctions sans toucher à la structure conditionnelle. De plus, ces fonctions resserviront sans doute ailleurs dans le code. On retrouve deux principes récurrents de la programmation : encapusuler les détails pouvant changer dans le futur et factoriser ce qui est redondant.<br />
<br />
Voici ce que ça peut donner en C :<br />
<div class="bbcode_container">
	<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr>
	<td style="border: 0; padding: 0; text-align: left">Code C :</td>
	<td style="border: 0; padding: 0; text-align: right"><a href="#" onclick="return ano_selectionnerCode(this);">Sélectionner tout</a> -
	<a href="#" onclick="return ano_etendreCode(this);">Visualiser dans une fenêtre à part</a></td></tr></table>
	<pre class="bbcode_code" style="height:204px;"><table cellspacing="0" cellpadding="0"><tr><td valign="top" width="33"><div style="border: 1px dashed gray; padding-left: 5px; padding-right: 5px; margin-right: 5px; text-align: right; font-family: monospace">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br /></div></td><td valign="top"><pre style="margin: 0"><span style="color: #339933;">#include</span><span style="color: #FF0000;"> &lt;stdbool.h&gt;</span>
<span style="color: #339933;">#include</span><span style="color: #FF0000;"> &lt;stdio.h&gt;</span>
&nbsp;
<span style="color: #339933;">#define ENTREE_POUSSIN  6</span>
<span style="color: #339933;">#define ENTREE_PUPILLE  8</span>
<span style="color: #339933;">#define ENTREE_MINIME   10 </span>
<span style="color: #339933;">#define ENTREE_CADET    12</span>
&nbsp;
<span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">unsigned</span> <span style="color: #0000ff;">int</span> age_t;
&nbsp;
<span style="color: #0000ff;">bool</span> isPoussin<span style="color: black;">&#40;</span>age_t age<span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span>
    <span style="color: #0000ff;">return</span> age &gt;= ENTREE_POUSSIN &amp;&amp; age &lt; ENTREE_PUPILLE;
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> isPupille<span style="color: black;">&#40;</span>age_t age<span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span>
    <span style="color: #0000ff;">return</span> age &gt;= ENTREE_PUPILLE &amp;&amp; age &lt; ENTREE_MINIME;
<span style="color: black;">&#125;</span>  
&nbsp;
<span style="color: #0000ff;">bool</span> isMinime<span style="color: black;">&#40;</span>age_t age<span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span>
    <span style="color: #0000ff;">return</span> age &gt;= ENTREE_MINIME &amp;&amp; age &lt; ENTREE_CADET;
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> isCadet<span style="color: black;">&#40;</span>age_t age<span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span>
    <span style="color: #0000ff;">return</span> age &gt;= ENTREE_CADET;
<span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: black;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#123;</span>
    age_t age = <span style="color: #cc66cc;">0</span>;
    puts<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Age ?&quot;</span><span style="color: black;">&#41;</span>;
    scanf<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;%u&quot;</span>, &amp;age<span style="color: black;">&#41;</span>; <span style="color: #808080;">// pas terrible mais simple pour cet exemple</span>
&nbsp;
    printf<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Il a %u ans ?<span style="color: #800000;">\n</span>&quot;</span>, age<span style="color: black;">&#41;</span>;
&nbsp;
    <span style="color: #0000ff;">if</span><span style="color: black;">&#40;</span>isPoussin<span style="color: black;">&#40;</span>age<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#123;</span>
       puts<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;C'est un poussin !&quot;</span><span style="color: black;">&#41;</span>;
    <span style="color: black;">&#125;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span><span style="color: black;">&#40;</span>isPupille<span style="color: black;">&#40;</span>age<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#123;</span>
        puts<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;C'est un pupille !&quot;</span><span style="color: black;">&#41;</span>;
    <span style="color: black;">&#125;</span>
    <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span><span style="color: black;">&#40;</span>isMinime<span style="color: black;">&#40;</span>age<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#123;</span>
        puts<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;C'est un minime !&quot;</span><span style="color: black;">&#41;</span>;
    <span style="color: black;">&#125;</span>
     <span style="color: #0000ff;">else</span> <span style="color: #0000ff;">if</span><span style="color: black;">&#40;</span>isCadet<span style="color: black;">&#40;</span>age<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
    <span style="color: black;">&#123;</span>
        puts<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;C'est un cadet !&quot;</span><span style="color: black;">&#41;</span>;
    <span style="color: black;">&#125;</span>
    <span style="color: #0000ff;">else</span>
    <span style="color: black;">&#123;</span>
        puts<span style="color: black;">&#40;</span><span style="color: #FF0000;">&quot;Too young to die, to old to rock n' roll...&quot;</span><span style="color: black;">&#41;</span>;
        <span style="color: #808080;">// https://www.youtube.com/watch?v=Rwn0R1PFUwU</span>
    <span style="color: black;">&#125;</span>
<span style="color: black;">&#125;</span></pre></td></tr></table></pre>
</div><br />
<div style="margin: 20px; margin-top: 5px"><pre class="alt2" style="border: 1px inset; padding: 5px">$ c99 conditional.c 
$ ./a.out 
Age ?
10
Il a 10 ?
C'est un minime !</pre></div>Le mérite d'une telle solution ne m'est pas totalement imputable : je reprend les principes énoncés par Steve McConnel au chapitre 15 (&quot;<i>Using Conditionals</i>&quot;) de son livre Code Complete (livre dont je conseille la lecture à tout personne trempant dans l'informatique au sens large).</blockquote>

]]></content:encoded>
			<dc:creator>Bktero</dc:creator>
			<guid isPermaLink="true">https://www.developpez.net/forums/blogs/313209-bktero/b48/tester-maniere-elegante-l-appartenance-plages-valeurs-c/</guid>
		</item>
	</channel>
</rss>
