« Langage C/Variables » : différence entre les versions

Contenu supprimé Contenu ajouté
Mewtow (discussion | contributions)
Ajout du chapitre sur les variables dans le cours sur le C
(Aucune différence)

Version du 15 mars 2013 à 19:09

Programmer, c’est avant tout donner des ordres à notre ordinateur. Ces ordres vont permettre à notre ordinateur de faire ce qu’on veut. Notre ordinateur peut manipuler un peu de tout : du texte, de la vidéo, des nombres, etc. Les ordres qu’on va donner à notre ordinateur vont ainsi lui permettre de manipuler de l’information sous différentes formes, plus ou moins variées. À ce stade du tutoriel, on sait que ces ordres, ces instructions sont effectués par notre processeur. Mais on ne sait rien sur la façon dont notre ordinateur fait pour maintenir ces informations, ni sur comment les utiliser dans notre langage C. De même, on ne sait pas comment donner des ordres à notre ordinateur, pour qu’il fasse ce qu’on lui demande.

Ce chapitre va pallier ce problème : il vous expliquera comment manipuler les types de données les plus simples disponibles en langage C. Ceux-ci ne sont autre que des nombres et des lettres. Ils sont manipulables grâce à ce qu’on appelle des variables, qui sont l’objet de ce chapitre. Après ce chapitre, vous saurez notamment comment manipuler des nombres et des lettres en langage C. Vous pourrez ainsi profiter de votre ordinateur comme s’il s’agissait d'une grosse calculette, bien plus rapide et puissante. Néanmoins, rassurez-vous ; le niveau en maths de ce chapitre sera très très faible : si vous savez compter, vous pourrez comprendre le chapitre facilement !

Cela peut paraitre simple, et pas très intéressant. Mais il faut bien commencer par les bases, comme la manipulation de données simples : manipuler du texte ou de la vidéo est complexe, et nécessite en plus de savoir comment manipuler des nombres. Eh oui ! Comme vous allez le voir, tout est nombre pour notre ordinateur, même le texte, et même la vidéo.

Qu’est-ce qu’une variable ?

Pour comprendre ce qu’est une variable, et comment manipuler celles-ci, il faut commencer par comprendre comment notre ordinateur fait pour stocker ces informations de base. Notre ordinateur a été conçu pour être assez polyvalent : il peut en théorie stocker tout type d’informations. Pour ce faire, celui-ci utilise une ruse particulièrement simple : il stocke ses informations en les découpant en petites unités d’information qu’on appelle des bits. Ces bits sont donc des unités très simples qui ne peuvent prendre deux valeurs : 0 ou 1.

Pour stocker des informations, il suffit de prendre plusieurs de ces bits et de les regrouper les uns à côté des autres. En faisant ainsi, on peut créer des suites de 0 et de 1 qui peuvent s’interpréter comme des nombres. On peut ainsi représenter des nombres positifs, des nombres négatifs, des nombres à virgule, etc. Tout ce que peut faire notre ordinateur, c’est manipuler ces suites de bits, ces nombres. En somme, notre ordinateur n’est qu’une grosse calculatrice.

Les informations plus complexes, comme de la vidéo, du texte, etc. sont toutes stockées dans notre ordinateur sous la forme de nombres. En utilisant plusieurs de ces bits, on peut ainsi représenter n’importe quoi : du texte, des nombres, de la vidéo, etc. Je suppose qu’il sera difficile de me croire, mais sachez tout de même que toute information qu’on trouve dans notre ordinateur est représentée avec seulement des 0 et des 1 !

Mémoire

Ces bits sont stockés dans un composant électronique particulier, présent das notre ordinateur : la mémoire. Son rôle : stocker tous les bits qui permettent de représenter nos informations.

Enfin, je dis « la mémoire », mais en fait il y en a plusieurs. Tout comme un humain possède plusieurs mémoires (mémoire à court terme, mémoire à long terme, etc.) qui lui servent à mémoriser plein d’informations, l’ordinateur se sert aussi de plusieurs mémoires pour stocker tout un tas de données de différentes tailles.

Mais pourquoi plusieurs mémoires et pas une seule ?

Le fait est que si l’on souhaitait utiliser une seule grosse mémoire dans notre ordinateur, celle-ci serait donc fatalement très lente : il est impossible de créer des mémoires qui soient à la fois rapides et qui puissent contenir beaucoup de données. On ne peut donc utiliser une seule grosse mémoire capable de stocker toutes les données dont on a besoin. Ce problème s’est posé dès les débuts de l’informatique. Les inventeurs des premiers ordinateurs modernes furent rapidement confrontés à ce problème. Pour ceux qui ne me croient pas, regardez un peu cette citation des années 1940, provenant d’un rapport de recherche portant sur un des premiers ordinateurs existant au monde :

   Idéalement, nous désirerions une mémoire d’une capacité indéfiniment large telle que n’importe quelle donnée soit immédiatement accessible. Nous sommes forcés de reconnaître la possibilité de la construction d’une hiérarchie de mémoire, chacune ayant une capacité plus importante que la précédente, mais accessible moins rapidement.

Comme on le voit, cette citation (traduite de l’anglais) montre le problème, mais évoque aussi la solution adoptée face à ce problème. Pour résoudre ce problème, il suffit de segmenter la mémoire de l’ordinateur en plusieurs sous-mémoires, de taille et de vitesse différentes qu’on utilise suivant les besoins. On aura donc des mémoires pouvant contenir peu de données dans lesquelles on pourra lire et écrire rapidement et des mémoires plus importantes, mais plus lentes. Cette solution a été la première solution inventée pour résoudre ce problème et est encore massivement utilisée à l’heure actuelle : on n’a pas encore fait mieux !

Nous avons dit que l’ordinateur utilisait plusieurs mémoires. Et il faut savoir que trois de ces mémoires sont importantes, et doivent être connues de tout programmeur. Je vous présente donc :

  • les registres ;
  • la RAM ;
  • le disque dur.

Alors évidemment, ce ne sont pas les seules : on pourrait aussi citer la mémoire cache et d’autres encore, mais cela n’a rien à faire dans un tutoriel sur le C. Et puis il y a déjà des cours à ce sujet sur le Site du Zéro, citons par exemple Fonctionnement d'un ordinateur depuis zéro.

Les registres sont des mémoires intégrées dans notre processeur. Elles sont très rapides, mais ne peuvent contenir que des données très simples : on peut difficilement mettre plus qu’un nombre dedans. Leur utilité est de stocker des données temporaires afin d’y accéder plus rapidement.

La mémoire RAM est une mémoire un peu plus grosse, et plus lente que les registres. Elle peut contenir pas mal de données, et on l’utilise généralement pour stocker le programme qu’on vient de lancer, ainsi que les données qu’il va manipuler.

Cette mémoire a tout de même un léger défaut : elle perd son contenu quand on coupe le courant. Autant dire qu’on doit trouver une autre mémoire pour stocker notre système d’exploitation, nos programmes, etc. : c’est le rôle du disque dur, une mémoire très grosse, mais très lente.

En C, la mémoire la plus utilisée est la mémoire vive. Et donc, pour bien comprendre comment programmer en C, il faudra comprendre comment interagir avec cette mémoire RAM. Plus loin dans ce cours, nous verrons également comment manipuler des fichiers sur le disque dur. Mais pour ce qui est des registres, c’est autre chose : le C cache presque totalement la gestion de ceux-ci, qui est réalisée presque entièrement par le compilateur. Impossible de les manipuler directement !

La RAM

Hé, une minute : si je stocke une donnée dans ma mémoire, comment je fais pour la récupérer ?

Eh bien dans ce cas-là, vous n’avez pas trop le choix : vous devez savoir où se trouve votre donnée dans la mémoire de l’ordinateur. Généralement, cette donnée se trouvera en mémoire RAM. On peut bien sûr copier notre donnée dans un registre, ou sur le disque dur, mais passons. Et pour retrouver notre donnée en RAM, rien de plus simple.

Bytes et octets

Dans notre RAM, les bits sont regroupés en « paquets » contenant une quantité fixe de bits : des « cases mémoires », aussi appelées bytes. Généralement, nos mémoires utilisent des bytes de 8 bits. Autrefois, certaines mémoires avaient des bytes de 6 ou 5 bits, parfois plus. Mais maintenant, la situation s’est un peu normalisée et la grande majorité des mémoires utilisent des bytes de 8 bits. Un groupe de 8 bits s’appelle un octet.

Avec un octet, on peut stocker 256 informations différentes. Par exemple, on peut stocker 256 nombres différents. On peut stocker les lettres de l’alphabet, ainsi que les symboles alphanumériques. On peut aussi stocker tous les nombres de 0 à 255, ou de -128 à 127, tout dépend de comment on s’y prend.

Pour stocker plus d’informations (par exemple les nombres de -1024 à 1023), on peut utiliser plusieurs octets, et répartir nos informations dedans. Nos données peuvent prendre un ou plusieurs octets qui se suivent en mémoire, sans que cela pose problème : nos mémoires et nos processeurs sont conçus pour gérer ce genre de situations facilement. En effet, nos processeurs peuvent parfaitement aller lire 1, 2, 3, 4, etc. octets consécutifs d’un seul coup sans problème, et les manipuler en une seule fois.

Adresse mémoire

Chacun de ces octets se voit attribuer un nombre unique, l’adresse, qui va permettre de la sélectionner et de l’identifier celle-ci parmi toutes les autres. Il faut imaginer la mémoire RAM de l’ordinateur comme une immense armoire, qui contiendrait beaucoup de tiroirs (les cases mémoires) pouvant chacun contenir un octet. Chaque tiroir se voit attribuer un numéro pour le reconnaitre parmi tous les autres. On pourra ainsi dire : je veux le contenu du tiroir numéro 27 ! Pour la mémoire c’est pareil. Chaque case mémoire a un numéro : son adresse.

En fait, on peut comparer une adresse à un numéro de téléphone (ou à une adresse d’appartement) : chacun de vos correspondants a un numéro de téléphone et vous savez que pour appeler telle personne, vous devez composer tel numéro. Les adresses mémoires fonctionnent exactement de la même façon !

 
MemoryAccess

Références

Pour retrouver votre donnée dans la RAM, on doit donc simplement préciser son adresse. Ce principe peut se généraliser aux autres mémoires : on doit fournir ce qu’on appelle une référence, qui permet d’identifier la localisation de notre donnée dans la mémoire : dans quel registre elle est (l’« adresse » du registre est alors ce qu’on appelle un nom de registre), à quel endroit sur le disque dur, etc. Ainsi, toute donnée est identifiée dans notre ordinateur par une référence, qui permet d’accéder à notre donnée plus ou moins directement. Notre adresse n’est donc qu’un cas particulier de référence, cette notion étant plus générale.

Manipuler nos données se fait alors via des références, plus ou moins compliquées, qui peuvent permettre de calculer l’adresse de notre donnée, et déterminer si elle est dans un registre, la RAM, le disque dur, etc.

Variables

Le seul problème, c’est que manipuler explicitement des références est un vrai calvaire. Si vous ne me croyez pas, essayez de programmer en assembleur, le seul langage dans lequel on doit manipuler des références explicitement. C'est une horreur. Mais rassurez-vous : on a moyen de se passer de ce genre de choses. Pour ce faire, on peut décider de camoufler ces références plus ou moins efficacement. Pour cela, on peut décider de remplacer ces références par autre chose.

Dans nos langages de programmation, et notamment dans le langage C, on remplace des références par des variables. Cette variable correspondra à une portion de mémoire, appelée objet, à laquelle on donnera un nom. Ce nom permettra d’identifier notre variable, tout comme une référence permet d’identifier une portion de mémoire parmi toutes les autres. On va ainsi pouvoir nommer les données qu’on manipule, chacun de ces noms étant remplacés par le compilateur en référence vers un registre ou vers une adresse mémoire.

Déclarer une variable