Nous venons d'écrire quelques programmes très simples en langage C en utilisant l'ordinateur comme une calculette. C'est déjà pas mal, les premiers appareils pouvant faire cela ne datent que des années 1940. Mais on peut faire plus que cela avec un langage de programmation. Nous allons voir dans ce chapitre l'intérêt d'utiliser des variables, et les deux instruction fondamentale d'affectation et de lecture pour pouvoir les utiliser.
Donnons un problème (de programmation) à résoudre et voyons comment le recours à un petit programme peut nous aider.
Soit la fonction réelle de la variable réelle f définie par :
f(x) = (sin x + ln(x) ) / (ex+ 2)
On veut étudier cette fonction.
Une façon de faire est d'étudier l'allure de la courbe comme on le fait au lycée. Mais à un certain moment, soit ceci vous semble trop diffcile et vous allez essayer de construire l'allure de la courbe point par point, soit, pour obtenir un graphe plus précis, vous décidez de calculer un grand nombre de points. Vous pouvez pour cela utiliser une calculette scientifique, ou le langage C en tant que calculette scientifique, et écrire un certain nombre de fois l'expression numérique avec des valeurs différentes pour x. Mais ceci risque d'être assez long, sans oublier les possibilités d'erreurs dans l'écriture répétée de l'expression numérique.
Il est vrai que vous pouvez être aidé par l'éditeur de textes. Mais il faut quand même remplacer à chaque fois trois valeurs numériques. La programmation permet d'affecter une seule fois la valeur à x (exactement comme en Mathématiques) et de faire affcher la valeur f(x).
| Un programme | Voici un exemple de programme pour cela, qui se comprend de lui-même, et que nous commenterons ensuite pour que vous soyez capables d'écrire des programmes analogues.
#include <stdio.h>
#include <math.h>
int main(void)
{
float x, y;
x = 2;
y = (sin(x) + log(x))/(exp(x) + 2);
printf("f(%f) = %f", x, y);
}
|
| Utilisation de ce programme. | Lorsqu'on fait exécuter ce programme, on obtient une ligne de la forme suivante :
f(2.000000) = 0.170672Il sufft de modifier légèrement le programme, en ne changeant que la valeur affectée à x, autant de fois que nécessaire pour obtenir les valeurs désirées. |
| Commentaires. |
|
| Nom d'une variable. | Lorsqu'on utilise plusieurs variables, donc plusieurs boîtes, il est intéressant, pour ne pas dire fondamental, de pouvoir les distinguer. Une façon de faire est de leur donner un nom (un nom différent par variable). |
| Ecriture des identificateurs. | Les identificateurs seront donc des mots écrits linéairement sur un alphabet propre à chaque langage, comprenant les vingt-six lettres, ou caractères, (non accentuées) de `A' ‘ a `Z', et éventuellement en minuscule de `a' à `z', les chiffres de `0' à `9', et des caractères spéciaux (c'est-à-dire les autres symboles) tels que `$', `%', ` ' ... Un certain nombre de mots ne peuvent pas être utilisés comme identificateurs ; on les appelle les mots réserv és. Ils servent pour la combinaison des instructions élémentaires. Au vu des programmes préc&e acute;dents on se doute par exemple que les mots ``float'' et ``void'' sont des mots réservés du langage C. |
||||||||||||||||||||||||||||||||
| Les identificateurs du langage C. | En langage C, les identificateurs sont des mots écrits linéairement sur l'alphabet comprenant les vingt-six lettres (non accentuées) majuscules de `A' à `Z', les vingt-six lettres minuscules de `a' à `z', les chiffres de `0' à `9', et le blanc souligné ` ', avec la restriction que ce mot ne doit ni commencer par un chiffre, ni être un mot réservé. La longueur peut être quelconque mais le compilateur ne tient compte en général que des 32 premiers caractères, et même quelquefois que des 8 premiers. |
||||||||||||||||||||||||||||||||
| Mots réservés. | Les mots réservés du langage C standard sont les suivants :
|
| Intérêt des types. | Si nous poursuivons l'analogie d'une variable et d'une boîte, il peut être intéressant de savoir ce que doit contenir la boîte (pour qu'elle soit assez grande, ou qu'elle soit plus sophistiquée avec des séparations). Autrement dit il est int éressant d'indiquer le type de boîte que l'on veut. On dit que l'on attribue un type à une variable donnée. |
| Typage explicite. | Le typage explicite possède à la fois des avantages et des inconvénients. Le principal avantage du typage pour les utilisateurs est que le compilateur vérifie la cohérence des types. Imaginons, par exemple, que l'on écrive l'instruction suivante : A = B + C; avec B et C déclarées comme variables réelles et A déclarée comme variable entière. Il y a nécessairement une mauvaise conception du programme, que le compilateur détectera. Un autre avantage, bien que passant inaper›cu à l'utilisateur a priori, est que la déclaration du type permet à l'ordinateur de ne réserver que la place mémoire nécessaire (place moins importante pour un entier que pour un réel, par exemple). Un inconvénient est que le programmeur peut ressentir l'obligation de typer ses variables comme quelque chose de contraignant. D'autre part la vérification de la cohérence des types ralentit le compilateur. |
| Les types | On a les quatre types :
|
| Les constantes. | Lorsqu'une constante de type long est placée dans un programme, il faut la faire suivre de L (sans blanc). Par défaut une constante entière est de type int. On aura, par exemple : n = 2123L; |
| Format. | Le format pour affcher une expression de type long est %Ld. |
| Types. | On a les types float et double, et quelquefois long double :
|
| Constantes. | Lorsqu'une constante de type float (respectivement de type long double) est plac&eac ute;e dans un
programme, il faut la faire suivre de f ou de F (respectivement de L ou de l) sans espace. Par défaut une constante réelle est de type double. On aura, par exemple : X = 2.0L; |
| Format. | Le format pour affcher une expression de type long double est %Lf (attention !%lf n'est pas compris). |
| Type. | On a vu le type char ci-dessus. Les caractères sont codés par des entiers à l'aide d'un code, par exemple le code ASCII pour beaucoup de systèmes d'exploitation. Ainsi le caractère `A' est rangé dans la machine en tant qu'entier 65. |
| Format | Le format pour affcher les caractères est %c. |
| Constante. | Une constante caractère se place entre apostrophes verticales. Par exemple le caractère `a' s'écrit 'a'. Lorsqu'il s'agit d'un caractère non affchable on indique son code ascii précédé d'une contre-oblique (antislash en anglais), par exemple pour CTRL-Z de code ascii 26 on aura '\26'. |
Existe-t-il d'autres types ? Oui.
Nous venons de voir les types de bases.
Nous verrons au fur et à mesure de nos besoins des constructeurs de types, permettant d'obtenir des types plus complexes, tels que les types tableaux et les types structurés.
| Introduction | En langage C une variable doit toujours être déclarée avant d'être utilisée. Ceci n'est pas le cas de tous les programmes informatiques (par exemple le PHP). L'intérêt est le même que pour le typage. Si une variable non déclarée est utilisée, il y a une erreur dans le programme. Il sufft de consulter les déclarations de variables pour connaître la liste des variables utilisées. De plus la déclaration de variables facilite la compilation (mais ceci semble moins important à l'utilisateur). |
| Syntaxe. | Les variables se déclarent par des lignes de la forme : <type> <identificateur1>, <identificateur2>,...,<identificateurn>; où <identificateur1>, <identificateur2>,...,<identificateurn>; sont les noms des variables (àsavoir X ou Y dans notre exemple ci-dessus) et où <type> indique de quelle nature est la variable, float dans l'exemple ci-dessus.
#include <stdio.h>
int main (){
int a; /* Déclaration d'un entier nommé 'a'*/
short b=24;/* Déclaration d'un entier court, initialisé à 24, nomé 'b' */
char caratere_unique; /* Déclaration d'une variable pouvant contenir un caractère */
caratere_unique='g';/* Affectation du caractère 'g' à la variable 'caractere_unique' */
}
|
| Emplacement des déclarations. | Ces lignes ne peuvent pas se placer n'importe où à l'intérieur du programme. On peut déclarer des variables à l'intérieur de chaque bloc, mais à la condition que ces déclarations soient placées avant la première instruction du bloc. On peut aussi déclarer des variables hors de toute fonction, par exemple avant la fonction main(). |
| Introduction. | L'affectation est une instruction élémentaire très importante. Elle indique qu'il faut donner (on dit affecter) telle valeur à telle variable. |
| Syntaxe. | Une telle instruction est de la forme :Identificateur = Expression ; où Identificateur est une variable (déclarée) et Expression une expression dont le type est le même que celui de Identificateur. |
| Sémantique. | La valeur de l'expression (ce qui suppose que les variables apparaissant dans celle-ci possèdent une valeur) est affectée à la variable. Remarquons à ce propos que toute variable possède une valeur à tout moment (le contenu de la mémoire correspondante). Les variables doivent donc être initialisées, sinon le contenu risque d'apparaoître à l'utilisateur comme aléatoire. |
| Introduction. | Nous avons vu l'intérêt d'initialiser les variables. On peut déclarer une variable puis l'initialiser ensuite. On peut également, en langage C, initialiser une variable lors de sa déclaration. |
| Exemple de la première méthode. | Si on veut initialiser un entier àla valeur 2 on peut écrire : int i; ... i = 2; |
| Syntaxe de la deuxième méthode. | L'initialisation lors de la déclaration prend la forme suivante : type identificateur = valeur; |
Pour le problème précédent on peut donc aussi écrire :
int i = 2;
| Introduction. | Nous avons déjà remarqué que, parmi les fonctions prédéfinies, s'il existe bien une fonction partie entière dont le résultat est un réel, nous n'avons pas donné de fonction partie entière dont le résultat est un entier. Nous venons de voir, d'autre part, que les entiers et les réels ne sont pas codés de la même fa›con. Il existe, en langage C, une façon de convertir des entités de types cohérents d'un type à l'autre, par exemple des float en double, des int en float... Ceci se fait grâce à l'opération de conversion de type. Il existe une conversion de type implicite. Mais il existe aussi une conversion de type explicite (en anglais cast, à savoir 'joue le rôle de'). |
| Syntaxe. | On écrit : (type) expression pour forcer la valeur de l'expression expression à être de type type. |
| Sémantique | La sémantique est claire en général, avec quelquefois une valeur approchée qui a moins de précision (cas du passage du type double à float, par exemple). Dans le cas du passage d'un type réel à un type entier on obtient la partie entière. |
Le programme suivant :
/* cast.c */
#include <stdio.h>
int main(void) {
printf("%d", 3.14);
printf("Partie Entière de PI : ")
printf("\n%d\n", (int) 3.14);
}
permet de constater comment il faut calculer la partie entière. En effet l'exécution du programme donne : 1374389535
Partie Entière de PI : 3
| Introduction | Reprenons notre problème initial, à savoir calculer un certain nombre de valeurs de la fonction : f(x) = (sin x +ln(x))/(ex+ 2) . Nous avons vu plusieurs façons de faire (réécrire un programme par valeur, changer les valeurs grâce à l'éditeur de texte, ne changer qu'une seule fois la valeur grâce à l'affectation) mais, pour toutes ces méthodes, il faut un programme nouveau (et donc compiler à chaque fois) pour chaque valeur considérée. Les ordres de lecture vont nous faciliter la vie. |
| Un programme. | Voici un exemple de programme utilisant un ordre de lecture :
#include <stdio.h>
#include <math.h>
int main(void) {
float x, y;
printf("x = ");
scanf("%f",&x);
y = (sin(x) + log(x))/(exp(x) + 2);
printf("f(%f) = %f", x, y);
}
|
| Utilisation de ce programme | Lorsqu'on fait exécuter ce programme, on obtient une ligne de la forme suivante :x = Le symbole `` '' indiquant en fait le curseur qui clignote. Entrez alors un réel (le curseur se déplacera), pour obtenir, par exemple : x = 3.7865 puis appuyez sur la touche Return. On obtient alors les deux lignes : x = 3.7865 f(3.786500) = 0.015841 Il sufft de faire exécuter à nouveau le programme (sans le recompiler) autant de fois que nécessaire pour obtenir les valeurs désirées. |
| Introduction. | Nous connaissons l'intérêt des ordres d'écriture depuis notre tout premier programme. Nous venons de voir l'intérêt des ordres de lecture. Nous allons préciser la syntaxe de ces ordres en langage C. Il va s'agir plus exactement de ces ordres concernant les périphériques par défaut, à savoir le clavier pour les lectures et l'écran pour l'écriture. Nous verrons plus tard comment
faire pour d'autres périphériques, en particulier pour l'écriture sur l'imprimante. |
| Syntaxe | Un ordre d'écriture formatée est de la forme : printf(FORMAT, ARG1, ... ,ARGn); où FORMAT est une chaîne de caractères contenant n (le même n que celui de ARGn) directives de format (commençant par `%') et où ARG1, ... , ARGn sont des expressions. |
| Sémantique. | La chaîne de caractères sera affchée telle quelle sauf en ce qui concerne les séquences d'échappement et les directives de format. Nous avons déjà vu comment sont affchées les séquences d'échappement, par exemple `\\' par `\' et `\n' par un passage à la ligne. La i-ième directive de format sera remplacée par la valeur du i-ième argument suivant les instructions de cette directive de format. |
| Syntaxe. | On a : scanf(format, &variable); où format est une directive de format (commençant par `%') et où variable est une variable. L'esperluette (ampersand en anglais) & est appelée l'opérateur d'adressage. |
| Sémantique. | Lorsque cet ordre est rencontré, l'ordinateur attend que quelque chose soit entré au clavier, ce qu'il indique par un curseur clignotant à l'écran. Il affche à l'écran en écho le mot entré de la même façon qu'un ordre de lecture. Il sait que ce mot est entré complètement lorsqu'on appuie sur la touche return. Le curseur est alors placé (à l' écran),non pas juste après ce qui vient d'être entré, mais au début de la ligne suivante puis l'ordinateur passe à l'instruction suivante. Bien entendu, de plus, la valeur entrée est affectée à la variable. On dit que l'ordre de lecture est une instruction bloquante car on ne passe à l'instruction suivante que lorsque l'utilisateur a réagi. |
| Introduction. | Nous ne voyons pas comment entrer du texte avec les ordres de lecture vus précédemment, puisque les seuls types de variables sont, pour l'instant, ceux de nombres (entiers et réels). |
| Un exemple. | Le programme suivant se comprend aisément ; nous expliciterons après les aspects nouveaux :
/* prenom.c */
#include <stdio.h>
int main(void) {
char prenom[20]; /* Déclaration d'une variable pouvant contenir maximun 20-1 caractères */
printf("Quel est votre prenom ?");
scanf("%s", prenom);
printf("Bonjour %s \n",prenom);
}
|
| Déclaration des variables chaînes de caractères. | Sans que nous cherchions pour l'instant à comprendre complètement pourquoi (nous y reviendrons plus tard), disons qu'un mot (on dit plutôt en informatique une chaîne de caractères, string en anglais) de nom mot d'au plus 19 caractères se déclare : char mot[20]; (nous verrons également, plus tard, pourquoi 20 et non 19, c'est-à-dire un de plus). |
| Format. | Le format pour saisir ou affcher une chaîne de caractères (en tant que valeurs d'une variable; nous avons vu que le format n'est pas nécessaire pour les constantes) est %s. |
| Saisie d'une chaîne de caractères. | La saisie se fait comme les autres types mais on remarquera l'absence de l'esperluette. Nous l'expliquerons plus tard. |
| Intérêt. | Il n'y a rien de vraiment nouveau à propos de la saisie d'un caractère ; nous allons seulement donner un exemple et en expliquer l'intérêt. L'intérêt de saisir un caractè re, même si cela n'apparaît pas à l'utilisateur, est la gestion de la mémoire. La place retenue en mémoire par la déclaration d'un caractère est évidemment (beaucoup) moindre que celle pour une chaoîne de caractères. |
| Exemple. | L'exemple ci-dessous est caractéristique de l'utilisation du type char dans un programme :
/* char.c */
#include <stdio.h>
int main(void) {
char c;
printf("Aimezvous ce cours ? (O/N)");
scanf("%c", &c);
}
|
| Commentaire. | Le programme demande si l'on aime le cours en question et attend une réponse parmi les deux qui sont indiquées : `O' pour oui, `N' pour non. Le programme est cependant un peu décevant puisque, quelle que soit la réponse, il s'arrête (quel était l'intérêt de la question dans ces conditions ?). Nous verrons que c'est l'introduction des structures de contrôle qui nous permettra d'aller plus loin intelligemment. |
L'intérêt des variables est qu'elles peuvent prendre des valeurs que l'on ne connaoît pas a priori. Si l'on connaît la valeur alors autant la considérer tout de suite. Ce principe a des exceptions. Si on doit utiliser plusieurs fois cette valeur dans un programme, surtout si son écriture est un mot assez long, on a intérêt à lui donner un nom auquel on affecte une valeur, cette valeur ne pouvant plus être changée. Ceci conduit à la notion de constante au sens informatique.
Il y a deux façons de déclarer une constante en langage C :
| Constante pré-processeur | Dans la première version de C il n'y avait pas de notion de constante proprement dite. On pouvait l'émuler en utilisant la commande du préprocesseur appelée : #define. |
| Syntaxe | La syntaxe est : #define identificateur expression où expressionest une expression constante. Il vaut mieux placer cette commande en début de programme, comme toute commande du préprocesseur. Le préprocesseur remplace toute occurrence de identificateur dans le programme par l'expression. On remarquera qu'il n'y a pas de signe d'égalité entre l'identificateur et l'expression. |
| Type 'const' | Cette méthode n'est valable que pour le C ANSI. C'est un emprunt au langage PASCAL via le langage C++. Les constantes se déclarent aux mêmes positions que les variables, de la façon suivante : const type Identificateur = valeur ; `const'(pour constante) est l'appel de déclaration de constantes. Chaque constante a un nom, qui est un identificateur, non utilisé par ailleurs et qui ne pourra plus être attribué a une autre entité (constante, variable...). La valeur de cette constante est donnée. Le type de la constante est précisé explicitement. |
Cours, éxercices ou graphismes libre de droit. Un mail est souhaitable | Webmestre : Aublet Bastien (bastien.aublet@hotmail.fr)