C-II : sommaire
C-II 1
Eléments lexicaux
-
Séparateurs et commentaires
- Identificateurs
- Constantes littérales
- Mots réservés
- Directives du pré-processeur
C-II 2
Séparateurs et commentaires |
-
espace, tab, newline :
sont ignorés, ils servent uniquement de séparateurs d'entités lexicales.
- /* ... */ ou // (C++
uniquement) : commentaires, ignorés également.
|
/* ceci est un commentaire |
sur plusieurs lignes*/ |
// ne commente qu'une ligne
|
Attention : les commentaires ne s'imbriquent pas !
- ; : termine 1 déclaration ou 1 instruction simple.
- , : sépare 2 éléments dans une liste.
- ( ... ) : liste d'arguments.
- { ... } : bloc ou liste d'initialisations.
- [ ... ] : dimension/sélection d'éléments de tableaux.
C-II 3
-
Suites de chiffres ([0..9]), lettres ([a..z], [A..Z]), ou
``_'' ne commençant pas par un chiffre.
Ex. de noms corrects :
x x2 _x LePoint c_est_bon
Ex. de noms incorrects :
2x non' le.point hara-kiri
- Distinction entre MAJUSCULES et minuscules :
toto
¹ Toto
¹ TOTO
- Attention : les mots réservés du langage (cf. plus loin)
ne sont pas redéfinissables par le programmeur.
Ex. : int, if, then, while, ...
C-II 4
-
Entier
-
notation décimale :
24
24L
(long)
24UL
(long non signé)
- notation héxadécimale :
0x18
0xFUL
(long non signé)
- notation octale :
030
- Flottant
3.14
6.025e25
1.
- Caractère
-
notation classique :
'c'
- notation octale :
'\010'
- notation hexadécimale :
'\x08'
- caractères spéciaux :
'\n'
'\t'
'\b'
'\''
'\\'
'\0'
- Chaîne de caractères
""
"I am a string"
"I am two st""rings"
C-II 5
-
Relatifs aux structures de données :
° entiers : bool, char, short, int,
long, signed, unsigned
° flottants : float, double
° non défini : void
° classe d'allocation : auto, register, static, extern
° qualifiant : const, volatile
° définition de type : typedef
° constructeurs de type : struct, union, enum, class
° taille : sizeof,
° ...
- Relatifs aux structures de contrôle :
° condition : if, else
° choix : switch, case, default
° itération : for, while, do
° rupture : return, break, continue, goto
C-II 6
Directives du pré-processeur |
-
Commencent toujours par #
Ex. : #include #define #ifdef #if
- Quatre utilisations principales :
-
Inclusion de fichiers :
- Définition de constantes symboliques ;
- Définition de macros :
#define CARRE(z) ((z)*(z))
|
- Compilation conditionnelle
#if DEBUG |
/* code inclus ssi DEBUG != 0 */ |
fprintf(stderr, ...); |
#endif
|
C-II 7
Déclarations
-
Déclarations
- Définition vs. déclaration
C-II 8
[á class_allocñ] á typeñ
ident {','ident['='á express.ñ]}';'
-
TOUTE VARIABLE doit être déclarée AVANT son
utilisation.
En C++, cette déclaration peut avoir lieu
n'importe où dans un bloc,
En C, cette déclaration doit être en début de bloc.
- TOUTE FONCTION doit être déclarée AVANT son appel
(avec la liste des types de ses arguments).
Ex :
register int r=0, c, d=1; |
static int K; |
char chaine[300] = "ceci est un exemple"; |
int fonc(char *, int); |
int a; |
... [instructions quelconques] ... |
int b=0; |
for (int i=0; i<10; i++) b += i*i; |
// ATTENTION: i n'est pas locale au for |
a = fonc(chaine, r); |
...
|
C-II 9
Définition vs. déclaration (1) |
-
Distinguer la DEFINITION de la
DECLARATION d'une entité :
-
une déclaration ajoute un nom dans un programme.
Une déclaration nomme diverses entités (objet, type,
fonction). Aucune place mémoire n'est réservée.
- une définition est une déclaration qui
définit complètement le nom :
-
définir un type : déclarer ses composants,
- définir une fonction : donner son corps,
- définir un objet : réserver son emplacement mémoire.
Une DEFINITION ne peut et ne doit apparaître qu'UNE et UNE
SEULE FOIS dans un programme.
Une DECLARATION doit apparaître au moins UNE FOIS dans un
programme.
C-II 10
Définition vs. déclaration (2) |
Exemples de déclarations qui sont également des définitions
int monnumeroglobal=0; |
static double pi = 3.14; |
char* version = "Version 1.1"; |
extern int size = 128; |
struct A { int a; }; |
static int prev(int i) { |
return ((i-1 < 0) ? size : i-1); |
} |
int next(int i) {return(i+1) % size;} |
Exemples de déclarations qui ne sont pas des définitions
extern int monnumeroglobal; |
extern char* version; |
extern int size; |
struct A; |
extern int next (int i); |
int prev (int i);
|
C-II 11
Définition vs. déclaration (3) |
(cas 1) -- int foo = 3; |
(cas 2) -- int foo; |
(cas 3) -- extern int foo; |
(cas 3) -- extern int foo = 3; |
-
cas 1
- : lors de la compilation, un espace mémoire est réservé et
initialisé avec la valeur 3.
- cas 2
- : lors de la compilation, un espace mémoire est réservé. La
valeur initiale est indéterminée.
- cas 3
- : la variable foo est déclarée. La réalité de sa définition
sera prise en compte uniquement lors de l'édition de lien : recherche
de sa définition dans l'ensemble des fichiers qui constituent le
programme.
- cas 4
- : la variable foo est définie. Lors de l'édition de lien,
on vérifiera qu'elle n'est pas définie par ailleurs dans un autre
fichier constituant le programme.
C-II 12
Types
-
Types élémentaires
- Booléens
- Constantes
- Pointeurs
- Références
C-II 13
-
Le type vide : void
- Les types entiers :
-
char
ex : char var ='a', Var= 'B', foo='\n', Foo='\014';
- short, int, long
ex : short si=120; int i=-10, j=0123;
long l=0xfc, k=1234555;
-->
entiers positifs en préfixant les types
précédents par unsigned
ex : unsigned int ui; unsigned char uc=0;
- Les types réels :
-
float, double
ex : float f = 1.23, fb=1.2345e+12, fbb= 1. ;
double d = 1.23, db=1.23456789012345e+12;
Tailles limites :
-->
limits.h
pour les types entiers,
-->
float.h
pour les types réels.
C-II 14
-
En C : pas de type booléen, par contre, les
expressions booléennes existent.
- Par convention, toute valeur entière peut
être considérée comme une valeur booléenne.
Tel que :
-
Faux est codé par l'entier nul.
- Vrai est codé par un entier non nul.
- En C++ ANSI : ajout d'un nouveau type bool.
(NON DISPONIBLE SUR LES COMPILATEURS INSTALLES)
-
les valeurs de ce type sont true et false,
- la conversion d'une valeur numérique en un bool
rend false pour 0 et true pour n'importe
quelle valeur non nulle,
- une valeur de type bool, convertie en int est
égale à 0 pour false et à 1 pour
true,
- les instructions if et while sont converties
en bool,
- tous les opérateurs retournant des valeurs booléennes
retournent des valeurs de type bool.
C-II 15
-
Déclarées avec le mot clé : const
const double PionMass=0.1395679; |
const int Dim=10; |
int const FALSE=0; // º const
int FALSE=0; |
const int BufSize=1024, TRUE=1; |
// const qualifie int, |
// donc s'applique aussi à TRUE |
const int cst1=1, const cst2=2; |
// Erreur, const s'applique à un type |
// --> ne pas précéder cst2 de const
|
- Elles doivent être initialisées :
double const e; // Erreur |
double const i=0; // OK.
|
- Elles ne peuvent pas être modifiées :
double const e=0; |
e = exp(1.); // Erreur
|
- Contrairement aux const du C, ce sont de ``vraies''
constantes utilisables par exemple pour dimensionner les tableaux.
Þ Préférer l'utilisation des constantes à celle des #define
const int maxDim=100; |
float tableau[maxDim];
|
C-II 16
á typeñ '*' identificateur';'
-
un pointeur est une variable qui contient l'adresse
d'une autre variable.
- un pointeur est une variable typée.
- pour les opérations arithmétiques avec les pointeurs,
l'unité est la taille de l'objet pointé.
int i,j; |
int *iptr, k; |
// iptr pointeur sur entier MAIS k entier
|
-
& est l'opérateur de ``référençage'';
- * est l'opérateur de ``deréférençage''.
iptr = &i; |
i = 5; // *iptr est égal à 5 |
(*iptr) = 6; // i a la valeur 6; |
iptr = & j;
|
Remarque : Le pointeur nil est 0 (NULL)
Attention : NULL!=NUL
C-II 17
Trois cas sont possibles...
-
Pointeur sur une valeur constante :
const int a = 3, b = 5; // b est constant |
const int * pt1 = &a, * pt2 = &b; |
// *pt1 et *pt2 sont constants |
int const * pt3 = pt1; // Ecriture valide |
pt1 = &b; // Ok |
*pt1 = 7; // Erreur
|
- Pointeur constant sur une valeur non constante :
int c = 3, d = 10; |
int * const pt2 = &c, * const pt3=&c; |
// pt2 et pt3 sont constants |
pt2 = &d; // Erreur |
*pt2 = 7; // Ok
|
- Pointeur constant sur une valeur constante :
const int a = 3, const b = 5; |
const int * const pt3 = &a; |
pt3 = &b; // Erreur |
*pt3 = 7; //Erreur
|
C-II 18
á typeñ '&' nom '=' lvalue';'
-
Une référence définit un alias d'un objet en
donnant un nouveau nom à un objet tout en assurant que toute
opération effectuée sur la référence est réalisée sur l'objet.
- Affecter une valeur à une référence ne change pas la
référence mais change la valeur de l'objet référencé.
int red = 2, blanc = 0; |
int & white = blanc; |
white += 1; // blanc = 1 |
white = red; // blanc = 2 |
red=3; // blanc = 2 red = 3
|
- Une référence peut être utilisée à la place des pointeurs
pour accroître la lisibilité du code, réduire le coût du
passage de paramètre, optimiser la compilation.
- Une référence peut être utilisée comme variable ou
constante.
C-II 19
-
Une référence doit toujours être initialisée.
int blanc = 0; |
int & x; // Erreur |
int & y=blanc; // OK
|
- La valeur initialisant une référence (non constante)
doit être une LVALUE.
-
une lvalue est une EXPRESSION pouvant apparaître en
partie gauche d'une affectation : variable, cellule d'un
tableau, pointeur déréférencé, ...
- une rvalue est une EXPRESSION pouvant apparaître en
partie droite d'une affectation : variable, cellule d'un
tableau, pointeur déréférencé, ..., VALEUR LITTERALE.
-->
IL EST IMPOSSIBLE DE FAIRE UNE AFFECTATION D'UNE RVALUE DANS
UNE REFERENCE.
int & red1 = 2; // Erreur 2 est une rvalue |
const int & red1 = 2; // OK car réf. CONSTANTE
|
C-II 20
Expressions et Opérateurs
-
Définition
- Opérateurs arithmétiques
- Opérateurs d'incrémentation/décrémentation
- Opérateurs logiques
- Opérateur d'affectation
- Opérateurs relationnels
- Opérateurs d'accès aux objets
C-II 21
-
Une expression se compose d'une ou de plusieurs opérations.
- Différents types d'opérations :
-
°
- Opérateurs arithmétiques.
- °
- Opérateurs logiques.
- °
- Opérateur d'affectation.
- °
- Opérateurs relationnels.
- °
- Opérateurs d'accès aux objets.
- °
- Conversion de type.
- L'ordre d'évaluation dans une expression est déterminé par
des règles de priorité et d'associativité.
- Important :
le type de donnée du résultat est déterminé par le type des
opérandes.
C-II 22
Opérateur |
Rôle |
Usage |
+ |
addition (binaire) |
expr + expr + ... |
|
|
|
- |
soustraction (unaire) |
- expr |
- |
soustraction (binaire) |
expr - expr |
|
|
|
* |
multiplication (binaire) |
expr * expr |
|
|
|
/ |
division (binaire) |
expr / expr |
|
|
|
% |
modulo (binaire) |
expr % expr |
Fonctions supplémentaires disponibles dans la bibliothèque
mathématique : pow
, exp
, log
, sin
, etc.
fichier d'entête : <math.h>
bibliothèque : libm.a
C-II 23
Opérateurs d'incrémentation/décrémentation |
-
L'opérateur d'incrémentation (++) et l'opérateur de
décrémentation (--) fournissent un moyen efficace pour
compacter des écritures.
- [Post/Pré] [incr/décr]émentation :
x++ ; |
y-- ; |
post-incr(décr)émentation |
++x ; |
--y ; |
pré-incr(décr)émentation |
pile[x++] = val Û |
ì í î |
|
pile[x] = val ; |
x = x + 1 ; |
|
|
val = pile[--x] Û |
ì í î |
|
x = x - 1 ; |
val = pile[x] ; |
|
|
Ecrire ce qui se passe pour pile[++x] = val ; et val = pile[x--] ;.
C-II 24
Opérateur |
Rôle |
Usage |
& |
Et |
op1 & op2 |
|
|
|
| |
Ou (inclusif) |
op1 | op2 |
|
|
|
^ |
Ou exclusif |
op1 ^ op2 |
|
|
|
~ |
Négation |
~ op1 |
|
|
|
<< |
décalage à gauche (× 2) |
op1 << op2 |
|
|
|
>> |
décalage à droite (÷ 2) |
op1 >> op2 |
Ecrire les expressions pour tester :
- si le k-ième bit d'un entier est à 1,
- l'égalité du k-ième et i-ième bits d'un entier.
C-II 25
-
Retourne la valeur affectée :
double x,y,z; |
x = y = z = -1.;
|
- Combinaison possible avec un opérateur arithmétique ou logique :
+=, *=, -=, /=, %=, ...
a = a + 2 ; |
Þ |
a += 2 ; |
y = y & 0x0f ; |
Þ |
y &= 0x0f ; |
x = x * (y + z) ; |
Þ |
x *= y + z ; |
C-II 26
Opérateur |
Rôle |
Usage |
== |
égalité |
expr == expr |
!= |
inégalité |
expr != expr |
> |
stt supérieur |
expr > expr |
>= |
stt supérieur ou égal |
expr >= expr |
< |
inférieur |
expr < expr |
<= |
inférieur ou égal |
expr <= expr |
! |
non logique |
!expr |
&& |
et logique |
expr && expr |
|| |
ou logique |
expr || expr |
-
Le résultat est une expression booléenne,
- Attention : arrêt de
l'évaluation dès que le premier opérande
est faux (dans le cas &&) ou vrai (dans le cas ||).
C-II 27
-
Opérateur conditionnel arithmétique (ternaire).
áexp1ñ ? áexp2ñ : áexp3ñ |
|
c = ( a > b) ? a : b ; |
- Valeur en unité machine de la taille d'un type : sizeof.
-
° sizeof (identificateur)
- ° sizeof (type)
- Absorption
,
a = (i++,j++) ; |
º |
i++; |
|
|
a = j; |
|
|
j++; |
C-II 28
Opérateurs d'accès aux objets |
Opérateur |
Rôle |
Usage |
& |
adresse |
&expr |
* |
contenu |
*expr |
[ ... ] |
indexation |
expr[i] |
. |
sélecteur de champ |
expr.x |
-> |
sélecteur de champ |
expr-> x |
:: |
portée |
::expr |
Attention : de multiples rôles pour les symbôles '&' et
'*' :
|
Rôle |
& |
référence dans une déclaration, |
|
opérateur logique ET dans une expression, |
|
opérateur adresse devant une variable. |
* |
pointeur dans une déclaration, |
|
accés au contenu devant un pointeur, |
|
opérateur de multiplication dans une expression. |
-->
rôles mutuellement exclusifs.
C-II 29
Instructions de contrôle
-
Instruction Conditionnelle
- Instruction de choix
- Instructions d'itérations
- Instructions de ruptures
C-II 30
Deux types d'instructions
-
Les instructions simples terminées par un ';'
- Les instructions composées utilisant { ··· }
{ ··· } est un bloc.
Structuration des instructions par
-
instructions conditionnelles,
- instructions de choix,
- instructions d'itération.
C-II 31
Instruction conditionnelle |
if '('á expressionñ')' á
instruction1ñ |
[ else á instruction2ñ ] |
|
Ou en cascade |
|
if '('á expression1ñ')' ··· |
else |
if '('á expression2ñ')' ··· |
else |
if '('á expression3ñ')' ···
|
-
Vérifie les conditions séquentiellement et exécute les
instructions de la première évaluée à true.
C-II 32
Exemple d'instructions conditionnelles
#include <math.h> |
// calcul des racines |
... |
double delta = b*b - 4*a*c; |
if (delta < 0) cout << "pas de sol. "; |
else if (delta == 0) |
cout << "rac. double " << b/(2*a); |
else { |
double rac = sqrt (delta); |
cout << "rac." << (-b+rac)/(2*a) |
"et" << (-b-rac)/(2*a)); |
} |
...
|
C-II 33
switch '('á expressionñ')' { |
[case á csteñ ':'] [á
instructionñ] |
[break ';'] |
[default ':' [á instruction ñ]] |
}
|
-
á csteñ doit être un scalaire.
- La sortie d'une alternative se fait par l'utilisation de
l'instruction break ; sinon on passe à l'alternative
suivante (``break through'').
- L'ordre des scalaires est quelconque, MAIS les
scalaires doivent être TOUS différents.
switch(expression_entiere)
{
case valeur1 : liste_instructions
case valeur2 : liste_instructions
...
case valeurN : liste_instructions
default : liste_instructions
/* Facultatif */
}
C-II 34
Exemple d'instruction de choix
// Compter le nb voyelles, nb blancs ou TAB, |
// et le nb des autres caractères. |
int main (void) |
{ |
int nbv, nbb, nba, flag=1; |
char c; |
|
nbb = nba = nbv = 0; |
while (flag) { |
cin.get(c); |
if(cin.eof()) flag = 0; // end-of-file |
else { |
switch (c) { |
case 'a' : case 'e' : |
case 'i' : case 'o' : |
case 'u' : case 'y' : nbv++; break; |
case ' ' : |
case '\t': nbb++; break; |
default : nba++; |
} } } |
cout << nbv << ``voyelles, '' << nbb |
<< `` blancs '' << nba << `` autres''; |
}
|
C-II 35
C-II 36
Exemple d'instructions d'itération
// Calcul de puissance ab par |
// multiplications successives. |
int puis( int a, int b) |
{ |
int p = 1; |
#ifdef SIMPLE |
for (int i = 0; i < b; i += 1) p = p * a; |
#else |
for (int i = 0; i < b; |
p *= a, i += 1) {;} |
// Corps de boucle est l'instruction vide. |
#endif |
return p; |
} |
|
// Calcul de factorielle |
int fact( int n) |
{ |
int i = n; |
while (n>=0) i *= --n; |
return i; }
|
C-II 37
C-II 38
Exemple d'instructions de rupture
#include<stdio.h> |
... |
// écriture dans un tableau avec arrêt dès que |
// le tableau est plein ou que fin d'entrée |
char tab[100]; |
int i, c, j; |
for (i=0; i < 100; i++) { |
c = getchar() ; |
if (c == EOF) break; |
tab[i] = c; // c!= EOF |
} |
// i a le nombre exact d'elts du tableau |
... |
for (j=0;j<i;j++) { |
// traite toutes les entrées sauf |
// celles commençant par # |
if (tab[j] == '#') continue; |
traite_val(tab[j]); |
} |
...
|
C-II 39
Entrées/Sorties
-
Entrées/Sorties en C
- Entrées/Sorties en C++
-
La classe istream
- La classe ostream
C-II 40
-
Définitions de types, constantes et fonctions dans la
bibliothèque standard du C,
Déclarations dans <stdio.h>
- Type ``descripteur de fichier'': FILE
- Constante de fin de fichier : EOF
- Trois flux ``standards'' d'entrées-sorties :
-
Flux d'entrée standard : stdin
- Flux de sortie standard : stdout
- Flux d'erreurs standard : stderr
- De nombreuses fonctions et macros pour :
-
ouverture/fermeture de fichiers;
- lecture/écriture;
- positionnement dans un fichier;
- gestion des erreurs.
C-II 41
E/S en C : Fonctions de base |
Ensemble de fonctions d'E/S sur stdin/stdout :
-
Écriture d'un caractère sur stdout :
putchar(c);
- Lecture d'un caractère sur stdin :
int c;
c = getchar();
if (c != EOF) {...}
- Écriture formatée sur stdout :
printf ("format",
arg1, ... , argn);
- Lecture formatée sur stdin :
scanf ("format",
adr1, ... , adrn);
- ...
if (scanf("%f %f",&x,&y) != 2) |
printf("mauvaise lecture\n."); |
else |
printf("x=%lf, y=%lf\n",x,y);
|
C-II 42
#include <stdio.h> |
|
int lectecr1 (void) { |
int c; /* Noter def. comme int */ |
c=getchar(); |
while (c != EOF) { |
putchar(c); c=getchar(); |
} |
return 0; |
} |
|
int lectecr2 (void) { |
int c; |
while ((c=getchar()) != EOF) putchar(c); |
return 0; |
}
|
C-II 43
Extension des entrées/sorties standards du C par des classes :
stream et iostream
-
I/O standard implantées par des instances particulières de ces classes
stdin |
Þ |
cin |
stdout |
Þ |
cout |
stderr |
Þ |
cerr |
- Utilisation de ces instances et des opérateurs d'entrée/sortie :
-
Définis pour les types de base du langage.
- Possibilité de les surcharger.
- Définitions dans iostream.h
C-II 44
Exemple
#include <iostream.h> |
... |
int a, b; |
cout << "Entrez deux valeurs : "; |
cin >> a >> b; // ! et non &a, &b |
cout << a << " + " << b; |
cout << " = " << a+b << endl; |
... |
Personne p; |
cin >> p; // si redéfini |
// pour classe Personne |
... |