Seance2 C

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 28

PROGRAMMATION

EN
LANGAGE C
PARTIE1

Eric Ziad-Forest
[email protected]
Séance de cours 2
du 11/09/2017

Eric Ziad-Forest

L’École des INGÉNIEURS Scientifiques


Rôle et utilisation du scanf

• La fonction scanf permets de lire des données entrées au clavier.


• Exemple :
float prix_min = 0.0;
double prix_max;
unsigned int duree = 0;
printf("Entrez une durée en seconde (entier positif) :");
scanf("%d",&duree);
printf("Entrez un prix minimum et un prix maximum : ");
scanf("%f %lf", &prix_min, &prix_max);
printf("%d \t%2.1f \t%02.4f", duree, prix_min, prix_max);

• Résultats produits :
Entrez une durée en seconde (entier positif) :12
Entrez un prix minimum et un prix maximum : 2.41 5.47
12 2.4 5.4700

Entrez une durée en seconde (entier positif) :42


Entrez un prix minimum et un prix maximum : 5 75.12458
42 5.0 75.1246

3
Détails sur le scanf

• Le symbole & devant chaque nom de variable est obligatoire


– Nous reviendrons sur la raison plus tard dans le cours lorsque nous traiterons les pointeurs

• De la même façon que pour printf, la fonction scanf utilise différents types de données en entrée :
– %d : pour les nombres entiers signées
– %u : pour les nombres entiers non signées
– %f : pour les nombres flottant
– …
• Attention, il faut faire la différence entre les différentes tailles d’un même type :

4
Calculs de base en C

• Les opérateurs de base sont : +, -, *, /


• Les variables, constantes et valeurs numériques sont directement exploitables dans une expression de calcul.
• Les priorités des opérateurs sont respectées.
• Les parenthèses ont leur rôle habituel.
• Exemples :
float a, b, c, r1, r2, r3;
const float PI = 3.1416;
printf("entrez les valeurs de a, b et c : ");
scanf("%f %f %f", &a, &b, &c);
r1 = b*b - 4.0*a*c;
r2 = (PI+1)/(PI-1);
r3 = PI*(a-(b+c)/2.0);
printf("r1=%f, r2=%f, r3=%f", r1, r2, r3);
• Résultat :
entrez les valeurs de a, b et c : 2.5 7.0 4.0
r1=9.000000, r2=1.933881, r3=-9.424800

5
Opérateur modulo (%)

• L’opérateur % retourne le reste de la division entière.


• Attention : la division de deux entiers produit systématiquement un entier (troncature)!
• Il est possible de transformer un type de donné en un autre en plaçant le type entre parenthèses devant
la valeur à modifier :
• Exemples :
int ia = 11, ib = 3;
float fa = 11.0, fb = 3.0;
int ir = ia % ib; // utilisation de l’operateur modulo
int id = ia / ib; // une division entière
float fd = ia / ib; // une autre division entière
float fd2 = fa / fb;
float fd3 = (float)ia / ib; // tranformation d’un int en float
printf("%d, %d, %f, %f %f", ir, id, fd, fd2, fd3);

2, 3, 3.000000, 3.666667 3.666667

6
Incrémentation (pré et post)

• L’opération valeur = valeur + 1 à un raccourci d’écriture valeur++


• Attention x = i++ et x = ++i ne produit pas le même résultat.
– Dans le premier cas il y a post incrémentation alors que dans le second il y a pré incrémentation
int x =0, valeur = 5;
x = valeur++; // post-incrémentation de valeur
printf("x = %d, valeur = %d\n", x, valeur);
x = ++valeur; // pré-incrémentation de valeur
printf("x = %d, valeur = %d\n", x,valeur);

x = 5, valeur = 6
x = 7, valeur = 7

x-- correspond à x = x – 1 et est désigné par le terme décrémentation

7
Autres écritures réduites

• a += b correspond à a = a + b
• a -= b correspond à a = a - b
• a *= b correspond à a = a * b
• a /= b correspond à a = a / b
• a %= b correspond à a = a % b
Exemples :
float a = 113.45, b = -2.0e3;
int c = 10, d = -3, e = 7;
a+=b; b-=a;
c*=2; c/=d;
d+=6; e%=d;
printf("%.2f %.1e %i %i %i\n", a, b, c, d, e);

-1886.55 -1.1e+002 -6 3 1

8
Problèmes de déplacement et valeurs limites

• Attention au problème de débordement lors d’un calcul. Si le résultat d’un calcul dépasse la valeur minimale ou
maximale représentable, il n’y aura pas d’erreur de produite à l’exécution.
• Pour obtenir les valeurs minimales et maximales des différents types numériques, il faut exploiter les constantes
définies dans le fichier limits.h avec un include.

short a = 32700;
short b = a + 100; Constantes définies dans le
unsigned short c = a +100; fichier limits.h
printf("%d %d %d \n", a, b, c);
printf("%d %d %u\n", SHRT_MIN, SHRT_MAX, USHRT_MAX);
printf("%ld %ld %lu\n",LONG_MIN,LONG_MAX,ULONG_MAX);

32700 -32736 32800


-32768 32767 65535
-2147483648 2147483647 4294967295

Description de l’ensemble des constantes dans le fichier limits.h : https://www.google.fr/#q=limits.h

9
float, double et problèmes

• La même constante représentée par un float ou double ne correspond pas à la même représentation (valeur) en mémoire
• Les conversions d’un type vers l’autre produisent des effets d’arrondi 0 0 0
• Il existe un format long double avec la plus grande précision
• La division de deux entiers dont un entier et non un nombre à virgule. 1 1 1 1
– Pour avoir un nombre à virgule, il faut convertir l’un des entiers en float, double, …
#include <stdlib.h>
#include <stdio.h> 1.192093e-07 2.220446e-16 1.084202e-19 3.141500e+00
#include <float.h>
int main(){
double pi1 = 3.1415; /* Nombre en double précision dans un double */ 4 8 16
double pi2 = 3.1415f; /* Nombre en simple précision converti en double */
float pi3 = 3.1415; /* Nombre en double précision converti en simple */
float pi4 = 3.1415f; /* Nombre en simple précision dans un simple */
unsigned short res1 = pi1 == pi2, res2 = pi1 == pi3, res3 = pi1 == pi4;
printf("%u %u %u \n", res1, res2, res3);
unsigned short res4 = pi2 == pi3, res5 = pi2 == pi4, res6 = pi3 == pi4, res7 = pi4 == pi4;
printf("%u %u %u %u \n", res4, res5, res6, res7);
long double v = 3.1415l; /* Dernier symbole un L en minuscule */
// EPSILON : Ecart entre 1 et la plus petite valeur supérieur à 1 qui soit représentable
float vminf = FLT_EPSILON;
double vmind = DBL_EPSILON;
long double vminld = LDBL_EPSILON;
printf("%e %e %Le %Le \n", vminf, vmind, vminld, v);
printf("%lu %lu %lu\n",sizeof(float),sizeof(double),sizeof(long double));
return 0;
}

10
Opérateurs binaires

• Le langage C propose un ensemble d’opérateurs binaires pour agir directement sur les bits des entiers.
unsigned short a = 0xFFF0; // Utilisation des opérateurs
unsigned short b = 0x0FFF; // bits à bits : & | ^ ~
unsigned short c = a & b; // a and b
unsigned short d = a | b; // a or b
unsigned short e = a ^ b; // a xor b 1111 1111 1111 0000
unsigned short f = ~e; // not e & 0000 1111 1111 1111
printf("%X %X %X %X \n", c, d, e, f); = 0000 1111 1111 0000
unsigned short g = e >> 2 ; // décalage de 2 bits à droite
unsigned short h = e << 2; // décalage de 2 bits à gauche
printf("%X %X \n", g, h);

0FF0 FFFF F00F 0FF0


3C03 C03C
1111 0000 0000 1111
<< 2
1100 0000 0011 1100

11
Bibliothèque mathématique

• Il faut ajouter #include<math.h> au début du fichier C.


• Fonctions disponibles :
– fabs(x) : valeur absolue de x
– floor(x) et ceil(x) : arrondir à l’entier inférieur et supérieur
– pow(a,b) : élévation de a à la puissance b
– sqrt(x) : racine carré de x.
– sin(x), cos(x), tan(x) : sinus, cosinus et tangente de x
– asin(x), acos(x), atan(x), exp(x), log(x), log10(x) , …
Pour plus de détails voir : ...

12
Exemple d’utilisation de math.h

#include <stdio.h>
#include <stdlib.h>
#include <math.h> Une des constantes de la librairie
mathématique
int main(){
double angle = M_PI/3.0; /* angle en radian */
double vx = cos(angle);
double vy = sin(angle);
double r = sqrt(pow(vx,2.0)+pow(vy,2.0)) ;
printf("%.3f %.3f %.3f %.3f\n", angle, vx, vy, r);
printf("%.12f\n",M_PI);
return 0;
La compilation doit de faire avec l’option –lm :
}
gcc -Wall -o exemple_math exemple_math.c -lm

1.047 0.500 0.866 1.000


3.141592653590

13
Instructions conditionnelles
• Les mots cles if et else permettent d’exécuter certaines instructions seulement si une condition est (ou non) vérifiée.
• Opérateurs de test : == (est égale à), != (est différent de), >, <, >=, <=
Attention = est une affectation, alors que == est un test d’égalité !
double x;
printf("Entrez la valeur de x : ");
scanf("%lf",&x);
if (x>=0.0) printf("La valeur est positive");
else printf("La valeur est négative");
printf(", x = %f\n",x);

Entrez la valeur de x : 5.0


La valeur est positive, x = 5.000000

Entrez la valeur de x : -3.14


La valeur est négative, x = -3.140000

14
Block d’instructions

• Plusieurs instructions peuvent être regroupées ensembles grâce à l’utilisation des accolades {}
• Exemple d’utilisation avec une conditionnelle :
int valeur, resultat = 0;
const int seuil = 100;
printf("Entrez une valeur : ");
scanf("%d",&valeur);
if (valeur>seuil){
printf("la valeur est plus grande que %d\n",seuil);
resultat = valeur*3-seuil;
}
else{
printf("la valeur est plus petite que %d\n",seuil);
resultat = valeur+seuil;
}
printf("Resultat = %d\n",resultat);

15
Exploitation du else if

• L’exemple ci-dessous illustre l’exploitation de deux conditions, dont la seconde ne sera évaluée que si la première
est fausse :
char code;
int val;
printf("Entrez un caractère : ");
scanf("%c",&code);
if (code=='o'){ Le nombre de else if consécutifs n’a pas de
printf("oui\n"); val = +1; limite .
} if (code='a') …
else if (code=='n'){ else if (code=='b') …
printf("non\n"); val = -1; else if (code=='c') …
} else if (code=='d') …

else {
else …
printf("???\n"); val = 0;
}
printf("val = %d (%c)",val,code);

16
Conditions avec : et, ou, négation

• Les symboles : &&, || et ! Correspondent respectivement au et logique, ou


logique et à la négation.
• Exemple d’utilisation dans la condition d’un if :
char code1, code2;
printf("Entrez un caractère : ");
scanf("%c%c", &code1, &code2);
if (code1>='a' && code1<='z') printf("Une minuscule\n");
if (!(code1<'A' || code1>'Z')) printf("Une majuscule\n");
if (code2=='o' || code2=='O') printf("La lettre o\n");
if ((code1=='n' || code1=='N')
&&
(code2=='o' || code2=='O')) printf("C'est 'no'!\n");

17
Instructions if imbriquées

Il n’y a pas de limite au nombre de if else


double x;
qu’il est possible d’imbriquer.
printf("Entrez la valeur de x : ");
scanf("%lf",&x); Cependant, si ce nombre est important la
if (x>=0 && x<100){ lisibilité du code peut devenir rapidement difficile
printf("x est entre 0 et 100.\n");
if (x>=10 && x<=20) printf("x est entre 10 et 20.\n");
else printf("x n'est pas entre 10 et 20.\n");
if (x>=30 && x<=40) printf("x est entre 30 et 40.\n");
else printf("x n'est pas entre 30 et 40.\n");
}
else {
printf("Valeur hors limite");
if (x<0) printf(" et négative");
printf("!\n");
}

18
Valeur 0 et autre avec un if

• Si la valeur d’une condition est 0, le test est faux, sinon pour toute autre valeur il est vrai !

double x;
printf("Entrez la valeur de x : ");
scanf("%lf",&x);
if (x) printf("Le test est vrai!");
else printf("le test est) faux!");

• Si la valeur de la variable est 0 ou 1, on dit que la variable est booléens.


• Les variables booléens peuvent exploiter les opérateurs &&, || et !.

19
Utilisation du switch

• Permet de produire un code plus lisible et compact qu’un ensemble de else if.
int choix;
scanf("%d",choix);
switch (choix){ Attention, sans break,
case 1 : les instructions suivants sont exécutées.
printf("Entrez votre nom.");
break;
case 2 : Par exemple le code ci-dessous :
switch (choix){
printf("Entrez votre prénom.");
case 1 :
break;
printf("Entrez votre nom.");
case 3 : /* pas de break ici ! */
printf("Entrez votre age."); case 2 :
break; printf("Entrez votre prénom.");
// … break;
case 10 : Affichera avec choix = 1 :
printf("Entrez votre email."); Entrez votre nom.
break; Entrez votre prénom.
default :
printf("Choix non répertorié");
}
// suite des instructions du programme

20
Conditions condensées

• L’opérateur ternaire : condition ? action si vrai : action si faux ; permet une écriture
condensée d’un test conditionnel.
• Si l’action produit un résultat, il peut directement être affecté à une variable.
• Les opérateurs ternaires conditionnels peuvent être imbriqués.

int a=5, b =10, c = 7;


int d = a>b ? a-b : a+b;
int e = c>b ? +1 : c<a ? -1 : 0;
e ==0 ? printf("Valeur comprise entre %d et %d\n", a, b)
: printf("Autre cas\n");
printf ("%d %d \n", d, e);

Valeur comprise entre 5 et 10


15 0

21
Les boucles

• Une boucle est une structure qui permet de répéter une instruction ou un block d’instructions plusieurs
fois.
• L’utilisation des boucles pour la réalisation de programme est un élément essentiel en programmation.
– La grande majorité des programmes comportent des processus itératifs
• Le langage C utilise deux types de boucle identifiable à partir des mots clés :
– while (et la variante do … while)
– for
• Pour éviter de répéter les instructions indéfiniment, il est indispensable de définir une condition d’arrêt.
– C’est une condition booléen définit avec la même syntaxe que pour le cas du if.

22
La boucle while

Syntaxes :
– while (/* condition *) /*instruction à répéter*/
– while (/* condition*) {
/* block d’instruction à répéter */
}
Exemples : A vous de deviner ce qui
int i = 10; sera affiché si l’utilisateur
while (--i>0) printf("valeur de i = %d\n",i); saisi respectivement :
int valeur = -1;
while (valeur<0){
-12, -27, 45
printf("Entrez une valeur positive : ");
scanf("%d",&valeur);
i++;
if (valeur<0) printf("Essai i=%d, la valeur n'est pas
positive, recommencez !\n",i);
}
printf("Ok pour la valeur : %d\n",valeur);

23
Boucle infinie et cas du break

Si la condition est toujours vrai, la boucle est infinie.


int i=0;
while(1){ // quitter avec un ctrl + C
i++;
printf("i = %d\n",i);
}

Sauf si le block d’instruction utilise une instruction break.


int i=0;
while(1){
i++;
printf("i = %d\n",i);
if (i>100) break;
}

24
La boucle do … while

Par rapport à la boucle while, la boucle do … while garantie que le block d’instructions sera répétée au minimum
une fois, car la condition est testée après dans le second cas au lieu d’avant dans le premier.

const double v_init = 1e-10;


Le printf("%e") permet un affiche d’un nombre avec
const double v_stop = 1e-5;
une notation scientifique
double v; (ex: 0,00125 → 125.0 e-05)
v = v_init;
while(v>v_stop){
v /= 10.0;
printf("while v= %e \n",v);
}
A vous de deviner ce qui sera affiché
v = v_init; suivant la valeur de v_init et v_stop
do {
v /= 10.0;
printf("do while v= %e \n",v);
} while(v>v_stop);

25
La boucle for

• La boucle for n’est pas indispensable puisqu’elle peut être réalisée avec une boucle while, cependant elle a une
écriture condensée plus rapide à saisir.
• Syntaxe : for(initialisation; condition, incrémentation) …

int i;
i=0;
while(i<10){
printf("%d ",i); Affichera :
i++; 0123456789
} 0123456789
printf("\n");

// Equivalent avec un for


for(i=0; i<10; i++) printf("%d ",i);
printf("\n");

26
La boucle for suite

• Les parties : initialisation et incrémentation, peuvent contenir plusieurs instructions séparées par des
virgules.
int i,j, sum;
i = -100, j = 100, sum=0; Affichera dans les 2 cas:
while(i<0 && j>0){ i=-100, j=100
printf("i=%d, j=%d\n", i, j); Sum=0
if (i%2 == 0) printf("Sum=%d",sum); i=-97, j=98
i+=3; i=-94, j=96
j-=2;
Sum=3
sum+=i+j;
i=-91, j=94
}
i=-88, j=92
// Equivalent avec un for Sum=10
for(i=-100, j=100, sum=0; …
i<0 && j>0; i=-7, j=38
i+=3 , j-=2, sum+=i+j){ i=-4, j=36
printf("i=%d, j=%d\n", i, j); Sum=528
if ( i%2 ==0) printf("Sum=%d\n",sum); i=-1, j=34
}

27
MERCI

L’École des INGÉNIEURS Scientifiques

Vous aimerez peut-être aussi