Académique Documents
Professionnel Documents
Culture Documents
Langages de Programmation :
Langage C
En C
Program Nom_prog ;
Uses crt, ;
Const PI=3.14 ;
Type nom_nouv_type = type;
Var i,j : integer;
Function nom_fct(paramtres) : type_retour ;
Var p : integer ;
Begin
P := 0;
{Commentaire : pascal ne fait pas de diff
entre maj P et min p }
nom_fct := ;
End ;
#include<stdio.h>
#define PI 3.14
typedef type nom_nouv_type ;
int i,j ;
type_retour function nom_fct (parameters)
{
int p = 0;
/* Commentaire : C fait la diffrence entre
maj P et min p */
return () ;
}
void function nom_prd (paramtres)
{
;
}
void main()
{
;
}
Begin
;
End.
Langage C vers II
#include <stdio.h>
#define PI 3.14
#include <stdio.h>
#define PI 3.14
float f_surface(float);
void main()
{
float surface;
surface=f_surface(2.0);
printf("%f\n",surface);
}
void main()
{
float surface;
surface=f_surface(2.0);
printf("%f\n",surface);
}
les identificateurs
les mots-clefs
les commentaires
les constantes
les oprateurs
les signes de ponctuation.
On peut ajouter ces six groupes les commentaires, qui ne sont pas considrs par le pr
processeur.
Une constante entire peut tre reprsente de 3 manires diffrentes suivant la base dans
laquelle elle est crite :
dcimale : par exemple, 0 et 2437 sont des constantes entires dcimales.
octale : la reprsentation octale d'un entier correspond sa dcomposition en base 8.
Les constantes octales doivent commencer par un zro. Par exemple, les reprsentations
octales des entiers 0 et 255 sont respectivement 00 et 0377.
hexadcimale : la reprsentation hexadcimale d'un entier correspond sa
dcomposition en base 16. Les lettres de a/A f/F sont utilises pour reprsenter les
nombres de 10 15. Les constantes hexadcimales doivent commencer par 0x ou 0X.
Par exemple, les reprsentations hexadcimales de 14 et 255 sont respectivement 0xe et
0xff.
-
Une constante chane de caractres est une suite de caractres entours par des
guillemets. Par exemple,''Ceci est une chane de caractres'' (ATTENTION : en pascal
une chane est entoure par deux apostrophes ceci est une chane en pascal).
Elle peut contenir des caractres non imprimables, dsigns par les reprsentations vues
prcdemment. Par exemple, ''ligne 1 \n ligne 2''
A l'intrieur d'une chane de caractres, le caractre '' doit tre dsign par \''.
Enfin, le caractre \ suivi d'un passage la ligne est ignor. Cela permet de faire tenir de
longues chanes de caractres sur plusieurs lignes. Par exemple :
Sans espace
''ceci est une longue longue longue longue longue longue longue longue \
chane de caractres''
Remarque :
Le compilateur ajoute \0 la fin de la chane dans la mmoire.
Il faut savoir distinguer la constante caractre de la constante chane de caractre. Ainsi
x et "x" ne sont pas quivalents. Le premier reprsente la valeur numrique du caractre
x, le second est une chane ne comprenant quun caractre (la lettre x) en plus \0 final.
typedef int entier ; /* fait du nouveau nom entier un synonyme de int. Ce type peut
tre utilis dans des dclaration, des casts exactement comme int. */
tyedef char* STRING ; /* fait de string un synonyme de char* */
typedef struct noeud {
char* mot ;
int quantite ;
}ARBRE ; /*cre un nouveau type appel ARBRE (une structure) */
Dfinit le type par numration nomm couleur et dclare deux variables q1 et q2 de ce type.
(exemple : q1=rouge ; q2=jaune ; ..).
4
5. Dclaration de variables
Les variables doivent tre dclares avant dtre utilises. A une variable correspond un
espace en mmoire et un mcanisme permettant dadresser cet emplacement. En C une
variable est caractris par :
Son nom (un identificateur)
Son type (type de base ou type dfinie par lutilisateur)
Une dclaration de variables a la forme :
type
Exemples :
int var_globale1=0, var_globale2;
float var ;
int i,j,k ;
char backslash=\\ ;
int i=0 ;
float eps=1.0 e-5 ;
6. Dclaration de constantes
Les constantes doivent toutes tre dclares et initialises avant dtre utilises. Il existe 2
mthodes pour la dclaration des constantes.
Mthode 1 :
#define nom_cste valeur
/* Sans point virgule la fin */
Exemple : #define PI 3.14
Le compilateur ne rserve pas de place en mmoire. Les constantes dclares par #define
s'crivent traditionnellement en majuscules, mais ce n'est pas une obligation.
Mthode 2 :
const type nom_cste = valeur ;
Exemple : const float PI = 3.14 ;
Dans ce cas, le compilateur rserve de la place en mmoire (ici 4 octets), pour la variable PI,
mais dont on ne peut changer la valeur.
Remarques gnrales
1- Le type Boolen nexiste pas dans le langage C
2- Il ny a pas de notion de procdure en langage C
(On peut dire que une procdure
en langage C est une fonction sans rsultats void nom_procedure(paramtres) )
3- Le langage C ne permet pas de dclarer des fonctions lintrieur dautres fonctions
+ addition
soustraction
multiplication
/ division
% reste de la division (modulo) (pour les entiers)
Ces oprateurs agissent de la faon attendue sur les entiers comme sur les flottants. Leurs
seules spcificits sont les suivantes :
Contrairement d'autres langages, le C ne dispose que de la notation / pour dsigner la
fois la division entire et la division relle (loprateur div nexiste pas comme en
pascal).
o Si les deux oprandes sont de type entier, l'oprateur / produira une division
entire (quotient de la division).
o Par contre, il dlivrera une valeur flottante ds que lun des oprandes est un
flottant. Par exemple :
6
float x;
x = 3 / 2;
affecte x la valeur 1. Par contre
x = 3 / 2.0;
/* affecte x la valeur 1.5. */
L'oprateur % ne s'applique qu des oprandes de type entier.
Notons enfin quil n'y a pas en C doprateur effectuant llvation la puissance. De
faon gnrale, il faut utiliser la fonction pow(x,y) de la librairie math.h pour calculer
xy
Attention !!!!
Comme pour les oprateurs de comparaison, la valeur retourne par ces oprateurs est un int
qui vaut 0 si la condition est faux.
Dans une expression de type : expression1 op1 expression2 op2 ...expressionN , lvaluation
se fait de gauche droite et s'arrte ds que le rsultat final est dtermin. Par exemple dans
int i=18,j=0;
if ((i >= 0) && (i <= 9) && !(j == 0))
La dernire expression !(j == 0) ne sera pas value si i n'est pas entre 0 et 9.
7
|=
7. L'oprateur virgule
Une expression peut tre constitue d'une suite d'expressions spares par des virgules :
expression1, expression2, ..., expressionN
Cette expression est alors value de gauche droite. Sa valeur sera la valeur de l'expression
de droite. Par exemple, le programme
main()
{
int a, b;
b = ((a = 3), (a + 2));
// a=3 ; b=a+2 ;
printf(''\n b = %d \n'',b);
}
La valeur de b est 5
Autre exemple :
int i, j ;
i=(j=2, j++, j++); j=2; j=j+1; i=j; j=j+1; i = 3 et j = 4
La virgule sparant les arguments d'une fonction ou les dclarations de variables ne
reprsente pas l'oprateur virgule.
Main()
{
int i=5 ;
printf("ladresse mmoire de i est : %x ",&i) ;
}
Affiche sur lcran ladresse mmoire de i sous forme hexadcimale : exemple FFF4
Exemple 1 :
int a = -1;
unsigned int b = 25;
char c = X;
scanf(%d%u%c,&a,&b,&c);
10
Remarque:
On peut placer la longueur de la variable entre le signe % et la lettre spcificateur. Par
exemple %3d indique quon va lire un entier de 3 chiffres et le reste des chiffres
sont ignors. scanf ("%3d",&i) ;
Si lon spare les spcificateurs de format par des espaces ou par des virgules alors les
valeurs lire seront spares par les mmes sparateurs.
Exemple 2:
char alpha;
scanf("%d",&alpha);
Si l'utilisateur saisie 97 tout va bien, alpha devient le caractre dont le code ASCII
vaut 97 qui est a.
Si l'utilisateur saisie a, sa saisie est ignore (PB !!!).
Exemple 3: (***)
Tout caractre ou nombre saisi au clavier et non pris en compte par la fonction scanf est
rang dans le tampon dentr qui est de type FIFO (First In First Out).
#include <stdio.h>
void main()
{
char c1,c2;
printf("ENTRER UN CARACTERE: ");
scanf("%c",&c1);
printf("VOICI SON CODE ASCII EN HEXADECIMAL: %x\n",c1);
printf("ENTRER UN AUTRE CARACTERE: ");
scanf("%c",&c2);
printf("VOICI SON CODE ASCII EN HEXADECIMAL: %x\n",c2);
}
Excution (trace) :
Si l'utilisateur saisit K pour c1, le programme donnera l'cran d'excution suivant:
ENTRER UN CARACTERE: K lutilisateur saisi K puis il a appuy sur RETURN donc on a
dans le tampon le caractre LF qui a le code ASCII en hxa a
: le tampon LF FIFO
VOICI SON CODE ASCII EN HEXADECIMAL: 4b
ENTRER UN AUTRE CARACTERE: VOICI SON CODE ASCII EN HEXADECIMAL: a
11
Exemple :
#include <stdio.h>
void main()
{
char * CH;
gets(CH);
}
2.3. La fonction getchar() stdio.h
La fonction getchar permet la saisie d'un caractre (char). Elle appartient la bibliothque
stdio.h. Les 2 critures suivantes sont quivalentes:
char c;
printf("ENTRER UN CARACTERE: ");
scanf("%c",&c);
char c;
printf("ENTRER UN CARACTERE: ");
c = getchar();
Non formate, la fonction getchar est moins gourmande en place mmoire que scanf. Il vaut
mieux l'utiliser quand cela est possible; getchar utilise le flux d'entre exactement comme
scanf.
Autre fonction qui permet de saisir un seul caractre : int getch() ; de la bibliothque
conio.h . Cette fonction ne demande pas une validation par la touche entre pour rcuprer
le caractre saisi.
Exemple : c = getch() ;
Nous pouvons utiliser cette fonction sans rcupration du caractre saisi :
Exemple : getch () ;
12
Remarque:
1. printf ("%kd",n) ; Affiche au moins k caractres droite.
Exp1 : k=3 et n = 25 affiche _25 (tir bas remplace lespace)
Exp2 : k=2 et n = 355 affiche 355
2. printf ("%-kd",n) ; Affiche au moins k caractres gauche.
Exp1 : k=3 et n = 25 affiche 25_ (tir bas remplace lespace)
Exp2 : k=2 et n = 355 affiche 355
3. printf ("%f",x) ; Affiche le nombre rel en dcimal avec 6 chiffre aprs la virgule,
par dfaut.
Exp1 : x=1.5 1.500000
4. printf ("%kf",x) ; Affiche le nombre rel en dcimal avec 6 chiffre aprs la
virgule, par dfaut. Avec k reprsente la longueur minimale du
nombre.
Exp1 : k=9, x=1.5 _ _1.500000
5. printf ("%kf.J",x) ; Affiche le nombre rel en dcimal avec 6 chiffre aprs la
virgule, par dfaut. Avec k reprsente la longueur
minimale du nombre et J reprsente le nombre de chiffre
aprs la virgule.
Exp1 : k=9, J=3 ,x=1.5 _ _ _ _ _1.500
3.2. La fonction puts
Envoie une chane de caractres vers stdout et ajoute un saut de ligne (newline).
int puts (const char * s) ;
Exemple :
puts ( ceci est un exemple );
3.3. La fonction putchar
Envoie un caractre vers stdout (cran)
int putchar (int c) ;
Exemple :
char c ;
c= A
putchar (c);
putchar (B);
13
Si l'expression fournit une valeur diffrente de zro, alors le bloc d'instructions 1 est
excut
- Si lexpression fournit la valeur zro,
alors le bloc d'instructions2 est excut
- Attention !!! Les ( ), devant if , sont obligatoires.
Remarques :
o Les { } ne sont pas ncessaires lorsque les blocs ne comportent qu'une seule
instruction.
o On peut avoir des if imbriqus
Exemples :
if (a > b)
max = a;
else
max = b;
if (A-B)
printf("A est diffrent de B\n");
else
printf("A est gal B\n");
int a,b,c;
;
if (!a)
//quivalent if (a==0)
{
printf( cas o a = = 0 );
;
}
else // commentaire : cette partie traite le cas o a != 0
{
if (!b)
{
printf(cas o a != 0 et b = = 0);
;
21
}
else
{
printf(cas o a != 0 et b != 0 );
. ;
}
2. Instruction switch
Cest un moyen qui permet des choix multiples uniquement sur des entiers ou des caractres.
switch (choix)
{
case cst1 : liste d'instructions 1 ;
break;
case cst2 : liste d'instructions 1 ;
break;
.
default : liste instructions N ;
}
Remarques :
o Le bloc default nest pas obligatoire
o choix doit tre de type char ou int
o choix, cst1, cst2 et les autres valeurs sont de mme type
Linstruction break permet de sortir de linstruction switch. Elle est importante car si on ne la
met pas aprs chaque cas dexcution alors toutes les instructions aprs ce cas seront
excutes (bien sur sils ne sont pas suivis dune autre instruction break).
Exemple :
int mois ;
scanf(" %d" ,&mois) ;
switch ( mois )
{
case 1 : printf(" janvier" ) ; break ;
case 2 : printf(" fevrier" ) ; break ;
22
Exemple 1:
/* Afficher les nombres de 0 9 */
int I = 0;
while (I<10)
{
printf("%d \n", I);
I++;
}
/* Afficher les nombres de 0 9 */
int I = 0 ;
while (I<10)
printf(%d\n,I++);
/* Afficher les nombres de 1 10 */
int I = 0 ;
while (I<10)
printf(%d\n,++I);
Exemple2:
23
2. Structure do -While
do
{
bloc dinstructions;
} while ( expression );
- Le bloc d'instructions est excut au moins une fois et jusqu ce que l'expression fournit
une valeur gale zro (eq false).
- Les { } ne sont pas obligatoires, si le bloc dinstruction contient une seule instruction.
Une application typique de do - while est la saisie de donnes qui doivent remplir une certaine
condition.
float N;
do
{
printf("Introduisez un nombre entre 1 et 10 :");
scanf("%f", &N);
}
while (N<1 || N>10);
Exemple2 : division de deux entiers (diviseur doit tre diffrent de zro)
int n, div;
printf("Entrez le nombre diviser : ");
scanf("%d", &n);
do
{
printf("Entrez le diviseur ( != 0) : ");
scanf("%d", &div);
}
while (!div); //while (div==0)
printf("%d / %d = %f\n", n, div, (float)n/div);
Exemple3 : Lecture dun nombre rel positif
float N;
do
{
printf("Entrer un nombre (>= 0) : ");
scanf("%f", &N)
}
while (N < 0);
printf("La racine carre de %.2f est %.2f\n", N, sqrt(N));
3. Structure for
La structure pour en langage algorithmique est utilises pour faciliter la programmation de
boucles de comptage. La structure for en C est plus gnrale et beaucoup plus puissante.
for ( expr1 ; expr2 ; expr3 )
{
bloc d'instructions ;
}
Est quivalente :
expr1;
while (expr2 )
{
bloc d'instructions
expr3 ;
}
25
expr1 est value une fois avant le passage de la boucle. Elle est utilise pour initialiser les
donnes de la boucle.
expr2 est value avant chaque passage de la boucle. Elle est utilise pour dcider si la boucle
est rpte ou non.
expr3 est value la fin de chaque passage de la boucle. Elle est utilise pour rinitialiser les
donnes de la boucle.
En pratique, les parties expr1 et expr2 contiennent souvent plusieurs initialisations ou
rinitialisations, spares par des virgules.
Exemple1:
/* affichage des carrs des nombres entiers compris entre 0 et 20 */
int I;
for (I=0 ; I<=20 ; I++)
printf("Le carr de %d est %d \n", I, I*I);
/* Autre version : nest pas lisible */
int I;
for (I=0 ; I<=20 ; printf("Le carr de %d est %d \n", I, I*I), I++)
;
Exemple2 : Somme des nombres de 1 100
int n, tot;
for (tot=0, n=1 ; n<101 ; n++)
tot+=n;
printf("La somme des nombres de 1 100 est %d\n", tot);
26
son adresse, cest dire ladresse mmoire partir de laquelle lobjet est stock.
sa valeur, cest dire ce qui est stock cette adresse.
Adressage indirect: Accs au contenu d'une variable, en passant par un pointeur qui contient
l'adresse de la variable.
Exemple :
Soit A une variable contenant la valeur 10 et P un pointeur qui contient l'adresse de A. En
mmoire, A et P peuvent se prsenter comme suit:
Inta,P ;
P = &a ;
3. Notion de pointeur :
Un pointeur est une variable dont la valeur est gale ladresse dun autre objet. On dclare un
pointeur par linstruction suivante :
Type * nom_du_pointeur ;
Type de lobjet point
Exemple :
// En Langage C
char * pc;
/*pc est un pointeur pointant sur un objet de type char*/
int *pi;
/*pi est un pointeur pointant sur un objet de type int*/
float *pf;
/*pf est un pointeur pointant sur un objet de type float*/
27
4. Allocation dynamique
Lorsque l'on dclare une variable char, int, float .... Un nombre de cases mmoire bien dfini est
rserv pour cette variable. Il n'en est pas de mme avec les pointeurs. Avant de manipuler un
pointeur, il faut linitialiser soit par une allocation dynamique soit par une affectation
dadresse p=&i. Sinon, par dfaut la valeur du pointeur est gale une constante symbolique
note NULL dfinie dans stdio.h En gnral, cette constante vaut 0.
On peut initialiser un pointeur p par une affectation sur p. Mais il faut dabord rserver p un
espace mmoire de taille adquate. Ladresse de cet espace mmoire sera la valeur de p. Cette
opration consistant rserver un espace mmoire pour stocker lobjet point sappelle allocation
dynamique. Elle se fait en C par la fonction malloc de la librairie standard stdlib.h Sa syntaxe
est la suivante :
char* malloc (nbr_octets)
Cette fonction retourne un pointeur de type char* pointant vers un objet de taille nbr_octets.
Pour initialiser des pointeurs vers des objets qui ne sont pas de type char*, il faut convertir le type
de la sortie de la fonction malloc laide dun cast.
Exemples : la fonction malloc
Exemple 1 :
char *pc;
int *pi,*pj,*pk;
float *pr;
pc = (char*)malloc(10);
/* on rserve 10 octets mmoire, soit la place pour 10 caractres */
pi = (int*)malloc(16);
/* on rserve 16 octets mmoire, soit la place pour 4 entiers */
pr = (float*)malloc(24);
/* on rserve 24 places en mmoire, soit la place pour 6 rels */
pj = (int*)malloc(sizeof(int)); /* on rserve la taille d'un entier en mmoire */
pk = (int*)malloc(3*sizeof(int));
/* on rserve la place en mmoire pour 3 entiers
on force le type int* */
28
Exemple 2 :
Le programme suivant :
#include <stdio.h>
#include <stdlib.h>
void main()
{
int *p ;
/* p est un pointeur vers un objet de type int */
printf( la valeur de p avant initialisation est : %d ,p) ;
p = (int*) malloc (sizeof(int)) ;
printf( \n la valeur de p aprs initialisation est :%x ,p) ;
*p = 2;
/* p contient la valeur 2 */
printf( \n la valeur de *p est :%d ,*p) ;
}
Imprime :
La valeur de p avant initialisation est : 0
La valeur de p aprs initialisation est : ff11
La valeur de *p est : 2
Analyse de lexemple :
Avant lallocation dynamique, *p na aucun sens et toute manipulation de *p gnrerait lerreur
suivante : segmentation fault.
Lallocation dynamique a pour rsultat dattribuer une valeur p et de rserver cette adresse un
espace mmoire compos de 4 octets pour stocker la valeur de *p.
Remarque1 :
Dans le programme :
#include <stdio.h>
main()
{ int i ;
int * p ;
p=&i ; }
Est quivalent :
Int n=10;
Int *p ;
p= (int*) malloc (n * sizeof(int)); /* tableau de n entiers*/
For (i=0; i<n; i++) *(p+i)=0;
29
Enfin, lorsque lon na plus besoin de lespace mmoire alloue dynamiquement c'est--dire quand
on nutilise plus le pointeur p, il faut librer cette place en mmoire. Ceci se fait laide de
linstruction free qui a pour syntaxe :
free( nom_du_pointeur) ;
Libration de la mmoire : la fonction free
pi = (int*)malloc(16);
/* on rserve 16 octets en mmoire : la place pour 4 entiers */
pr = (float*)malloc(24);
/* on rserve 24 octets en mmoire : la place pour 6 rels */
.
free(pi);
/* on libre la place prcdemment rserve pour pi */
free(pr);
/* on libre la place prcdemment rserve pour pr */
Remarque :
*p++ quivalente *(p++)
++*p quivalente ++(*p)
*++p quivalente *(++p)
30
Dclaration et mmorisation
Dclaration
Dclaration de tableaux en C :
TypeSimple NomTableau [nombreCases] ;
Les noms des tableaux sont des identificateurs.
Exemples :
int notes [8] ; /* dclaration dun tableau nomm notes, de type int et de dimension 8 */
char tab [100] ; /* dclaration dun tableaux nomm tab, de type char et de dimension 100 */
float moy[40] ; /* dclaration dun tableau nomm moy, de type float et de dimention 100 */
Mmorisation
En C, le nom d'un tableau est le reprsentant de l'adresse du premier lment du tableau. Les
adresses des autres composantes sont calcules (automatiquement) relativement cette adresse.
Exemple:
char A[5] = {A, 66, 70, C, 240};
65
66
70
67
240
..
Lors de la dclaration d'un tableau, on peut initialiser les composantes du tableau, en indiquant la
liste des valeurs respectives entre accolades.
Exemples :
int A[5] = {10, 20, 30, 40, 50};
float B[4] = {-1.05, 3.33, 87e-5, -12.3E4};
int C[10] = {1, 0, 0, 1, 1};
Il faut videmment veiller ce que le nombre de valeurs dans la liste corresponde la dimension
du tableau. Si la liste ne contient pas assez de valeurs pour toutes les composantes, les composantes
restantes sont initialises par zro.
31
Si la dimension n'est pas indique explicitement lors de l'initialisation, alors l'ordinateur rserve
automatiquement le nombre d'octets ncessaires.
Exemples
int A[] = {10, 20, 30, 40, 50};
==> Rservation de 5*sizeof(int) octets
float B[] = {-1.05, 3.33, 87e-5, -12.3E4};
==> Rservation de 4*sizeof(float) octets
En dclarant un tableau par int A[5]; nous avons dfini un tableau A avec cinq composantes,
auxquelles on peut accder par:
A[0], A[1], ... , A[4]
Exemple :
Affichage et affectation
La structure for se prte particulirement bien au travail avec les tableaux. La plupart des
applications se laissent implmenter par simple modification des exemples-types de l'affichage et
de l'affectation.
int A[5];
int I; /* Compteur */
for (I=0; I<5; I++)
printf("%d ", A[I]);
int A[5];
int I; /* Compteur */
for (I=0; I<5; I++)
scanf("%d", &A[I]);
32
Dclaration et mmorisation
dclaration
Mmorisation
Comme pour les tableaux une dimension, le nom d'un tableau est le reprsentant de l'adresse du
premier lment du tableau (c--d l'adresse de la premire ligne du tableau). Les composantes d'un
tableau deux dimensions sont stockes ligne par ligne dans la mmoire.
Exemple: Mmorisation d'un tableau deux dimensions
short A[3][2] = {{1, 2 },
{10, 20 },
{100, 200}};
.
10
20
100
200
..
Lors de la dclaration d'un tableau, on peut initialiser les composantes du tableau, en indiquant la
liste des valeurs respectives entre accolades. A l'intrieur de la liste, les composantes de chaque
ligne du tableau sont encore une fois comprises entre accolades. Pour amliorer la lisibilit des
programmes, on peut indiquer les composantes dans plusieurs lignes.
Exemples
int A[3][10] ={{ 0,10,20,30,40,50,60,70,80,90},
{10,11,12,13,14,15,16,17,18,19},
{ 1,12,23,34,45,56,67,78,89,90}};
float B[3][2] = {{-1.05, -1.10 },
{86e-5, 87e-5 },
{-12.5E4, -12.3E4}};
Lors de l'initialisation, les valeurs sont affectes ligne par ligne en passant de gauche droite. Nous
ne devons pas ncessairement indiquer toutes les valeurs: Les valeurs manquantes seront
initialises par zro. Il est cependant dfendu d'indiquer trop de valeurs pour un tableau.
Si le nombre de lignes L n'est pas indiqu explicitement lors de l'initialisation, l'ordinateur
rserve automatiquement le nombre d'octets ncessaires.
33
Laccs un lment dun tableau deux dimensions se fait selon le schma suivant :
NomTableau[Ligne][Colonne]
Les lments d'un tableau de dimensions L et C se prsentent de la faon suivante:
A[0][0]
A[1][0]
A[2][0]
. . .
A[L-1][0]
A[0][1]
A[1][1]
A[2][1]
. . .
A[L-1][1]
A[0][2]
A[1][2]
A[2][2]
. . .
A[L-1][2]
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
A[0][C-1]
A[1][C-1]
A[2][C-1]
. . .
A[L-1][C-1]
Affichage et affectation
Lors du travail avec les tableaux deux dimensions, nous utiliserons deux indices (p.ex: I et J), et
la structure for, souvent imbrique, pour parcourir les lignes et les colonnes des tableaux.
int A[5][10];
int I,J;
/* Pour chaque ligne ... */
for (I=0; I<5; I++)
{
/* ... considrer chaque composante (colonne) */
for (J=0; J<10; J++)
printf("%7d", A[I][J]);
}
3. Pointeurs et tableaux :
Tout tableau en C est en fait un pointeur constant. Dans la dclaration :
int tab[10] ;
34
tab est un pointeur constant non modifiable dont la valeur est ladresse du premier lment du
tableau. Autrement dit tab a pour valeur &tab[0]. On peut donc utiliser un pointeur initialise tab
pour parcourir les lments du tableau.
Exemple :
int tab[5] = {2,1,0,8,4} ;
int *p ;
p= tab ;
/* ou p= &tab[0]; adresse du premier lment */
for (int i=0 ; i<5 ; i++)
{
printf ( %d \n,*p);
p++ ;
}
4. Tableau de pointeurs :
La dclaration dun tableau de pointeur se fait comme suit :
Type * NomTableau [N]
Cest la dclaration dun tableau NomTableau de N pointeurs sur des donnes du type Type.
Exemple :
char *JOUR[] = {"dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"};
/* affichage des 7 chane de caractres */
for (int I=0; I<7; I++) printf("%s\n", JOUR[I]);
/* affichage des premires lettres des jours de la semaine */
for (I=0; I<7; I++) printf("%c\n", *JOUR[I]);
/* affichage de la 3 eme lettre de chaque jourde la semaine */
for (I=0; i<7; I++) printf("%c\n",*(JOUR[I]+2));
35
Remarques :
Vous ne pouvez pas le droit de :
Comparer deux tableaux ; exp : int tab1[3], tab2[3] ; if (tab1>tab2) { } ATTENTION!
Affecter un tableau un autre : exp : tab1 = tab2 ; ATTENTION!
Dclarer un tableau de taille dynamique comme lexemple suivant : int n = 4 ; char T[n] ;
36
un type simple
une structure (dfinie par struct ),
une runion (dfinie par union ),
un pointeur,
void (la fonction correspond alors une 'procdure')
Une fonction ne peut pas fournir comme rsultat des tableaux, des chanes de caractres ou
des fonctions. Mais, il est cependant possible de renvoyer un pointeur sur le premier lment
d'un tableau ou d'une chane de caractres.
Si une fonction ne fournit pas de rsultat, il faut indiquer void (vide) comme type du rsultat.
Si une fonction n'a pas de paramtres, on peut dclarer la liste des paramtres comme (void)
ou simplement comme () .
Le type par dfaut est int; autrement dit: si le type d'une fonction n'est pas dclar
explicitement, elle est automatiquement du type int.
Il est interdit de dfinir des fonctions l'intrieur d'une autre fonction (comme en Pascal).
En principe, l'ordre des dfinitions dans le texte du programme ne joue pas de rle, mais
chaque fonction doit tre dclare ou dfinie avant d'tre appele.
37
Syntaxe correcte :
#include <stdio.h>
void PERMUTER (int X,int Y)
{
int tampon;
tampon = X;
X = Y;
Y = tampon;
}
#include <stdio.h>
void PERMUTER (int *px,int *py)
{
int tampon;
tampon = *px;
*px = *py;
*py = tampon;
}
void main()
{
int A = 5 , B = 8;
PERMUTER(A,B);
printf( A=%d\n , A) ;
printf( B=%d\n , B) ;
}
PASSAGE DES PARAMETRES
PAR VALEUR
void main()
{
int A = 5 , B = 8 ;
PERMUTER(&A,&B);
printf( A=%d\n , A) ;
printf( B=%d\n , B) ;
}
PASSAGE DES PARAMETRES
PAR ADRESSE
38
Explication1: Lors de l'appel, les valeurs de A et B sont copies dans les paramtres X et Y.
PERMUTER change bien contenu des variables locales X et Y, mais les valeurs de A et B restent
les mmes.
Explication2: Lors de l'appel, les adresses de A et B sont copies dans les pointeurs px et py.
PERMUTER change ensuite le contenu des adresses indiques par les pointeurs A et B.
Remarque :
Pour qu'une fonction puisse travailler correctement avec un tableau qui n'est pas du type char, il
faut aussi fournir la dimension du tableau ou le nombre d'lments traiter comme paramtre,
sinon la fonction risque de sortir du domaine du tableau.
39
#include <stdio.h>
main()
{
/* Prototype de la fonction SOMME */
float SOMME(float *A, int N, int M);
/* SOMME(&T[0][0], 3, 4) ); */
/* Dclaration de la matrice */
float T[3][4] = {{1, 2, 3, 4},
{5, 6, 7, 8},
{9,10,11,12}};
/* Appel de la fonction SOMME */
printf("Somme des lments : %f \n",
SOMME((float*)T, 3, 4) );
return 0;
}
Remarque : protection des variables de type tableau lors du passage comme paramtre dans une
fonction ; exemple : int lire_tab (const char *t) ;
40
2. Dclaration de structure :
Mthode 1 : dclaration en prcisant un nom pour la structure
struct
{
char nom[20];
char prenom[20];
int
n_cin;
} personne;
Dclare l'identificateur personne comme tant le nom d'un type de structure, compose de trois
membres. On peut ensuite utiliser ce type structure pour dclarer des variables, de la manire
suivante :
struct personne p1,p2; /* qui dclare deux variables de type
struct personne de noms p1 et p2 */
Mthode 2 : dclaration en prcisant un nom pour la structure et en dclarant des variables (combiner)
struct
{
char nom[20];
char prenom[20];
int n_cin;
} personne p1,p2;
Dclare les deux variables p1 et p2 et donne le nom personne la structure. L aussi, on pourra
utiliser ultrieurement le nom struct personne pour dclarer d'autres variables :
Mthode 4 : dclaration en utilisant typedef
typedef struct
/* On dfinit un type struct */
{
char nom[10];
char prenom[10];
int age;
float moyenne;
} fiche;
41
fiche f1,f2;
5. Affectation de structures :
On peut affecter une structure une variable structure de mme type.
struct personne pr1,pr2;
pr1 = pr2 ;
6. Comparaison de structures :
Aucune comparaison n'est possible sur les structures, mme pas les oprateurs == et !=.
42
7. Tableau de structures :
Une dclaration de tableau de structures se fait selon le mme modle que la dclaration d'un tableau dont
les lments sont de type simple. Supposons que l'on ait dj dclar la struct personne.
8. Composition de structures :
Une structure permet de dfinir un type. Ce type peut tre utilis dans la dclaration dune autre
structure comme type dun de ses champs.
Exemple :
struct
{
unsigned int jour;
unsigned int mois;
unsigned int annee ;
} date;
struct
{
char nom[20];
char prenom[20];
struct date d_naissance;
} personne;
9. Pointeur et structures :
Supposons que l'on ait dfini la struct personne l'aide de la dclaration :
struct
{
char nom[20] ;
unsigned int age ;
} personne;
On dclarera une variable de type pointeur vers une telle structure de la manire suivante :
struct personne *p ;
43
Corrig :
#include <stdio.h>
#include <conio.h>
typedef struct {int num;float x;float y;} point;
void main()
{
point p[4];
/* tableau de points */
int i;
float xx,yy;
/* saisie */
printf("SAISIE DES POINTS\n\n");
for(i=0;i<4;i++)
{
printf("\nRELEVE N %1d\n",i);
p[i].num = i;
printf("X= ");scanf("%f",&xx);
printf("Y= ");scanf("%f",&yy);
p[i].x = xx;p[i].y = yy;
}
/* relecture */
printf("\n\nRELECTURE\n\n");
for(i=0;i<4;i++)
{
printf("\nRELEVE N%1d",p[i].num);
printf("\nX= %f",p[i].x);
printf("\nY= %f\n",p[i].y);
}
printf("\n\nPOUR SORTIR FRAPPER UNE TOUCHE ");
getch();
}
45
1. Dclaration :
La dclaration dune chane de caractre se fait par lune des mthodes suivantes :
char NomChaine [Longueur];
OU
char * NomChaine ;
Exemple :
char NOM [20];
/* dclaration sans initialisation */
char PRENOM [] = "stream";
/* dclaration avec initialisation : tab de 7 caract "stream\0" */
char adresse1 [] = { c, h,a, r ,g,u,i,a,\0} ; /* dclaration avec initialisation */
char adresse2 [20] = { c, h,a, r ,g,u,i,a,\0} ; /* dclaration avec initialisation */
char * CH1 ;
/* dclaration sans initialisation */
char * CH2= " voila" ;
/* dclaration avec initialisation */
CH1 = " affectation permise" /* affectation permise*/
NOM = " chaine" /* !!!! attention affectation non permise*/
2. Mmorisation :
Le nom d'une chane est le reprsentant de l'adresse du premier caractre de la chane. Pour
mmoriser une variable qui doit tre capable de contenir un texte de N caractres, nous avons
besoin de N+1 octets en mmoire:
Exemple :
char TXT [10] = "BONJOUR !";
La concatnation est la juxtaposition de chanes afin den former une seule. Elle est ralise en C
laide de lune des deux fonctions strcat et strncat (string. h)
(A). La fonction strcat
Lappel de strcat se prsente ainsi :
char *strcat (char *destination, char *source)
Cette fonction recopie la seconde chane source la suite de la premire destination, aprs en
avoir effac le caractre de fin.
Remarques :
1. Aucun contrle de longueur nest ralis par cette fonction ; il est ncessaire que l'emplacement
rserv pour la premire chane soit suffisant pour y recevoir la partie lui concatner.
2. strcat fournit un rsultat :
ladresse de la chane correspondant la concatnation des deux chanes fournies en
argument, lorsque lopration sest bien droule. Qui est ladresse de destination.
Le pointeur NULL lorsque lopration est mal droule.
Examinons cet exemple :
#include <string.h>
main ()
{
char ch1[50]=bonjour ;
char *ch2=monsieur;
printf (avant :
%s\n , ch1);
strcat (ch1, ch2);
printf (aprs :
%s\n,ch 1);
}
Il faut noter la diffrence entre les deux dclarations (avec initialisation) de chacune des deux
chanes ch1 et ch2. La premire permet de rserver un emplacement plus grand que la constante
chane que y trouve place initialement.
(B). La fonction strncat
Cette fonction, dont lappel se prsente ainsi :
char* strncat (char *destination , char *source , int n)
47
Imprime su l'cran :
avant :bonjour
aprs :bonjour m
-
Il est possible de comparer deux chanes en utilisant lordre des caractres dfini par le code
ASCII.
Code ASCII de 'a' = 97 et celui de 'A' = 65 'a' > 'A'
(A).
Compare deux chanes et elle fournit une valeur entire dfinie comme tant :
positive
si ch1 > ch2
nulle cd 0 si ch1 = ch2
ngative
si ch 1 < ch2
Par exemple :
strcmp(bonjour , monsieur) est ngatif et
strcmp(Tunis2 , Tunis10) est positif.
(B).
Travaille comme strcmp mais elle limite la comparaison au nombre maximum de caractres
indiqu par lenlier lgmax.
Par exemple :
strncmp(bonjour , bon, 4) est positif tandis que
strcmp(bonjour , bon , 2)
vaut zro.
48
Travaillent respectivement comme strcmp et strncmp, mais sans tenir compte de la diffrence entre
majuscules et minuscules (pour les seuls caractres alphabtiques).
(A).
Procde de manire analogue strcpy, en faisant la recopie au nombre de caractres prciss par n.
Il faut noter que si la longueur de la chane source est infrieure cette longueur maximale (n) son
caractre de fin sera effectivement recopi. Mais dans le cas contraire, il ne le sera pas. Lexemple
suivant illustre les deux situations :
L'exemple suivant :
#include <string. h>
main()
{
On trouve des fonctions de recherche de loccurrence dans une chane, dun caractre ou dune
autre chane (nomme alors sous-chane).
Ces fonctions fournissent comme rsultat :
ladresse de linformation cherche on cas de succs
le pointeur null dans le cas contraire.
char *strchr (char *chane, char caractre)
(string.h)
49
(string.h)
Il existe trois fonctions permettant de convertir une chane de caractres en une valeur numrique
de type int, long ou double. Ces fonctions ignorent les ventuels espaces de dbut de chane et
utilisent les caractres suivant pour fabriquer une valeur numrique. Le premier caractre invalide
arrte lexploration. Par contre, si aucun caractre nest exploitable, ces fonctions fournissent un
rsultat nul (0).
atoi (chaine) (stdlib.h)
50
(stdlib.h)
(stdlib.h)
:0.000000e+00
Nous nous limiterons ici au fonctions de conversion dun entier en une chane (il existe des
fonction permettant de convenir un nombre flottant on une chane). Celles-ci permettent
dexprimer un nombre non seulement sous forme dune suite de chiffres en base 10, mais
galement dans nimporte quelle base comprise entre 2 et 36. Elles sont particulirement bien
adaptes pour afficher par exemple un nombre en binaire.
Ces trois fonctions fournissent en rsultat un pointeur sur la chane obtenue
char* itoa ( int entier,char *chaine, int base )
(stdlib.h)
Travaille avec un entier de type int.
char* itol ( long entier, char *chaine, int base )
Travaille avec un entier de type long.
51
(stdlib.h)
(stdlib.h)
Les fonctions de <ctype> servent classifier et convertir des caractres. Dans la suite, c
reprsente une valeur du type int qui peut tre reprsente comme caractre.
isupper(c) ; /* retourne une valeur diffrente de zro si c est une majuscule */
islower(c) ; /* retourne une valeur diffrente de zro si c est une minuscule */
isdigit (c) ; /* retourne une valeur diffrente de zro si c est un chiffre dcimal */
isalpha(c) ; /* retourne une valeur diffrente de zro si isupper(c) ou islower(c) */
isalnum(c) ; /* retourne une valeur diffrente de zro si isalpha(c) ou isdigit (c) */
isxdigit(c) ; /* retourne une valeur diffrente de zro si c est un chiffre hexadcimal */
isspace(c) ; /* retourne une valeur diffrente de zro si c est un signe despacement */
Les fonctions de conversion suivantes fournissent une valeur du type int qui peut tre
reprsente comme caractre; la valeur originale de c reste inchange:
char tolower(c) ; /* retourne c converti en minuscule si c est une majuscule */
char toupper(c) ; /* retourne c converti en majuscule si c est une minuscule */
52
Affectation : pas daffectation directe (genre JOUR [2] = "vendredi" ;). Utiliser strcpy
strcpy(JOUR[4], "Friday");
53
Bibliographie
[1] BEN RHOUMA Ons, HAMDI Omessad, SALEM Faten et ZAYANI Hafeth, "Langages de
fvrier 2003.
[6] Claude Delannoy, "Programmer en langage C : Cours et exercices corrigs", Edition avril 2002.
54