Retour à l'index

Variable, affectation et lecture


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.

Un premier programme

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.170672
			
Il 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.
  • On utilise des variables, nommées ici x et y.
  • Toute variable doit être déclarée, et sa nature doit être donnée. Techniquement, on doit spécifier le type (ici de type réel flottant). C'est l'objet de la septième ligne du programme.
  • La huitième ligne est une instruction d'affectation : elle indique qu'il faut donner (on dit affecter) telle valeur (ici 2) à telle variable (ici x). La neuvième ligne est également une instruction d'affectation, un peu plus complexe. L'instruction nouvelle que nous venons d'introduire est celle d'affectation. Explicitons-la un peu plus.

Variable

Qu'est-ce qu'une variable ?

Vous connaissez déjà la notion de variable pour l'avoir rencontrée en mathématiques. Aucune définition ne vous en a été donnée. On peut seulement la comparer à une booîte qui peut prendre des valeurs différentes à des instants différents.
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).

Identificateur

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 :
auto breakcasecharconstcontinuedefaultdo
doubleelseenumexternfloatforgotoif
int long register return short signed sizeof static
struct switch typedef union unsigned void volatile while

Type

Gén éralités sur les types

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.

Cas des entiers

Les types On a les quatre types :
  • char,
  • int,
  • short,
  • long.
(évidemment pour les mots anglais character, integer) signifiant caractère, entier, court et long). Chacun de ces quatre types peut tous être précédés du modificateur signed (valeur par défaut, sauf pour char) ou unsigned pour désigner des entiers naturels ou des entiers relatifs. Le mot signed ou unsigned tout seul est considér&eacu te; comme suivi du mot int.
  • Le type char est un entier codé sur un octet. Il prend donc les valeurs 0 à 255. Il sert, en particulier, à repr&eacut e;senter la valeur entière d'un caractère.
  • Le type short code les entiers sur un certain nombre d'octets, ce nombre n'étant pas défini par la norme.
  • Le type long code les entiers sur un certain nombre d'octets, ce nombre n'étant pas défini par la norme, mais il doit & ecirc;tre égal ou supérieur au nombre d'octets pour le type short.
  • Le type int correspond à short ou à long, le type exact auquel il se réfère n'étant pas d& eacute;fini par la norme.

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.

Cas des réels

Types. On a les types float et double, et quelquefois long double :
  • un ré ;el de type float est codé sur un certain nombre d'octets, celui-ci n'étant pas défini par la norme.
  • un réel de type double est codé sur un certain nombre d'octets, celui-ci n'étant pas défini par la norme mais étant égal ou supérieur à celui pour le type float.
  • un ré ;el de type long double peut, par exemple être cod&eacu te; sur 10 octets (avec en général une mantisse de 64 bits, un exposant de 15 bits et un signe de 1 bit), ce qui donne, pour les r&eac ute;els positifs, des nombres appartenant à l'intervalle de 3,4.10-4932 à 3, 4.104932>

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).

Cas des caractères

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'.

Autres types

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.

Déclaration des variables

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().

Affectation

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.

Initialisation des variables

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; 


Exemple.

Pour le problème précédent on peut donc aussi écrire :

 int i = 2; 

Partie entière et conversion de type

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.

Ordres de lecture et d'écriture

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.

Exemple.

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

Il parrait évident qu'il existe une erreur. A la premiere ligne, le programme tente d'afficher un entier, alors qu'en argument, il lui est passé un réel (float).
Cependant, à la seconde ligne, il est afficher '3', il est bien la partie entière (int) du réel 3.14.


Nous avons déjà vu quelques instructions d'affchage à l'écran. Voyons maintenant comment saisir un paramètre au clavier.

Un exemple

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.

Ordre d'écriture formatée

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.

Ordre de saisie formatée

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.

Commentaires

Cas des chaînes de caractères

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.

Saisie d'un caractère

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.

Les constantes


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.

Déclaration des constantes

Il y a deux façons de déclarer une constante en langage C :


Cours, éxercices ou graphismes libre de droit. Un mail est souhaitable | Webmestre : Aublet Bastien (bastien.aublet@hotmail.fr)