• Aucun résultat trouvé

     Cours Langage C

N/A
N/A
Protected

Academic year: 2022

Partager "     Cours Langage C"

Copied!
217
0
0

Texte intégral

(1)

Types de données et représentation

Langage C

B. Rouzeyre, Polytech'ERII

(2)

1. Action de base 2. Séquencement

3. Bloc et niveau de détail

Représentation des algorithmes

Organigramme : façon graphique de représenter le déroulement d'un calcul

Action 1

Action 1 Action 2

Action 12 Action 11 Action 1

Action 2

(3)

4. Sélection

Organigramme

Non structuré

Action 23 Action 22 Action 21 Action 1

Action 3

Action 23 Action 22

Action 21

Action 1

Action 3 Critère ?

Ev.1

Ev.3 Ev.2

Ev.1 Ev.2 Ev.3

Σ Evi = 1 et Evi.Evj = 0

Structuré

Se lit de haut en bas et de gauche à droite Se lit en suivant les fils

(4)

4. Cas particulier : alternative

Organigramme

Non structuré

Action 22 Action 21 Action 1

Action 3

Action 22 Action 21

Action 1

Action 3 Critère ?

Vrai

Faux Vrai Faux

Structuré

(5)

4. Cas particulier : alternative sans action

Organigramme

Non structuré

Action 21 Action 1

Action 3

Action 21

Action 1

Action 3 Critère ?

Vrai

Faux Vrai Faux

Structuré

(6)

5. Itérations : exprime le fait que l'on répète une action

Organigramme

Action 2 Action 1

Action 3

Action 3 Action 2

Action 1

Critère

5.1 "Tant que"

Vrai Faux

1 – On évalue le critère

2 – s'il est vrai on effectue l'action 2, retour en 1 2 bis – s'il est faux on passe à la suite

Remarque : éventuellement l'action 2 n'est pas exécutée

(7)

5. Itérations :

Organigramme

Action 2 Action 1

Action 3

Action 3 Action 2

Action 1

Critère

5.2 "Jusqu'à ce que"

Faux Vrai

1 – On exécute l'action 2 2 – s'il est faux, retour en 1

2 bis – s'il est vrai, on passe à la suite

Remarque : l'action 2 est exécutée au moins une fois

(8)

5. Itérations :

Organigramme

Action 2 Action 1

Action 3

5.3 "Pour tout e ε E"

l'action 2 est exécutée autant de fois qu'il y a d'éléments dans E.

Remarque : si E est vide, Action 2 n'est pas exécutée.

Action 3 Action 2

Action 1

e ε E ?

Vrai Faux

e <- valeur suivante de E

(9)

-utiliser que les primitives précédentes -intérêt : traduction (presque) directe en C -ne pas faire de spaghetti :

- traduction difficile - debug impossible - résultat incompréhensible - => 0 à l'examen

Organigramme : conseil

Action 3 Action 2

Action 1

e ε E ?

Vrai Faux

e <- valeur suivante de E

(10)

Organigramme : exemple

Imprimer S S=0

x pair ?

x=

suivant(x)

x = premier

x dernier ?

S=0 x = premier

Imprimer S S = S+ x

Vrai Faux

fin = v

x= suivant(x) fin = faux

S = S+ x

KO OK

(11)

• Les actions ou "instructions" en langage C ne sont en fait que des opérations élémentaires (+,-, * etc…) sur des données unitaires.

• Chaque instruction est suivie d'un ;

• Le début d'un bloc est signalé par un { , la fin d'un bloc par }. Un bloc devient l'équivalent syntaxique d'une instruction.

• Ex :

Codage d'un algorithme en C

Calcul

x = 1 y = 2

imprimer z z = x+y

{

x=1;

y=2;

z=x+y;

printf("%d",z);

} ;

optionnel

(12)

Alternative

if (expression) action1 ; else action2 ;

Codage d'un algorithme en C

"problème"

calcul

Imprimer z

Vrai

Faux

"calcul juste"

z = z+10

if (z == 3) {

printf("calcul juste");

z=z+10;

} ;

else printf ("problème");

printf ("%d",z);

fin de l'instruction if

(13)

Cas particuliers de alternative

Codage d'un algorithme en C

if (z == 3) ;

else printf("problème);

printf ("%d",z);

"problème"

calcul

Imprimer z

Vrai

Faux

(14)

Cas particuliers de alternative

Codage d'un algorithme en C

calcul

Imprimer z

Vrai

Faux

"calcul juste"

z = z+10

if (z == 3) {

printf("calcul juste");

z=z+10;

} ; else;

printf ("%d",z);

ou bien

if (z == 3) {

printf("calcul juste");

z=z+10;

};

printf ("%d",z);

(15)

Sélection multiple : en C, la sélection ne peut être qu'une comparaison à des valeurs de constante entière ou caractère (si besoin passer à plusieurs if imbriqués)

Codage d'un algorithme en C

switch (z) {

case 3 : printf("ok"); break;

case 4 : printf("PB1"); break;

default : "printf ("PB2");

};

"PB2"

"PB1"

"ok"

Action 1

Action 3

z=3

autres z=4

(16)

Structures itératives. Exemple, on veut imprimer tous les nombres de 1 à 10 TANT QUE : while (condition) action;

Codage d'un algorithme en C

x=1;

while (x <=10) {

printf("%d\n",x);

x=x+1;

};

x=1

imprimer x x=x+1

x=1

imprimer x x=x+1

x=1;

do {

printf("%d\n",x);

x=x+1;

}

while (x <= 11);

JUSQU'À CE QUE : do action while (condition);

(17)

POUR

Codage d'un algorithme en C

for(x=1; x≤10; x=x+1) printf("%d\n",x);

imprimer x

équivalent TANT QUE

x=1;

while (x <=10) {

printf("%d\n",x);

x=x+1;

};

x=1

imprimer x x=x+1

(18)

Compilateurs

• Sur le web

– ideone.com (pour le début)

• En TP

– Visual C++

(19)

Types de données

• 3 types de base

caractères

ex : 'a', '1', '\n'

entier relatifs

ex : 0 , -12, 328

réel

3.14, 2.3 e+4

• Remarques :

Pas de booléen (vrai, faux)

Pas de type chaînes de caractères prédéfini

(20)

Type caractère

Caractère : Symboles alphanumériques (a,z,!,1,9) + caractères spéciaux (retour à la ligne, beep, etc..)

Un caractère est représenté sur un octet (8 bits) suivant la table ASCII (American Standard Code for Information Interchange)

ex : 'a' = 9710 = 6116 = 0110 00012

Table ASCII

ex : code ASCII du 'A' = 65 'A'<'B'<……..< 'Z'

'0'<'1'<'2'<…..<'9' 'a'<'b'<……….<'z'

Déclaration de variable de type caractère

char c;

c = 'a';

Constante de type caractère

#define caractère_a 'a'

(21)
(22)

Table ASCII

• Remarques :

les chiffres sont codés suivant un ordre croissant (48 à 57) idem pour les lettres (65 à 90, 97 à 122)

code des majuscules est inférieur au code des majuscules (différence constante = 32)

les codes supérieurs à 128 dépendent de la langue : é, ö , ä, æ, œ etc

• Déclaration d'une variable caractère :

char c;

c='a';

…..

(23)

Type caractère

• Caractères spéciaux (retour à la ligne, tabulation etc..)

• Exemple :

retour à la ligne = CR = code ASCII 13 char retour;

retour = 13; ou bien retour = '\n';

• Conventions

\n : retour à la ligne

\t : tabulation

\f : nouvelle page

\' : apostrophe

\0 : caractère nul (indique la fin d'une chaîne de caractères)

(24)

Les entiers : entiers naturels

Codage sur 2 ou 4 octets suivant le calculateur

Sur deux octets on peut coder les nombres de 0 à 216-1 (0 à 65535)

Nombre représenté en base 2, les bits sont rangés dans des cellules correspondant à leur poids, on complète à gauche par des 0

Exemple :

13 = 8 + 4 +1 = 1*23+1*22+0*21+1*20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1

Déclaration d'une variable entier naturel x

unsigned int x;

short unsigned int x; (on force sur 16 bits) long unsigned int x; (on force sur 32 bits)

  0 , 1 , n 16 ou 32

, 2

1 0

 

i

n i i

i

x

x

x

(25)

Type entier relatif

• Implantation sur 2 ou 4 octets suivant le compilateur

• Représentation sur n bits : codage complément à 2

• Déclarations

int a,b;

….

a = 1;

….

b= 3;

  0 , 1

, 2

2

2

0 1

1

 

 

  i

n i i

i n

n

x x

x

x

(26)

Type entier relatif

• Codage complément à 2

• Si xn-1 = 0 : nombre positif, xn-1 = 1 : nombre négatif

• Exemple sur 16 bits

+5 = 1 * 22 + 0 * 21 + 1 * 20 = 0000 0000 0000 0101 -3 = -32768 + 32765

= -215+ 214 + 213 + 212 + 211 + 210 + 29 + 28 + 27 + 26 + 25 + 24 + 23 + 1.22 + 0.

21 + 1.20

= 1111 1111 1111 1101

• Sur 16 bits (2 octets)

-32768  x  32767

• Sur 32 bits

-2147483648  x  2147483647

  0 , 1

, 2

2

2

0 1

1

 

 

i

n i i

i n

n

x x

x

x

(27)

Complément à 2

• Représentation non symétrique : le plus petit nombre n'a pas d'opposé : sur n bits

• le plus grand entier positif est 2

n-1

-1

• le plus petit entier négatif est -2

n-1

• exemple sur 3 bits :

000

100 110 010

001

011 101

111 0

1

2 3 -3 -4

-2 -1

(28)

Codage complément à 2

• Remarques

1/ Complément à 2 de x = Complément à 1 de x + 1 représentation de –3 ?

3 = 0000 0000 0000 0011 c1(3) = 1111 1111 1111 1100 +1 = 0000 0000 0000 0001 c1(3) +1= 1111 1111 1111 1101 2/ Représentation 16 bits = > 32 bits

x >0 = 0000 0000 0000 0011 => x = 0000 0000 0000 0000 0000 0000 0000 0011 x <0 = 1111 1111 1111 1101 => x = 1111 1111 1111 1111 1111 1111 1111 1101

• Extensions

int 2 ou 4 octets ? problème de portabilité short int x; 2 octets

long int x ; 4 octets

unsigned int x ; bit de signe utilisé pour la valeur unsigned short int x ;

unsigned long int x ;

(29)

Type réel

• Déclaration

float x,y;

x = 3.14;

y = 2.0 e+3;

• Implantation sur 4 octets

• Représentation suivant le compilateur

en général mantisse exposant (norme IEEE)

• 10

-38

< x < 10

38

• Extension :

double x; x est codé sur 8 octets

(30)

Nombre réels

• Codage des réels : virgule flottante, Norme IEEE

• flottant stocké sous la forme M * B

E

M : Mantisse ; B : Base ; E : Exposant

• exemple : 123 . 10

3

= 123 000

• Représentation IEEE 754 (signe 1 bit, mantisse et exposant sur 32 ou 64 bits pour simple et double précision)

• SM : signe de la mantisse : 1 bit

• Eb : exposant biaisé : 8 ou 11 bits

• M : Mantisse : 23 ou 52 bits

SM Eb M

(31)

Mantisse et exposant

• Signe : bit de poids fort (0 = + ; 1 = -)

• Exposant

placé avant la mantisse pour simplifier les comparaisons (pour ceci il ne doit pas être représenté en complément à deux : -1 > 2)

sur 8 bits : 0..256

sans signe mais biaisé de 127 (simple précision) : Eb = 1 E = 1 – 127 = -126⇒

Eb = 254 E = 254 – 127 = 127⇒

les exposants 255 (erreur) et 0 (nb dénormalisé) sont interdits

• Mantisse

normalisée : bit de poids fort n’est pas 0 et un seul chiffre avant la virgule

• ex : 3,25

10

= 11,01

2

= 1,101 * 2

1

(32)

Virgule Flottante

• Comme le bit de poids fort de la mantisse est nécessairement 1 : on ne l’indique pas (gaspillage de place), il est implicite

• Mantisse

partie fractionnaire = f1f2 …fn m = 1,f1f2…fn nombre x = (-1)SM * 1,M * 2Eb-127

• Exemple

x = (-2,5)10 = -1,01*212 SM = 1 ;

E= 1 => Eb= 128 = 1000 0000 ; m=1,01 => M =010…….0

• Déclaration de variables réelles :

float x;

double y;

SM Eb M

f1,f2,……fn

(33)

Variables

• Variable : élément de mémorisation élémentaire

• Toutes les variables doivent être déclarées suivant un type

int a, b; ou bien int a;

int b;

float x;

char caractere;

• Identificateur de variables (noms)

Le premier caractères doit être une lettre

Les autres caractères sont les lettres (majuscules et minuscules), les chiffres et le caractère _

Majuscule / minuscule significatifs

• Exemples :

Pi, pi3_14, a2B3 : corrects 2x, i-E : incorrects A1  a1

(34)

Variables

• Exemple :

char a;

int un;

a = 'a';

un =1;

a = '1';

• Initialisation des variables

à l'exécution : int i;

….

i = 0;

à la compilation int i = 0;

(35)

Conversion de type

• Conversion explicite : ( type ) expression

Exemple :

int a; float x; char c;

a= 2;

x= (float) a;

x= 2.3;

a= (int) (x+1);

a = 98;

c = (char) a; -> c='b'

• Conversion implicite

Exemple :

int a; float x; char c;

a= 2;

x= a;

x= 2.3;

a= x+1;

a = 98;

c = a; -> c='b'

(36)

Conversion de types

• Exemples :

char c; int i; float f;

// conversion entier vers char.

c= 98; // implicite : c prend le code ASCII 98 c-à-d ’b' c = (char) 98; // explicite plus propre

// char vers entier

i= 'a' ; // i prend la valeur 97 i= (int) 'a' ; //plus propre

// entier vers réel

f= 3; // f prend la valeur 3.0;

f=(float) 3; //+ propre

//réel vers entier, attention : troncature i = 3.4; // i prend la valeur 3

i= -3.7; // i prend la valeur -3 i = (int) 3.4; // + propre

(37)

Conversion de types : application

• Passer au caractère suivant

char c;

c ='a';

c = c+1; // calcul fait en entier puis résultat converti en char c = (char) ((int) c+1) ; //+ propre

• Conversions majuscule<-> minuscule

char c;

c='t';

// conversion en Majuscule c=c-32; // c contient 'T' ou mieux

c=c-('a'-'A');

c=c+1; // c contient 'U' // conversion en minuscule c=c+32;

ou c=c+('a'-'A')

// conversion en Majuscule

if ((c >= 'a') && (c <= 'z')) c = c-('a'-'A');

(38)

Tableaux

• Lorsque on veut mémoriser plusieurs données de même type, on peut utiliser un tableau c-à-d on regroupe sous un même nom plusieurs informations

• Exemple de déclaration d'un tableau d'entiers

int tab[100];

int : type des éléments du tableau tab : identificateur (nom du tableau)

100 : nombre d'éléments du tableau (dimension)

tab peut recevoir 100 entiers indicés de 0 à 99 (attention !) le premier est tab[0]

le second tab[1]

..

le dernier tab [99]

(39)

Tableaux

• Utilisation

chaque élément du tableau est accessible par un indice qui doit être de type entier, quelque soit le type des éléments du tableau

exemples : int i ;

tab[2] 3eme élément du tableau tab[2+3] 6eme élément du tableau tab[i] i+1eme élément du tableau

• Exemples :

stocker les 100 premiers nombres pairs : 0,2,4,...,196,198 int i, t[100];

for (i=0; i < 100; i=i+1) t[i]= 2*i;

(40)

Tableaux

• Remarques:

1/ chaque élément du tableau s'utilise comme une variable tab[3] = 2;

2/ le nombre maximum d'éléments du tableau (dimension) 1/ doit être fixé à la compilation

2/ ne peut être modifié pendant l'exécution

3/ Pas d'opérations sur les tableaux en tant que tels

(41)

Parcours des éléments d’un tableau

Parcours du premier au dernier

int i; /* l’indice de balayage doit être un entier */

float t[100]; /* le type du tableau est quelconque, ici réel */

for (i=0; i < 100; i=i+1) // ou bien for (i=0; i <= 99; i=i+1) t[i]= …….;

Parcours du dernier au premier int i;

float t[100];

for (i=99; i >= 0; i=i-1) t[i]= …….;

(42)

La dimension

Bonne pratique de programmation int i;

int t[100];

for (i=0; i < 100; i=i+1) t[i]= 100;

Pb : modification du pgm, changement de la taille du tableau malaisée

#define TAILLE 100 int i;

int t[TAILLE];

for (i=0; i < TAILLE; i=i+1) t[i]= 100;

Il suffit de changer TAILLE

(43)

Exemples

Point de l'espace

1ere solution : float x,y,z;

2eme solution float pt[3];

pt[0] pour x, pt[1] pour y, pt[2] pour z

Mémorisation des 100 premiers nombres pairs et impairs:

int pairs[100], impairs[100];

int i;

for (i=0; i<100;i=i+1) { pairs[i]=2*i;

impairs[i]=2*i+1;

}

(44)

• En c, pas de type prédéfini chaîne de caractères. En pratique on utilise des tableaux de caractères.

• Convention : le dernier caractère utile est suivi du caractère

\0 (de code ascii 0)

• Exemples :

char t[10]; (9 caractères max, puisque une case réservée pour \0;

strcpy(t,"abcdefghi")

chaque lettre est accessible par l'indice char t[12];

strcpy(t,"abcdefghi");

• Initialisation

char t[10]= "abcdefghi"; ou char t[]= "abcdefghi";

• Constante chaîne de caractères

#define ceciestuntexte "azssddqsdqsd"

Chaînes de caractères

'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 0

'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 0 ? ?

(45)

Définitions de type utilisateur

typedef int entier; (entier est maintenant un type) entier i;

typedef int tableaude20[20];

tableaude20 t;  int t[20];

(46)

Les expressions en langage C

(47)

Expressions : introduction

• Remarque : expression  instruction

• une instruction indique à l'ordinateur de mener une action

• expression = élément syntaxique

• Expressions :

variable ou constante, ex : x, 3

constituées à l'aide d'opérateurs : x+ y

conversion de type, opérateurs arithmétiques, de taille, relationnels et logiques, affectation, bit-à-bit, conditionnels, adresse

(48)

Expressions

• Une expression représente une donnée élémentaire :

constante, variable, un élément de tableau, la référence à une fonction ou à une valeur, le résultat d'un calcul etc ….

• Exemples

3 a+b x=y

c = a+b x <= y x == y i++

sin(3.14)

• Toute expression a une valeur

(49)

Opérateurs arithmétiques

• Opérateurs bi-opérandes

+ , -

* , / , % (modulo)

Les opérandes doivent être des valeurs numériques.

entier opérateur entier -> résultat entier réel opérateur réel -> résultat réel entier opérateur réel -> résultat réel

• Exemples

int a,b;

a=10; b= 3

a+b 13

a-b 7

a*b 30

a/b 3 (division euclidienne)

a%b 1

float a,b;

a=12.6; b= 3.0

a+b 13.6

a-b 9.6

a*b 37.8

a/b 4.2 (division réelle) a%b erreur de syntaxe

(50)

Opérateurs arithmétiques

• Opérateur % :

- int a; flloat x;

(a+x) % 4 incorrect. ((int) (a+x))%4 correct

- si l'un des opérandes est négatif, le résultat est négatif.

• Si l'un des opérandes est de type caractère, c'est la valeur du code ASCII qui est prise (conversion implicite char vers int ou float)

• Conversion majuscule  minuscule

Exemple : char c = 'a';

c = c+1; => c = 'b' mécanisme :

c+1 = 98 + 1 =99

c = code ascii 99 = 'c'

Exemple : char c ;

if (c >= 'a' && c <='z') c = c-32 (ou bien c = c + 'A' –'a') if (c >= 'A' && c <='Z') c = c+32 (ou bien c = c - 'A' +'a')

(51)

Opérateurs arithmétiques

• Opérateurs unaires (un opérande)

a/ signe : + , - exemple : a = -a;

b/ incrémentation, décrémentation : ++ (+1) , -- (-1) exemple :

int i =1;

++i;

printf("%d",i) ; -> 2;

Syntaxes : ++i ou i++

++i : la valeur de i est d'abord incrémenté, la valeur résultat est utilisée dans l'expression courante

i++ : la valeur courante de i est utilisée dans l'expression courante, puis i est incrémenté

(52)

++ et --

• Exemples

i=1; i=1;

printf("i= %d\n",i); -> i=1 printf("i= %d\n",i); -> i=1 printf("i= %d\n",++i); -> i=2 printf("i= %d\n",i++); -> i=1 printf("i= %d\n",i); -> i=2 printf("i= %d\n",i); -> i=2

• Conclusions :

1/ appendre la règle (pour comprendre des programmes) 2/ à n'utiliser que lorsque il n'y a pas d'ambiguïté :

x=y+z++; // à éviter x++; // pas de risque

(53)

Opérateurs d'affectation

• Affectation simple

syntaxe : variable = expression

la valeur de l'expression est stockée dans la mémoire à l'endroit réservé pour la variable

Exemples :

a = 2; b=1; c=0;

a = b+c;

a = b && c;

la valeur de l'expression vaut la valeur affectée Attention : affectation et test d'égalité

if (a =1) instruction1; else instruction2;

L'instruction1 est toujours déclenchée.

a = b = 3; (évaluation de droite à gauche)

(54)

Opérateurs d'affectation

• Affectation et opération : +=, -=, *=, /=, %=,<<= , >>=, &=,

|=, ^=

Syntaxe : variable opérateur expression

équivalent à : variable = variable opérateur expression Exemple :

int i;

i= 3;

i+=2; // même chose que i=i+2;

printf("%d\n",i); -> 5

(55)

Opérateurs relationnels et logiques

Valeur logique :

0 : faux

 0 : vrai

exemple : if (3) traitement1 ; else traitement 2;

équivalent à : traitement1;

Relationnels : >= , > , == , <, <= , !=

La valeur de l'expression est 1 si l'expression est vraie , 0 si elle est fausse

Exemple : 2 < 3 vaut 1 , 2 > 3 vaut 0

Attention à la confusion : test d'égalité == et l'affectation =

ex : if (x=0) traitement 1; // au lieu de x==0 else traitement 2;

Conséquence: En cas d'erreur, non seulement le traitement 1 ne sera jamais exécuté mais en plus x vaudra 0 quelle que soit sa valeur initiale

Logiques : && "et" logique , || "ou" logique, ! "non" logique

Dans l'évaluation de l'expression, 0 est considéré comme la valeur logique "faux", toute valeur  0 comme la valeur logique "vraie"

La valeur de l'expression est 1 ou 0 Exemples:

2 && 0 vaut 0 et donc est faux 2 || 0 vaut 1 et donc est vrai !0 vaut 1 !4 vaut 0

(56)

Opérateurs bit à bit

• Opèrent sur les représentations des valeurs

• & et , | ou, ^ ou-exclusif, ~ complément à 1 ,

• << décalage à gauche, >> décalage à droite,

• Attention : &  &&

• Exemples

5 0000 0000 0000 0101

20 0000 0000 0001 0100

5 & 20 0000 0000 0000 0100 => 5 & 20 => 4 5 | 20 0000 0000 0001 0101 => 5 | 20 => 21 5 ^ 20 0000 0000 0001 0001 => 5 ^ 20 => 17

~5 1111 1111 1111 1010 => -6

• Affectation/bit-à-bit : &=, |=, ^=, ~=

(57)

Décalages

• Décalages

• à gauche a << b : a est décalé à gauche de b bits (les bits ajoutés valent 0)

5 << 2 0000 0000 0001 0100 20

un décalage d'une position à gauche correspond à une multiplication par 2

• à droite a >>b : a est décalé à droite de b bits (les bits insérés valent le bit de poids fort)

14 0000 0000 0000 1110

14 >> 2 0000 0000 0000 0011 3

-6 1111 1111 1111 1010

-6 >> 1 1111 1111 1111 1101 -3

un décalage d'une position à droite correspond à une division par 2 (en respectant le signe)

(58)

Opérateur conditionnel

• Syntaxe

expression1 ? expression2 : expression3 à peu près équivalent à :

if (expression1) expression2; else expression3;

• Exemple :

maximum = (x>y) ? x : y;

if (x>y) maximum =x ; else maximum = y;

• Conseil : ne pas utiliser (peu clair)

(59)

Opérateurs d'adressage

• Adresse de : &

Syntaxe : &variable , donne l'adresse mémoire de la variable Exemple :

int i,adr;

adr = &i;

ne pas confondre avec le "et" bit à bit

• Dont l'adresse est : *

Syntaxe *expression : donne le mot mémoire dont l'adresse est donnée par l'expression

Exemple : int i,adr;

i=1;

adr = &i;

printf("%d", *adr); -> 1

(60)

Opérateur de taille : sizeof

• Donne la taille de l'implantation

• 2 syntaxes

1/ sizeof expression exemple :

int i,j ;

j= sizeof i; -> 2 ou 4 (octets) 2/ sizeof (type)

exmples :

typedef char tab[100];

tab t;

int n;

n = sizeof(int), -> 2 ou 4 (octets) n = sizeof(tab) -> 100 (char)

(61)

Opérateurs divers

• ( ) : force l'ordre des calculs

ex : 1 + 2 * 3 -> 7 (1+2) * 3 -> 9

• [ ] pour les tableaux

t[2] équivalent à *(t+2)

• -> et . (opérateurs sur structures, + tard)

(62)

Priorité des opérateurs

Priorité Opérateurs Description Associativité

15 () [ ] -> . opérateurs d'adressage ->

14

++ -- incrément/décrément

<-

~ complément à un (bit à bit)

! non unaire

& * adresse et valeur (pointeurs)

(type) conversion de type (cast)

+- plus/moins unaire (signe)

13 * / % opérations arithmétiques ->

12 + - "" ->

11 << >> décalage bit à bit ->

10 < <= > >= opérateur relationnels ->

9 == != "" ->

8 & et bit à bit ->

7 ^ ou exclusif bit à bit ->

6 | ou bit à bit ->

5 && et logique ->

4 || ou logique ->

3 ?: conditionnel <-

2 = += -= *= /= %=

>>= <<= &= ^= |= assignations <-

1 , séparateur ->

(63)

Priorité des opérateurs

a – b /c *d (a-b) / (c-d) i = j = k = 0;

a=1; b=4;

! --a == ++ !b

!0 == ++0 1 == 1 1

(64)

Priorité des opérateurs (exercices)

main(){

int x, y , z;

x = 2;

x += 3 + 2; printf("%d\n",x);

x -= y = z = 4; printf("%d%d%d\n",x,y,z);

x = y == z; printf("%d%d%d\n",x,y,z);

x == (y = z); printf("%d%d%d\n",x,y,z);

x = 3; y =2 ; z = 1;

x = x && y || z ; printf("%d\n", x);

printf ("%d\n", x || ! y && z);

x = y = 0;

z = x ++ -1; printf ("%d, %d\n", x, z);

z += -x ++ + ++ y; printf ("%d, %d\n", x, z);

x =1 ; y =1;

printf("%d\n", ! x | x);

printf("%d\n", ~ x | x);

printf("%d\n", x ^ x);

x <<= 3 ; printf("%d\n", x);

y <<= 3 ; printf("%d\n", y);

y >>= 3 ; printf("%d\n", y);

(65)

Priorité des opérateurs (exercices)

x =0 ; y =0; z=0;

x+=y+=z;

printf("%d\n", x < y ? y : x) ;

printf("%d\n", x < y ? x++ : y++) ; printf("%d, %d\n", x , y);

printf("%d\n", z += x < y ? x++ : y++) ; printf("%d, %d\n", y , z);

x = 3; y = z = 4;

printf("%d\n",( z >= y >= x) ? 1 : 0) ; printf("%d\n", z >= y && y >= x ) ; x = y = z = 0;

}

(66)

ENTREES / SORTIES

(67)

Les entrées/sorties (lecture/écriture)

• Lecture clavier

2 fonctions de base : getchar () et scanf()

Elles peuvent être appelées soit indépendamment soit au sein d'expressions

Exemples getchar();

while (c==getchar()) {…..};

(68)

getchar()

• getchar() : sert à la lecture de caractères isolés

• la valeur de getchar() est le code ascii du caractère lu

• utilisation char c;

c = getchar();

• Exemple : on veut lire et mémoriser 2 caractères donnés sur 2 lignes différentes

char c1,c2;

c1 = getchar() // acquiert le 1er caractère

getchar (); // filtre le <cr>, on ne mémorise pas la valeur lue c2 = getchar () // acquiert le 2ème caractère

(69)

scanf ()

• Sert à la lecture de données et convertit la succession de caractères donnés en entiers, flottants, caractères, chaîne de caractères

• Syntaxe :

 scanf (format,arg1,arg2,……,argn)

 le nombre d'arguments est quelconque

 arg1, arg2,……, argn sont les adresses des variables dans lesquelles on stocke les valeurs lues

variable simple (entier, caractère, flottant) : &v

chaîne de caractères = tableau : v

 le format est une chaîne de caractères précisant le type des arguments afin de convertir la suite de caractères lus dans les arguments

(70)

Scanf : format

• Format

chaîne de caractères composée de caractères % suivis d'une lettre et éventuellement séparés par des blancs

la lettre indique le type de conversion à effectuer exemple :

int i; float x;

scanf("%d %f", &i,&x);

le %d indique que le premier argument est un entier le %f indique que le second est un réel

réponse : 2312.6

23 est converti en entier et stocké dans i 12.6 est stocké en flottant et stocké dans x

(71)

Scanf : format

• caractères de conversion

c : donnée de type caractère simple d : donnée de type entier relatif

f : donnée de type flottant

e : donnée de type flottant en notation exponentielle x : donnée de type entier hexadécimal

s : donnée de type chaîne de caractères (tabl. de char terminé par \0)

• Exemple

char t[20];

int i ; float x;

scanf ("%s %d %f", t,&i,&x);

réponses :

1/ abcde 123 0.05

2/ abcde 123  0.05

3/ abcde

123  0.05

(72)

Scanf : rôle des caractères ☐, , tabulation, dans les réponses

• Dans les réponses

☐, , tabulation servent de délimiteurs pour les valeurs numériques et les chaînes de caractères (pas pour les caractères)

• Exemples

scanf ("%d%f",&i,&x);

rep1 : 123 ☐☐☐☐456  i = 123 , x = 456.0

rep2 : 123456  i = 123456 , x : pas encore lu (en attente) scanf("%s%d",ch,&i);

rep : abc 12 ch = "abc" , i=12 scanf ("%c%c",&c1,&c2);

rep1 : ab c1= 'a' , c2 = 'b'

rep2 : a☐b c1= 'a' , c2 = ☐

scanf ("%c%c%c",&c1,&c2,&c3);

rep1 : ab c1= 'a' , c2 = 'b', c3= 

rep2 : ab c1= 'a' , c2 = 'b'

c c3 = 

(73)

Scanf : rôle des caractères ☐ et tabulation, dans la chaîne de format

• Lecture de valeurs numériques : aucun rôle

scanf ("%d%f",&i,&x)  scanf ("%d☐%f",&i,&x)

• Lecture de caractères : indique de sauter les ☐, tab et 

• Exemples

scanf ("%c%c%c",&c1,&c2,&c3);

rep1 : abc c1= 'a' , c2 = 'b', c3= 'c' rep2 : a☐b☐c c1= 'a' , c2 = '☐', c3= 'b' scanf ("%c☐%c☐%c",&c1,&c2,&c3);

rep1 : abc c1= 'a' , c2 = 'b', c3= 'c' rep2 : a☐b☐c c1= 'a' , c2 = 'b', c3= 'c' rep2 : a☐b 

c c1= 'a' , c2 = 'b', c3= 'c'

(74)

Scanf : compléments

• Nombre de caractères lus

faire précéder le caractère de format du nombre de caractères (max) désiré

Exemples int i,j,k;

scanf("%3d %3d %3d",&i,&j,&k);

rep1 : 1☐2☐3 i=1 j=2 k=3

rep2 : 123☐456☐789 i=123 j=456 k=789 rep3 : 123456789 i=123 j=456 k=789 rep4 :1234☐5678☐9 i=123 j=4 k=567 int i; float x;char c;

scanf("%3d☐%5f☐%c,&i,&x,&c);

rep : 10☐234.567☐t i=10 x=234.5 c='6'

(75)

Scanf : compléments

• Lecture d'une chaîne de caractères

char ch[50];

scanf("%s",ch) // pas de &

rep : abcdefghi

Le caractère 0 de fin de chaîne est ajouté automatiquement

Exercice : faire l'équivalent de scanf("%s",ch) à l'aide de getchar()

• Saut conditionnel de caractères : %*d, %*f

permet de sauter des données correspondantes dans la réponse exemple :

int i,j; char c;

scanf("%d ☐ %*d ☐ %c",&i,&c);

rep1 : 12☐34x i=12 c='x' rep2 : 12☐x i=12 c='x'

'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 0 ? ?

(76)

scanf : compléments

• Filtre sur chaînes de caractères

[ caractères admissibles] ou [^caractères non admissibles]

exemples

char ch[100];

scanf("%[0123456789]",ch);

rep : 32ab48 ch="32"

scanf("%[^0123456789]",ch);

rep : 32ab48 ch="ab"

raccourcis : [0123456789] ou [0-9]

[abcdefg] ou [a-g]

(77)

Ecriture

• 2 fonctions de base : putchar() et printf()

• putchar(caractère)

• Exemple

char c;

c='a';

putchar ( c );

putchar ('\n');

putchar('b');

Affichage : a

b

(78)

Printf()

• Format

printf(format,arg1,arg2,…..,argn);

les arguments sont des valeurs d'expression à imprimer

le format donne le texte mort et le mode de décodage des arguments le format est une chaîne de caractères

• Exemples :

printf("bon"); printf("jour");printf("\n") bonjour i=j=1;

printf("i=%d\n",i) i=1

printf("%d%d%d\n",i,j,i+j); 112

printf("%d☐%d☐%d☐%d\n",i,j,i+j,sqrt(i)); 1☐1☐2☐1 x=3.0;

printf("%f☐%d\n",x,i); 3.000000☐1

printf("%d\n%d\n",i,i+j); 1

2

(79)

Printf

• Caractères spéciaux de format

%d : imprime les entiers sur le nombre de caractères nécessaires

%f : imprime les réels avec 6 chiffres de partie décimale

%e : imprime les réels en notation exponentielle

%c : imprime un caractère

%s : imprime une chaîne de caractères jusqu'à rencontrer le caractère de fin de chaine 0 (erreur si absent)

…..

\n : saut à la ligne

\t : tabulation

\p : saut à la page

….

(80)

Printf : mises en forme

• Forçage du nombre de caractères

entiers :

%5d l'entier est imprimé sur 5 caractères au moins (blancs) avec cadrage à droite

%-5d l'entier est imprimé sur 5 caractères au moins (blancs) avec cadrage à gauche

réels :

%10f le réel est imprimé sur 10 caractères (en tout) avec 6 chiffres en partie décimale (cadrage à droite)

%-10f idem + cadrage à gauche limitation de la partie décimale

%20.3f le réel est imprimé sur 20 caractères (en tout) avec 3 chiffres en partie décimale

(81)

Printf : format variable

• ("%*d",n,i)

n donne le nombre de caractères pour i

• ("%*.3f,n,x)

n donne le nombre total de caractères pour x

• ("%*.*f,n,m,x)

n donne le nombre de total caractères

m donne le nombre de caractères pour la partie décimale

• Exemples

(82)

Printf

• La valeur de retour du printf est le nombre de caractères écrits et une valeur négative si il y a eu un pb.

• Exemple :

int a,x;

a=32;

x = printf ("%d\n",a);

printf ("%d\n",x); -> 3

(83)

Autres fonctions d'E/S

• Beaucoup d'autre fonctions d'E/S

voir "stdio.h"

gets, puts permettent de lire et d'écrire des chaînes de caractères

contenant des espaces (rappel : scanf ("%s",….) les espaces sont des délimiteurs)

exemple :

#include "stdioh"

main() {

char ligne[80];

gets(ligne);

puts(ligne);

}

(84)

Lecture/Ecriture dans fichiers

• Principe : identique aux lecture/écriture sur clavier/écran

En fait, le clavier et l'écran sont des fichiers particuliers

• Il faut simplement en plus "ouvrir" le fichier c-à-d

- l'associer à un fichier physique (sur disque) - l'associer à un variable interne du pgm

• Un fichier peut être

- soit lu (read)

- soit (ré-)écrit (write) bande magnétique - soit écrit à la fin (append)

• Déclaration :

FILE * variable-interne

ex : FILE * f; // f est une variable spéciale de type "fichier"

(85)

Ouverture de fichier : fopen

• variable = fopen("nom du fichier sur disque",mode d'ouverture)

mode d'ouverture :

syntaxe : chaîne de caractères 1er caractère :

'r' = read = lecture 'w' = write = écriture

'a' = append = écriture à la fin

fopen renvoie la valeur NULL (=0) si le pb sur le fichier physique

• Exemple

FILE * f;

f = fopen ("c:\texte.txt","r1234");

if (f==NULL) printf ("le fichier est absent\n");

else printf ("ok\n");

variable interne

fichier physique

(86)

Fermeture du fichier : fclose

• Supprime l'association fichier physique-variable interne

• La variable interne peut être associée à un autre fichier physique

• Syntaxe

fclose (variable interne)

• Exemple :

FILE * f;

f= fopen (fichier1, "r");

….

fclose (f);

f= fopen (fichier2,"w");

(87)

Lecture dans fichier

• Lecture :

fgetc() et getc() ↔ getchar() exemple

c=fgetc(f);

fscanf() ↔ scanf() exemple

fscanf(f,"%d",i) le 1er argument est le variable interne fichier

• Le caractère EOF indique la fin de fichier

• Ecriture

fputc () ↔ putchar() // c= fgetc (f)

fprintf() ↔ printf() // fprintf(f,"……",…..);

(88)

Exercice

• Afficher à l'écran le contenu d'un fichier (idem commande unix ou MSDOS type)

main() {

FILE * monfichier;

char sur_disque[100]; char c;

/* acquisition du nom */

scanf("%s",sur_disque);

/*ouverture*/

monfichier=fopen(sur_disque,"r");

if (monfichier==NULL) printf("erreur\n");

else { // lecture affichage

while ((c=getc(monfichier))!=EOF) printf("%c",c);

fclose (monfichier);

} }

(89)

Lecture/ecriture dans chaines de caractères

sprintf (char * s, format, paramètres) = écriture dans la chaine s

sscanf (char * s, format, paramètres) = lecture dans la chaine s exemple

char tokenstring[] = "15 12 14... " ; char s[81]; char c; int i; float fp;

/*lecture de différentes valeurs: */

sscanf( tokenstring, "%s", s );

sscanf( tokenstring, "%c", &c );

sscanf( tokenstring, "%d", &i );

sscanf( tokenstring, "%f", &fp );

/* Sortie*/

printf( "String = %s\n", s );

printf( "Character = %c\n", c );

printf( "Integer: = %d\n", i );

printf( "Real: = %f\n", fp ); }

Sortie : String = 15 Character = 1 Integer: = 15 Real: = 15.000000

(90)

Lecture/écriture dans chaines de caractères

• Exercice :

Convertir un entier en une chaîne de caractères : exemple :

int i = 135,;

char s[1000];

/* à faire */

……..

printf("%s",s);  135;

(91)

Compléments sur les instructions de contrôle

• Instruction if : imbrication

ex1 : if(e1) if(e2) s1;

else s2;

else if (e3) s3;

else s4;

e1

s1 s1 s2 s3 s4 e2

e3

ex2 : if(e1) s1;

else if (e2) s2;

ex3 : if(e1) s1;

else if (e2) s2;

else s3;

ex4 : if(e1) if(e2) s1;

else s2;

e1

s1

s2 e2

e1

s1

s2 s3 e2

e1

s1 s1 s2 e2

e1

s1 s1

s2 e2

(92)

Compléments sur les instructions de contrôle

• Règle : le else se rapporte au if le + imbriqué

e1

s1 s1

s2 e2

if(e1) {if(e2) s1;}

else s2;

if(e1)

if(e2) s1;

else ; else s2;

ou bien

(93)

Compléments sur les instructions de contrôle : continue

• Dans une structure itérative : l'instruction continue permet d'arrêter l'itération courante sans sortie de la boucle

• Exemple: Calculer la moyenne des valeurs positives d'un tableau d'entiers relatifs.

nb_valeurs=0;

somme = 0;

for (i=0;i<dim;i++) {

if (T[i]<0) continue;

somme = somme + T[i];

nb_valeurs ++;

}

moyenne = somme / nb_valeurs

(94)

Instruction break

L'instruction break fait sortir de la structure de contrôle dans laquelle elle est imbriquée

Utilisation dans les boucles : permet de faire une boucle avec une condition de type "et" logique

ex: while (c1 && c2) {traitement;}

while (c1)

if (!c2) break;

else {traitement;}

Application typique : gestion d'exception

(95)

différence entre continue et break

for (i = 0 ; i < 10 ; i++) { if (i == 5) break ; printf("%d,",i) ; }

0,1,2,3,4,

for (i = 0 ; i < 10 ; i++) {

if (i == 5) continue ; printf("%d,",i) ;

}

0,1,2,3,4,6,7,8,9

(96)

break

On veut afficher tous les éléments d'un tableau d'entiers jusqu'à rencontrer un nombre <0 (si il y en a un)

for (i=0;t[i]>=0 && i<dim;i++) ou bien i=0;

printf("%d", t[i]); while(t[i]>=0 && i<dim) {printf("%d", t[i]);i++};

Pb : lorsque i=dim, il y a évaluation de t[dim] qui n'existe pas => erreur Solution 1 : avec un "drapeau »

positif=1;

// positif indique que l’on a eu que des valeurs positives jusqu'à maintenant for (i=0; (positif==1) && (i<dim) ; i++) {

if(t[i]<0) positif=0;

else printf("%d", t[i]);

} Solution 2 :

for (i=0; i<dim;i++) { if(t[i]<0) break;

else printf("%d", t[i]);

}

(97)

Instruction switch

• syntaxe : switch (expression) instructions où expression a une valeur entière ou caractère

• L'instruction est une expression composée d'alternatives.

Chaque alternative commence par une énumération de cas

• switch (expression) {

case valeur 1 : instruction1; instruction 2; ….;

case valeur 2 : instruction1; instruction 2; ….;

case valeur n : instruction1; instruction 2; ….;

default : instruction1; instruction 2; ….; // optionnel };

(98)

switch

Exemple : char c;

printf("donner un e couleur\n");

c=getchar();if (c>='a' && c<='z') c=c+'A'-'a' switch (c) {

case 'R' : printf("Rouge \n");

case 'V' : printf("Vert\n");

case 'B' : printf("Bleu\n");

default : printf ("Autre");

}

R

Rouge Bleu Vert Autre

V

Bleu Vert Autre

B

Bleu Autre Autre

(99)

switch + break

Exemple : char c;

printf("donner un e couleur\n");

c=getchar();if (c>='a' && c<='z') c=c+'A'-'a' switch (c) {

case 'R' : printf("Rouge \n");break;

case 'V' : printf("Vert\n");break;

case 'B' : printf("Bleu\n");break;

default : printf ("Autre");

}

R

Rouge

V

Vert

B

Bleu Autre

(100)

b ou B

switch + break

Exemple : char c;

printf("donner une couleur\n");

c=getchar();

switch (c) {

case 'r','R' : printf("rouge \n");break;

case 'v', 'V' : printf("Vert\n");break;

case 'b','B' : printf("Bleu\n");break;

default : printf ("Autre");

}

r ou R

Rouge

v ou V

Vert

Bleu Autre

(101)

Les tableaux

Rappel : tableau =regroupement de données de même type sous un même nom, accessibles par un indice (0,..,dim-1)

Déclaration et implantation mémoire :

int t[50]; => réservation dans la mémoire de 50 cases contiguës d'entiers.

L'adresse de la première case est t

&t[0]  t

*t  t[0]

t[0]t[1]

t[2]

t[48]

t[49]

t

(102)

Initialisation à la compilation int t[10] = {1,2,3,4,5,6,7,8,9,10};

float x[4] = {0.,0.25,3.14,2.57};

char couleur[4]= {'r','v','b','j'};

char texte[10]="abcd";

int t1[10] = {1,2,3};

• Dimension par défaut:

int t[ ]={0,0,0} => dimension =3

char t [ ]={'r','v','b','j'}; => dimension=4 char t[ ]="abcd" => dimension=5

par contre int t[ ] sans initialisation est incorrect

a b

Tableaux

1 2 3 4 5 6 7 8 9 10

c d \0 ? ? ? ? ? 1 2 3 ? ? ? ? ? ? ? 0. 0.25 3.14 2.57

r v b j

(103)

Tableaux

• Accès aux éléments d'un tableau

int t[50];

syntaxe 1

// accès à la (i+1)ème case avec i compris entre 0 et 49 t[i];

syntaxe 2

puisque t est l'adresse de la première case :

t[0]  *t // mot d'adresse t, * : opérateur mot dont l'adresse est) t[1]  *(t+1) // rem : priorité des opérateurs)

t[i]  *(t+i) // *t+i  t[0]+i

(104)

Tableaux à plusieurs dimensions

Tableau dont chaque case est elle-même un tableau ex : typedef int t[100] // t est un type

t matrice [20];

matrice est un tableau de 20 cases, chacune est un tableau de 100 entiers =>

matrice est un tableau de 20*100 entiers autre déclaration :

int matrice [20][100]; // tableau de 20 "lignes" et 100 "colonnes"

• Accès aux éléments

par un 1er indice allant de 0 à 19 et par un 2eme indice allant de 0 à 99 matrice[3] est la 4eme case de tableau. C'est un tableau de 100 cases

(entiers)

matrice[3][48] est un entier.

matrice [i][j] avec i de 0 à 19 et j de 0 à 99 matrice est un tableau à 2 dimensions

Références

Documents relatifs

J’écris une lettre au prêtre de ma paroisse pour le remercier de sa présence sur les réseaux sociaux.. pendant ce temps

Lorsqu'un char tire un obus, il tire selon un certain angle vers le haut afin d'atteindre sa cible.. Comment appelle-t-on la distance maximale à laquelle l'obus

Et bientôt, selon une évolution parallèle à celle de Nietz- sche, l'indépendance à l'égard de la vengeance contre les hom- mes va devenir aussi indépendance à l'égard du

DEVINETTE Je suis une fleur mais aussi une couleur.. est dans

Le client quitte la boulangerie avec un croissant.. Il est suivi par

â Mouvement d’une particule chargée dans un champ électrostatique uniforme : mettre en équation le mouvement et le caractériser comme un mouvement à vecteur accélération

´Ecrire un code qui permet de supprimer les deux derni`eres lettres d’une chaˆıne de caract`eres.. ´Ecrire un programme r´ealisant la concat´enation de deux chaˆınes de

GtkWidget* gtk_label_new(const gchar* str); crée un objet GtkLabel de libellé str void gtk_label_set_label(GtkLabel* label, const gchar* str); affecte le libellé str au label