Debian logo [embedded-µC.LINUX]

7. Éléments de Langage C

Cette section présente succinctement les éléments essentiels du Langage C en donnant un maximum d'exemples adaptés au développement sur système spécialisé.

On utilise un exemple de programme presque aussi connu que le très fameux «Hello, World!» ; le calcul des nombres de Fibonacci. On commence par présenter le listing complet, puis on détaille les éléments de la syntaxe du Langage C.

Le même programme est présenté sous plusieurs formes différentes en fonction du contexte de développement.

Exemple 3. Calcul des nombres de Fibonacci sur GNU/Linux avec GCC

01: /* $Id: gcc_fibonacci_single.c 1129 2007-05-07 15:07:52Z latu $
02:  * Un programme simple pour calculer les n premiers nombres de Fibonacci */
03: 
04: #include <stdio.h>
05: #include <stdlib.h>
06: 
07: #define MAX_FIB 49
08: 
09: main() {
10: 
11:   int n, i;
12:   unsigned int nombrePrecedent, nombreCourant, fibonacci;
13:   
14: 
15:   printf("Saisir le nombre de calculs de Fibonacci(n) :\n");  
16:   scanf("%d", &n);
17:   if (n >= MAX_FIB) {
18:     printf("Fibonacci(%d) depasse la capacite d'un mot de 32 bits\n", n); 
19:     exit(1);
20:     }
21: 
22:   nombrePrecedent = 0;
23:   nombreCourant = 1;
24:   for (i = 0; i < n; i++) {
25:      if (i > 1) {
26:         fibonacci = nombrePrecedent + nombreCourant;
27:         nombrePrecedent = nombreCourant;
28:         nombreCourant = fibonacci;
29:         printf("Fibonacci (%d) = %u\n", i, fibonacci);
30:      }
31:      else
32:         printf("Fibonacci (%d) = %u\n", i, i);
33:   }
34: }

Voici un exemple d'exécution du programme gcc_fibonacci_single.c :

$ ./gcc_fibonacci_single.out
Saisir le nombre de calculs de Fibonacci(n) :
11
Fibonacci (0) = 0
Fibonacci (1) = 1
Fibonacci (2) = 1
Fibonacci (3) = 2
Fibonacci (4) = 3
Fibonacci (5) = 5
Fibonacci (6) = 8
Fibonacci (7) = 13
Fibonacci (8) = 21
Fibonacci (9) = 34
Fibonacci (10) = 55

Comme dans le cas du premier programme présenté, le code source du programme destiné au microcontrôleur MSC1210 inclut le pilotage de l'interface série. Dans ce contexte de développement, on ne dispose pas de système d'exploitation.

Exemple 4. Calcul des nombres de Fibonacci sur microcontrôleur MSC1210 avec SDCC

01: #include <stdio.h>
02: #include <stdlib.h>
03: #include <msc1210.h>
04: #include "ser_msc1210.h"
05: 
06: #define MAX_FIB 49
07: 
08: // surdefinition du sous-programme putchar
09: void putchar(char c) {
10:    ser_putc(c);
11:   }
12: 
13: void main(void) {
14: 
15:    unsigned char s[3] = {'\0','\0','\0'};
16:    int n, i;
17:    unsigned long nombrePrecedent, nombreCourant, fibonacci;
18: 
19:    // Appuyer sur <Entree> pour ajuster automatiquement
20:    // le debit de la liaison
21:    autobaud();
22:    EA=1;
23: 
24:    do {
25:       printf("Saisir le nombre de calculs de Fibonacci :\r\n");
26:       ser_gets_echo(s, 2);
27:       n = atoi(s);
28:       if (n >= MAX_FIB)
29:          printf("\nFibonacci(%d) depasse la capacite d'un mot de 32 bits\r\n", n);
30:    } while (n >= MAX_FIB);
31: 
32:    printf("\r\n\n");
33:    nombrePrecedent = 0;
34:    nombreCourant = 1;
35:    for (i = 0; i < n; i++) {
36:       if (i > 1) {
37:          fibonacci = nombrePrecedent + nombreCourant;
38:          nombrePrecedent = nombreCourant;
39:          nombreCourant = fibonacci;
40:          printf("Fibonacci (%d) = %lu\r\n", i, fibonacci);
41:       }
42:       else
43:          printf("Fibonacci (%d) = %d\r\n", i, i);
44:    }
45:    while(1);
46: }

Voici un exemple de résultat d'exécution du programme sdcc_fibonacci_single.c :

MSC1210 Ver:000305F10
>M0000 ok
>M8000 ok
>E
>Saisir le nombre de calculs de Fibonacci :
11

Fibonacci (0) = 0
Fibonacci (1) = 1
Fibonacci (2) = 1
Fibonacci (3) = 2
Fibonacci (4) = 3
Fibonacci (5) = 5
Fibonacci (6) = 8
Fibonacci (7) = 13
Fibonacci (8) = 21
Fibonacci (9) = 34
Fibonacci (10) = 55

7.1. Délimiteurs

Généralités sur les délimiteurs de syntaxe du Langage C des exemples ci-dessus :

Les commentaires

Ils sont repérés par deux slashes (//) si le texte du commentaire ne comprend qu'une seule ligne. Ils sont délimités entre les balises /* et */ si le texte du commentaire comprend plusieurs lignes.

Les directives du préprocesseur

Elles sont repérées par le caractère dièse en début de ligne :

 #include <stdio.h>
 #define TRUE	1

Ces directives ne sont pas considérées comme faisant partie du code. Elles ne sont donc pas délimitées comme des instructions «classiques».

Les instructions

Elles sont séparées par le caractère point-virgule :

 printf ("Hello,");
 printf (" World!");

Dans les deux exemples de référence ci-dessus, on relève que toutes les instructions (déclarations de variables, opérations, etc.) sont délimitées par des caractères ';' à l'exception des directives du préprocesseur.

Les groupes d'instructions

Ils sont délimités par les caractères accolades ouvertes et fermées :

 while(1) {
 	printf ("Hello,");
	printf (" World!");
 }

7.2. Représentation des données

En programmation, les données manipulées sont appelées variables ou constantes.

Une variable sert au stockage d'une information en vue de sa réutilisation dans le programme principal et|ou un sous-programme.

Du point de vue gestion de la mémoire (RAM ou Random Access Memory), une variable est une zone mémoire réservée et «étiquetée» avec le nom de cette variable.

Sur une machine avec système d'exploitation, la phase de déclaration d'une variable correspond à une demande de réservation mémoire au gestionnaire de mémoire virtuelle du noyau. Ce gestionnaire doit gérer au mieux ces demandes en fonction des programmes actifs sur le système.

Sur un système spécialisé, c'est au développeur de gérer «manuellement» son espace mémoire. Il n'existe aucune protection contre le débordement de la capacité mémoire.

Du point de vue syntaxique, il existe certaines restrictions dans l'emploi des noms de variables et de constantes. Les caractères de ponctuation ne sont pas utilisables. Le caractère «souligné» (underscore) est considéré comme une lettre ; il est beaucoup utilisé par le préprocesseur.

[Avertissement] Avertissement

En Langage C, les majuscules et les minuscules sont traitées différemment. On utilise généralement les majuscules pour les définitions de constantes et les minuscules pour les variables.

Suivant la génération du compilateur utilisé, le nombre de caractère pris en compte pour les noms de variables est plus ou moins limité. Historiquement, cette limite était fixée à 8 bien que l'on puisse en utiliser davantage dans le code source.

Dans les deux exemples ci-dessus, on trouve les déclarations des variables après l'accolade de début de programme principal (fonction main()).

7.3. Types de représentation des données

Pour représenter les données à manipuler on distingue différents types élémentaires définis dans la syntaxe du langage de programmation. La table ci-dessous donne une liste complète de ces types.

Tableau 1. Types élémentaires du Langage C

Type de donnée syntaxe C
rien ou vide void
caractère char
nombre entier court short
nombre entier int
nombre entier long long
nombre entier long double long long
nombre réel float
nombre réel double double
nombre réel long double long double

À la lecture de la table ci-dessus, on constate que le langage C n'offre pas de type booléen. Pour autant, la valeur entière 0 correspond à l'état faux et toutes les autres valeurs entières correspondent à l'état vrai. La technique usuelle pour représenter les deux états booléens consiste à définir deux constantes. Voir Section 7.4, « Constantes ».

En Langage C, si les noms de types sont toujours les mêmes, leurs formats diffèrent suivant les chaînes de développement et les processeurs utilisés. Les deux exemples ci-dessous illustrent ces différences.

Dans le cas de la chaîne de développement GNU utilisée sur PC, il est possible de représenter de très grands nombres réels sur 12 octets soit 96 bits. À l'inverse, il n'est pas possible de représenter une donnée sur moins d'un octet.

Voici le résultat d'un programme utilisant la fonction sizeof pour chacun des types donnés dans la liste ci-dessus. Le code source de ce programme est disponible à l'adresse : gcc_sizeof.tar.bz2.

Exemple 5. Formats des types supportés par GCC

Dimension de chaque type en octets :
'char'          :       1
'unsigned char' :       1
'short'         :       2
'int'           :       4
'long'          :       4
'long long'     :       8
'float'         :       4
'double'        :       8
'long double'   :       12

Dans le cas du compilateur SDCC et du microcontrôleur cible MSC1210, il n'est pas possible d'utiliser des nombres réels au delà de la représentation simple sur 4 octets. La plus petite unité représentée est le bit même si l'appel à la fonction sizeof pour ce type produit un résultat surprenant  1 octet pour 1 bit.

Comme avec la chaîne de développement GNU/GCC, voici le résultat d'un programme utilisant la fonction sizeof pour chacun des types donnés dans la liste ci-dessus. Le code source de ce programme est disponible à l'adresse : sdcc_sizeof.tar.bz2.

Exemple 6. Formats des types supportés par SDCC

>Dimension de chaque type en octets :
'char'          :       1
'unsigned char' :       1
'short'         :       2
'int'           :       2
'long'          :       4
'long long'     :       4
'float'         :       4
Attention ! le type bit existe :
'bit'           :       1

7.4. Constantes

Une constante est une valeur particulière que l'on utilise tout au long du programme. Si cette valeur doit être modifiée, il est préférable de n'avoir qu'une seule ligne à éditer. En terme de maintenabilité du code source, l'utilisation de constantes est très avantageux. De plus, l'utilisation d'une représentation littérale d'une valeur numérique particulière permet de gagner en lisibilité.

En informatique industrielle, on fait un usage «massif» des constantes. En effet tous les registres et les adresses de pilotage des périphériques spécialisés sont représentés à l'aide de constantes. Si ce mode de représentation n'existait pas, on ne pourrait utiliser que des valeurs hexadécimales. Les difficultés de développement des programmes seraient beaucoup plus importantes du fait des confusions possibles entre des valeurs voisines.

En Langage C, les constantes sont en fait des directives destinées au préprocesseur. En effet, comme le rôle du préprocesseur est d'analyser la syntaxe du code source d'un programme, il peut se charger de substituer toutes les occurrences des constantes par leurs valeurs numériques avant de passer à la compilation proprement dite.

Cette technique est très avantageuse puisque l'utilisation des constante ne nécessite aucune réservation en mémoire.

Les deux exemples de programmes montrent la même constante MAX_FIB déclarée à l'aide de la directive #define. Cette constante correspond aux rang maximum du nombre de Fibonacci que l'on peut représenter sur 32 bits.

[Avertissement] Avertissement

Il faut noter qu'une directive de préprocesseur n'est pas instruction du langage C. C'est la raison pour laquelle on n'utilise pas le caractère ';' comme délimiteur. Cette absence de délimitation ne pose pas de difficulté dans la mesure où on ne peut trouver qu'une directive par ligne.

Dans les exemples «rituels» de définition de constantes on trouve les deux états booléens :

#define FALSE 0
#define TRUE 1

Le fichier d'en-tête standard limits.h est un exemple caractéristique de liste de définitions de constantes. Ce fichier contient les définitions des valeurs entières maximales pour chaque type connu. Voici un extrait du fichier fourni avec la chaîne GNU/GCC :

/* Number of bits in a `char'.  */
#  define CHAR_BIT      8

/* Minimum and maximum values a `signed char' can hold.  */
#  define SCHAR_MIN     (-128)
#  define SCHAR_MAX     127

/* Maximum value an `unsigned char' can hold.  (Minimum is 0.)  */
#  define UCHAR_MAX     255

/* Minimum and maximum values a `char' can hold.  */
#  ifdef __CHAR_UNSIGNED__
#   define CHAR_MIN     0
#   define CHAR_MAX     UCHAR_MAX
#  else
#   define CHAR_MIN     SCHAR_MIN
#   define CHAR_MAX     SCHAR_MAX
#  endif

/* Minimum and maximum values a `signed short int' can hold.  */
#  define SHRT_MIN      (-32768)
#  define SHRT_MAX      32767

/* Maximum value an `unsigned short int' can hold.  (Minimum is 0.)  */
#  define USHRT_MAX     65535

/* Minimum and maximum values a `signed int' can hold.  */
#  define INT_MIN       (-INT_MAX - 1)
#  define INT_MAX       2147483647

/* Maximum value an `unsigned int' can hold.  (Minimum is 0.)  */
#  define UINT_MAX      4294967295U

7.5. Opérateurs de calcul

On retrouve les opérateurs usuels en Langage C : +, -, * et /. À cette liste, il faut ajouter les éléments propres aux calculs en Langage C.

Opérateur modulo, %

Cet opérateur, noté %, renvoie le reste de la division entre 2 entiers. Par exemple : 24 % 9 = 6

Opérateurs d'incrémentation et de décrémentation, ++ et --

Pour ajouter une unité à une variable, on utilise l'opérateur d'incrémentation ++. Pour soustraire une unité à une variable, on utilise l'opérateur de décrémentation --.

La position de l'opérateur, à la gauche ou à la droite du nom de variable à une signification particulière. Dans l'expression 'while (++n < 10)', la variable n sera incrémentée avant d'être comparée à 10. À l'inverse, dans l'expression 'while (n++ < 10)', la variable n est comparée à 10 avant d'être incrémentée.

Opérateurs et expressions d'affectation

En Langage C, on peut appliquer la règle suivante sur les 2 expressions e1 et e2 : '(e1) = (e1) (opérateur) (e2)' est équivalent à '(e1) (opérateur)= (e2)'. Tous les opérateurs usuels de calculs sont utilisables avec cette règle. Ainsi, i = i + 2; est équivalent à i += 2;.

7.6. Opérateurs relationnels

Ces opérateurs évaluent une condition sur des nombres entiers ou réels et renvoient une valeur booléenne 0 ou 1.

Tableau 2. Opérateurs relationnels

Symbole Opérateur|Condition
== égalité
!= différence
> supérieur à
< inférieur à
>= supérieur ou égal à
<= inférieur ou égal à

7.7. Opérateurs logiques de bits

Tableau 3. Opérateurs logiques de bits

Symbole Opérateur
& ET
| OU (inclusif)
^ OU (exclusif)
<< décalage à gauche avec remplissage par 0
>> décalage à gauche avec remplissage par 0
~ négation binaire ou complément à 1

7.8. Instruction de test if-else

On utilise l'instruction if-else pour prendre des décisions. Sa forme générale est  :

 if ( expression )
    instruction1;
 else
    instruction2;

Si l'expression est vraie, c'est l'instruction 1 qui est exécutée ; sinon c'est l'instruction 2. Les instructions 1 et 2 peuvent correspondre à des groupes délimités par des caractères { et }. La partie else est optionnelle. Si l'instruction 2 n'existe pas, on n'utilise pas ce mot clé.

[Important] Une condition fausse vaut toujours 0

Si la condition codée dans l'expression n'est pas vérifiée (est fausse) c'est la valeur numérique 0 qui est renvoyée. Pour toutes les autres valeurs renvoyées par l'expression, la condition est considérée comme vérifiée (est vraie).

En langage C, il est très fréquent d'utiliser directement les valeurs numériques dans les instructions if-else sans coder explicitement la condition dans l'expression. De nombreux exemples de ce mode de codage ont été volontairement placés dans les exemples de programmes fournis dans le présent document.

  • Exemple 3, « Calcul des nombres de Fibonacci sur GNU/Linux avec GCC » : les lignes 17 à 20 permettent de contrôler que l'utilisateur a bien saisi un nombre de calculs compatible avec la représentation sur 32 bits du résultat. Si l'utilisateur saisit une valeur supérieure à la constante MAX_FIB, on affiche le message d'erreur à la console et l'exécution du programme s'arrête. Les deux instructions à traiter si l'expression est vraie sont encadrées par des accolades.

    Les lignes 25 à 30 montrent que l'on effectue le calcul des nombres de Fibonacci pour les valeurs de la variable i strictement supérieures à 1. Si cette condition n'est pas respectée, on affiche directement le numéro du calcul comme résultat.

  • Exemple 4, « Calcul des nombres de Fibonacci sur microcontrôleur MSC1210 avec SDCC » : les lignes 28 et 30 permettent de contrôler que l'utilisateur a bien saisi un nombre de calculs dont les résultats sont correctement représentés sur 32 bits. Dans ce cas, on se contente d'afficher le message d'erreur. On n'utilise pas d'accolades de délimitation de groupe d'instructions.

    Comme dans la version GNU/GCC, les lignes 36 à 41 montrent que l'on effectue le calcul des nombres de Fibonacci pour les valeurs de la variable i strictement supérieures à 1.

7.9. Instructions de choix multiples : switch & if-else-if

Le traitement des choix multiples peut devenir compliqué lorsque l'imbrication des blocs d'instructions entre instructions if-else augmente. C'est pour cette raison qu'une syntaxe particulière à été introduite : l'instruction switch dont le synoptique est le suivant.

switch (expression) {
	case Valeur1:
		// Instructions
		break;
	case Valeur2:
		// Instructions
		break;
	...
	case ValeurN:
		// Instructions
		break;
	default:
		// Instructions
}

Le cas classique d'utilisation de l'instruction switch consiste à programmer un menu à choix multiples. La variable à tester est de type simple puisqu'il s'agit d'un caractère. Le programme sdcc_switch.c illustre justement l'utilisation d'un menu suivi d'un test à choix multiples.

Cette structure est très pratique lorsque le résultat de l'expression est de type simple. Lorsque l'on doit évaluer non pas une valeur mais une plage de valeurs, il devient alors plus pratique de retenir un codage du type suivant.

  if (condition1) {
	// Instructions
  }
  else if (condition2) {
	// Instructions
  }
  else if (condition3) {
	// Instructions
  }
  // autres conditions
  else {
	// Instructions
  }

7.10. Instructions de boucles : for, while, do-while

Dès lors qu'une ou plusieurs instructions doivent être répétées, on utilise les instructions de boucles disponibles avec le Langage C.

Indépendemment du langage de programmation utilisé, il existe des règles dans l'emploi des boucles.

  1. On emploie la boucle pour (for) lorsque l'on connaît le nombre d'itérations (ie. le nombre de fois où le traitement doit être répété dans la boucle).

  2. On emploie la boucle répéter jusqu'à (do-while) lorsque le corps de la boucle doit être exécuté au moins une fois.

  3. On emploie la boucle tant que (while) lorsque le corps de la boucle peut ne pas être exécuté.

7.10.1. Syntaxe de la boucle pour (for)

La boucle pour (for) en C/C++ comprend 3 champs distincts : l'initialisation, le test de sortie et l'incrémentation.

  for (initialisation; test; incrémentation ) {
  	// Instructions
  }

Les 3 champs définis ci-dessus peuvent être composés à l'aide de n'importe quelle expression C/C++ valide. Ce mode de construction des boucles pour est une originalité importante du C/C++. Il faut cependant être vigilant lors du choix des expressions placées dans ces champs. Un codage trop compact (avec des appels multiples de fonctions par exemple) et|ou des opérations sur des variables sans relations sont très pénalisant pour la mise au point des programmes.

7.10.2. Syntaxe de la boucle répéter jusqu'à (do-while)

Conformément à la règle énoncée ci-dessus, le test est effectué après une première exécution du corps de la boucle répéter jusqu'à (do-while).

  do {
  	// Instructions
  } while (test);

Comme dans le cas de la boucle précédente, la condition testée peut être composée à l'aide de n'importe quelle expression C/C++ valide. Il est donc préférable de limiter la complexité de cette expression pour faciliter la mise au point des programmes.

7.10.3. Syntaxe de la boucle tant que (while)

Conformément à la règle énoncée ci-dessus, le test est effectué avant que le corps de la boucle tant que (while) ne soit exécuté.

  while (test) {
         // Instructions
  }

Une fois encore ! attention à l'expression de test.

7.11. Sous-programmes

La démarche classique de construction d'un programme informatique veut que l'on découpe un problème complexe en sous-ensembles plus faciles à traiter. Du point de vue du codage, cette démarche se traduit par l'utilisation de sous-programmes correspondant à ces sous-ensembles.

La réutilisation de code est un autre argument pour l'emploi des sous-programmes. Si un même traitement doit être répété à plusieurs reprises dans un programme, il est préférable de le placer dans un sous-programme qui sera appelé autant de fois que nécessaire.

Enfin, le recours aux sous-programmes doit faciliter la lecture et la mise au point des programmes. Un jeu de sous-programmes bien écrit et compréhensible par un grand nombre de programmeurs peut être réutilisé sous forme de bibliothèque.

La bibliothèque glibc est probablement l'exemple le plus emblématique de bibliothèque partagée. Elle est disponible avec la totalité des chaînes de développement en Langage C sur tous les systèmes d'exploitation et pour presque tous les processeurs.

Les fonctions getchar, putchar, printf et atoi sont quelques exemples de sous-programmes partagés à l'aide de la bibliothèque glibc. On les retrouve dans les programmes d'illustration présentés dans ce document.

Exemple 7. Utilisation d'un sous-programme dans le calcul des nombres de Fibonacci

01: #include <stdio.h>
02: #include <stdlib.h>
03: 
04: #define MAX_FIB 49
05: 
06: unsigned long iterative_fibonacci(unsigned long f) {
07: 
08:    unsigned long nombrePrecedent = 0, nombreCourant = 1, fibonacci = 0;
09:    int i;
10: 
11:    if (f > 1 )
12:       for (i = 1; i < f; i++) {
13:          fibonacci = nombrePrecedent + nombreCourant;
14:          nombrePrecedent = nombreCourant;
15:          nombreCourant = fibonacci;
16:       }
17:    else
18:       fibonacci = f;
19: 
20:    return fibonacci;
21: }
22: 
23: main() {
24: 
25:    int n, i;
26: 
27:    printf("Saisir le nombre de calculs de Fibonacci(n) :\n");  
28:    scanf("%d", &n);
29:    if (n >= MAX_FIB) {
30:       printf("Fibonacci(%d) depasse la capacite d'un mot de 32 bits\n", n); 
31:       exit(1);
32:    }
33: 
34:    for (i = 0; i < n; i++)
35:       printf("Fibonacci (%d) = %lu\r\n", i, iterative_fibonacci(i));
36: }

On retrouve des résultats identiques aux précédents avec le programme gcc_fibonacci_iterative.c.


Exemple 8. Utilisation d'un sous-programme dans le calcul des nombres de Fibonacci sur la cible MSC1210

01: #include <msc1210.h>
02: #include "ser_msc1210.h"
03: #include <stdio.h>
04: #include <stdlib.h>
05: 
06: #define MAX_FIB 49
07: 
08: // surdefinition du sous-programme putchar
09: void putchar(char c) {
10:    ser_putc(c);
11:   }
12: 
13: unsigned long iterative_fibonacci(unsigned long f) {
14: 
15:    unsigned long nombrePrecedent = 0, nombreCourant = 1, fibonacci = 0;
16:    int i;
17: 
18:    if (f > 1 )
19:       for (i = 1; i < f; i++) {
20:          fibonacci = nombrePrecedent + nombreCourant;
21:          nombrePrecedent = nombreCourant;
22:          nombreCourant = fibonacci;
23:       }
24:    else
25:       fibonacci = f;
26: 
27:    return fibonacci;
28: }
29: 
30: void main(void) {
31: 
32:    unsigned char s[3] = {'\0','\0','\0'};
33:    int n, i;
34: 
35:    // Appuyer sur <Entree> pour ajuster automatiquement
36:    // le debit de la liaison
37:    autobaud();
38:    EA=1;
39: 
40:    do {
41:       printf("Saisir le nombre de calculs de Fibonacci :\r\n");
42:       ser_gets_echo(s, 2);
43:       n = atoi(s);
44:       if (n >= MAX_FIB)
45:          printf("\nFibonacci(%d) depasse la capacite d'un mot de 32 bits\r\n", n);
46:    } while (n >= MAX_FIB);
47: 
48:    printf("\r\n\n");
49:    for (i = 0; i < n; i++)
50:       printf("Fibonacci (%d) = %lu\r\n", i, iterative_fibonacci(i));
51: 
52:    while(1);
53: }

On retrouve aussi des résultats identiques aux précédents avec le programme sdcc_fibonacci_iterative.c.

MSC1210 Ver:000305F10
>M0000 ok
>M8000 ok
>E
>T
>
>Saisir le nombre de calculs de Fibonacci :
11

Fibonacci (0) = 0
Fibonacci (1) = 1
Fibonacci (2) = 1
Fibonacci (3) = 2
Fibonacci (4) = 3
Fibonacci (5) = 5
Fibonacci (6) = 8
Fibonacci (7) = 13
Fibonacci (8) = 21
Fibonacci (9) = 34
Fibonacci (10) = 55