Bienvenue dans notre monde!!!!

Programmation en language C

 

INTRODUCTION

 D.Ritchie et B.W.Kernighan se sont inspirés des langages B et BCPL, pour créer un nouveau langage : le langage C dont le but était de permettre de développer un langage qui permettrait d'obtenir un système d'exploitation de type UNIXportable. Le langage C comporte beaucoup de caractériqtiques qu'il permet d'être le langage le plus utilisé :

- La portabilité : Un programme écrit en C peut être compiler sur n'importe quel sytème d'expoitation sans modifications (Windows, Linux, Unix, OS/390..) à condition qu'il soit mis au règles l'ANSI (abréviation de American National Standards Institute).

- Rapidité : Les programmes écrits en C sont très rapides du fait de la puissance du compilateur qui ne vérifie pas les adresses mémoires, les pointeurs.. En considérant que le developpeur sait ce qu'il fait.

- Taille plus compact : Les programmes écrits en C sont moins lourds par rapport aux programmes écrits aux autres langages.

- faiblement  typé : Le langage C ne manipule que peu de types données.

- Facile à apprendre : Au contraire à beaucoup de gens qui disent que le langage C est difficile, le langage C dispose que de peu d'instructions et les structures de données sont limités... L'apprentissage du langage C est plus facile que l'apprentissage du Fortran, ADA ou le pascal ..

Le compilateur :

Les compilateurs C  font subir deux transformations aux programmes:

1. un préprocesseur fait subir au texte des transformations d'ordre purement lexical.

2. le compilateur proprement dit prend le texte généré par le préprocesseur et le traduit en instructions machine.

Le but du préprocesseur est de rendre des services du type traitement de macros et compilation conditionnelle.

Les types de base :

Les caractères :

Le mot clé désignant les caractères est char. char est le type dont l'ensemble des valeurs est l'ensemble des valeurs entières formant le code des caractères utilisé sur la machine cible.

Les entiers :

Le mot clé désignant les entiers est int. Les entiers peuvent être affectés de deux types d'attributs : un attribut de précision et un attribut de représentation. Les attributs de précision sont short et long.

Les fottants :

Les flottants peuvent être en simple ou en double précision. Le mot clé désignant les flottants simple précision est float, et celui désignant les flottants double précision est double. La précision effectivement utilisée pour ces deux types dépend de l'implémentation.

Les constantes :

Les constantes entières : On dispose de 3 notations pour les constantes entières: décimale, octale et hexadécimale.

Les constantes caractères : La valeur d'une constante caractère est la valeur numérique du caractère dans le code de la machine.

Les constantes flottantes : La notation utilisée est la notation classique par mantisse et exposant. Pour introduire l'exposant, on peut utiliser la lettre e sous forme minuscule ou majuscule.

Les constantes nommées :

Il n'y a pas en C de possibilité de donner un nom  a une constante. On peut cependant réaliser un effet  equivalent grâce au préprocesseur. Lorsque le préprocesseur lit une ligne du type:

#define identificateur reste-de-la-ligne

il remplace dans toute la suite du source, toute nouvelle occurence de identificateur par reste-de-la-ligne.

 

LES FONCTIONS

Une fonction est une portion de programme formant un tout homogène, destiné à remplir une certaine tâche bien délimitée.

Lorsqu’un programme contient plusieurs fonctions, l’ordre dans lequel elles sont écrites est indifférent, mais elles doivent être indépendantes.

En règle générale, une fonction appelée a pour rôle de traiter les informations qui lui sont passées depuis le point d’appel et de retourner une valeur. La transmission de ces informations se fait au moyen d’identificateurs spécifiques appelés arguments et la remontée du résultat par l’instruction return.

Certaines fonctions reçoivent des informations mais ne retournent rien (par exemple printf), certaines autres peuvent retourner un ensemble de valeurs (par exemple scanf).

Définition de fonction :

· La définition d’une fonction repose sur trois éléments :

¨ Son type de retour

¨ La déclaration de ses arguments formels

¨ Son corps

· De façon générale, la définition d’une fonction commence donc par :

type_retour nom (type-arg-f1 arg-f1, type-arg-f2 arg-f2 ...)

· Les arguments formels permettent le transfert d’informations entre la partie appelante du programme et la fonctions. Ils sont locaux à la fonction, et lors de l’appel ils seront mis en correspondance avec les arguments effectifs.

· Contrairement à d’autres langages, le C ne permet pas la modification. Le seul mode de passage des paramètres est le mode par valeur. Cela signifie que « les valeurs des paramètres effectifs sont copiées dans les paramètres formels ».

· L’information retournée par une fonction au programme appelant est transmise au moyen de l’instruction return, dont le rôle est également de rendre le contrôle de l’exécution du programme au point où a été

· La syntaxe générale de la fonction return est la suivante :

return expression ;

Déclaration de fonction :

· Lorsque l’appel d’une fonction figure avant sa définition, la fonction appelante doit contenir une déclaration de la fonction appelée. On appelle cela prototype de la fonction.

· Attention a ne pas confondre définition et déclaration de fonctions. La déclaration est une indication pour le compilateur quant au type de résultat renvoyé par la fonction et éventuellement au type des arguments, et rien de plus.

· Dans sa forme la plus simple la déclaration d’une fonction :

type_de_retour nom () ;

 

EXPRESSIONS ET OPERATEURS

Les opérateurs relationnels :

Les principaux opérateurs relationnels sont :

· ==égalité (<> de l'affectation)

· != différence

· > supérieur

· >= Supérieur ou égal

· < Inférieur

· <= Inférieur ou égal

Les 2 opérandes doivent avoir le même type arithmétique. Si ce n'est pas le cas, des conversions sont effectuées automatiquement selon les ð Le type BOOLEEN n'existe pas explicitement en C : les opérateurs de relation fournissent les valeurs 0 ou 1 (respectivement FAUX et VRAI) du type int.

En C, on peut écrire A < B < C car cette expression correspond à (A < B) < C ce qui n'est probablement pas le résultat escompté par le programmeur : En effet si A < B, l'expression équivaut à 1 < C et sinon

Les opérateurs logiques :

Les principaux opérateurs logiques sont :

· ! Négation unaire d'une valeur logique

· && ET de 2 valeurs logiques

· || OU de 2 valeurs logiques

Ces opérateurs interviennent sur des valeurs de type int : la valeur 0 est considérée comme la valeur FAUX; toutes les autres valeurs comme la valeur VRAI.

Les valeurs produites sont 0 (FAUX) ou 1 (VRAI) du type int.

Les opérateurs && et || impliquent l'évaluation de l'opérande gauche avant celle de droite.

L'opérande de droite peut ne pas être évalué si la valeur obtenue à partir de l'opérande de gauche suffit à déterminer le résultat :

· 0 pour l'opérande gauche de l'opérateur && implique FAUX

· 1 pour l'opérande gauche de l'opérateur || implique VRAI

int Tab[10];

Soit le test : (k < 10) && (Tab[k] != v)

Si k est supérieur ou égal à 10 ,l'expression (Tab[k] != v) ne sera pas évaluée et il vaut mieux car pour k est supérieur ou égal à 10 Tab[k].

Priorités des opérateurs :

Lors de l'évaluation des expressions, certaines règles sont appliquées systématiquement par le compilateur. Le programmeur doit donc en tenir compte lors de l'écriture d'un programme.

· Les opérateurs les plus prioritaires sont appliqués en premier.

· Les opérateurs de même priorité sont appliqués de la gauche vers la droite.

· Si des sous-expressions parenthèsées sont présentes, les opérateurs présents dans celles-ci sont appliqués en premier.

L'ordre des priorités des opérateurs est le suivant :

· ! - (opérateurs unaires)

· * / %

· + -

· < <= >= >

· == !=

· &&

· ||

Ainsi A + B * C est évalué comme A + (B * C) .

Attention, tout programme qui dépend de l'ordre d'évaluation des opérandes doit être considéré comme incorrect, car pour la plupart des opérateurs il n'existe aucune règle et cela dépend du compilateur.

 

LES PRINCIPALES INSTRUCTIONS

Une instruction simple est une expression suivie d'un ; qui fait partie de l'instruction (ce n'est pas un séparateur comme en Pascal).

Une instruction composée est une suite d'instructions encadrée par {et}. Une instruction composée peut se mettre partout où l'on peut mettre une instruction.

if :

syntaxe : if (expression) instruction

· si expression est vraie (<> 0) instruction est exécutée

if ... else :

Syntaxe : if (expression) instruction1 else instruction2

· instruction1 et instruction2 sont des instructions simples (penser au ; (<> Pascal)), ou des instructions composées.

while :

Syntaxe : while (expression) instruction

· instruction est une instruction simple ou compos

Il est fréquent en C de voir une partie du travail ou la totalité reportée dans l'expression :

· while ((c=getchar())!= EOF)

putchar(c) ;

· while (s[i++]) ;

for :

Syntaxe : for ( expression1 ; expression2 ; expression3) instruction

· instruction est une instruction simple ou composée.

· expression1 sert à initialiser

· expression2 est la condition de rebouclage

· expression3 est l'expression d'incrémentation

Le for du C est un tantque traditionnel des autres langages. il peut dans la plupart1 des cas être réécrit de la façon suivante :

expression1

while (expression2)

{ instruction

expression3; }

Les expressions peuvent comporter plusieurs instructions

char s[]="Bonjour Tout le monde";

int c,i,j;

for ( i=0, j=strlen(s)-1 ; i

c=s[i] ; s[i]=s[j] ; s[j]=c ;}

do ... while :

Syntaxe : do instruction while (expression) ;

Ceci est équivalent à instruction

while (expression) instruction

Lorsque instruction est un bloc d'instructions simples, mettre {}

break :

Cette instruction provoque la fin de l'instruction switch, while, do ou for qui la contient. (au premier niveau). Elle est à utiliser avec précaution et devra toujours être justifiée par des commentaires, comme toute autre instruction de rupture.

continue :

Elle a pour but de provoquer le rebouclage immédiat de la boucle do, while ou for qui la contient.

Dans le cas d'un for (e1;e2;e3), e3 est évaluée avant le rebouclage. C'est pour cette raison que l'équivalence entre le for et le while n'est pas totale.

return :

L'exécution de la fonction qui contient le return est interrompu, le contrôle est rendu

return expression :

Idem avec une valeur de retour égale à l'évaluation de expression.

switch :

syntaxe : switch (expression) {

case c1 : instructions

....

default : instructions }

L'expression et les différentes constantes (ci) doivent êtres de type entiers. C'est différent du case Pascal.

 

LES POINTEURS ET LES TABLEAUX

Un pointeur, en C comme en PASCAL, est une adresse permettant de désigner un objet (une variable ou une fonction) en mémoire centrale.

Par extension, on appelle pointeur la variable qui contient cette adresse.

Pointeurs et adresses :

Un pointeur définissant l'adresse d'un objet, l'accès à cet objet peut alors être réalisé par une indirection sur le pointeur.

· L'opérateur unaire & fournit l'adresse de l'objet opérande (qui doit donc être une value2). On dit aussi que cet opérateur est l'opérateur de .

· L'opérateur unaire * considère son opérande comme un pointeur et retourne l'objet pointé par celui-ci. On dit aussi que cet opérateur est l'opérateur d'indirection.

Exemples :

int X, Y;

/* Soit PX un pointeur sur des int */

PX = &X; /* PX <- l'adresse de X */

Y = *PX; /* Y <- l'objet pointé par PX (ie X) */

Ceci équivaut donc à : Y = X;

Opérations sur les pointeurs :

La valeur NULL, est une valeur de pointeur, constante et prédéfinie dans stddef.h. Elle vaut 0 et signifie "Aucun objet". Cette valeur peut être affectée à tout pointeur, quel que soit son type.

· En ce cas, ce pointeur ne pointe sur rien...

· Bien entendu, l'utilisation de cette valeur dans une indirection provoquera une erreur d'exécution.

L'affectation d'un pointeur à un autre n'est autorisée que si les 2 pointeurs pointent le même type d'objet (ie ont le même type).

Exemple :

P = NULL;

P = Q; /* P et Q sont de pointeurs sur le même type */

P = 0177300; /* illégal */

P = (int *) 0177300; /* légal */

L'incrémentation d'un pointeur par un entier n est autorisée. Elle ne signifie surtout pas que l'adresse contenue dans le pointeur est incrémentée de n car alors cette adresse pourrait désigner une information non cohérente : être à cheval sur 2 mots par exemple...

L'incrémentation d'un pointeur tient compte du type des objets pointés par celui-ci : elle signifie "passe à l'objet du type pointé qui suit immédiatement en mémoire". Ceci revient donc à augmenter l'adresse contenue dans le pointeur par la taille des objets.

Comparaison de pointeurs :

Il est possible de comparer des pointeurs à l'aide des relations habituelles : < <= > >= == !=

Un pointeur peut être comparé à la valeur NULL.

Soustraction de pointeurs :

La différence de 2 pointeurs est possible, pourvu qu'ils pointent sur le même type d'objets. Cette différence fournira le nombre d'unités de type pointé, placées entre les adresses définies par ces 2 pointeurs.

Pointeurs et tableaux :

On rappelle que la déclaration d'un tableau dans la langage C est de la forme : int Tab[10];

En fait, cette déclaration est du "sucre syntaxique" donné au programmeur. En effet, de façon interne, elle entraine :

· La définition d'une valeur de pointeur sur le type des éléments du tableau, cette valeur est désignée par le nom même du tableau (Ici Tab)

· La réservation de la place mémoire nécessaire au 10 éléments du tableau, alloués consécutivement. L'adresse du premier élément (Tab[0]) définit la valeur du pointeur Tab.

Exemple !int *Ptab, Tab[10];

POINTEURS ET TABLEAUX MULTIDIMENSIONNELS

Un tableau unidimensionnel peut se représenter grâce à un pointeur (le nom du tableau) et un décalage (l’indice). Un tableau à plusieurs dimensions peut se représenter à l'aide d'une notation similaire, construite avec des pointeurs.

Par exemple, un tableau de dimension 2, est en fait un ensemble de deux tableaux à une seule dimension. Il est ainsi possible de considérer ce tableau à deux dimensions comme un pointeur vers un groupe de tableaux unidimensionnels consécutifs. La déclaration correspondante pourra s’écrire de la manière suivante:

type-donnée (*varpt)[expression 2];

au lieu de la déclaration classique:

type-donnée tableau [expression l][expression 2];

 

 

PRATIQUER

https://www.elektronique.fr/langage-c/langage-c-telecharger.php

© 2009 Tous droits réservés.

Créer un site internet gratuitWebnode