You are on page 1of 23

Exercice

Ecrire un programme qui vérifie si une chaîne est un


carré ou pas.

Définition :
Une chaîne de caractères est un carré si elle se compose de 2
chaînes identiques.
Exemple : "chercher" et "bonbon" sont des carrés.
.

1
2
Université Ibn Zohr - Faculté des Sciences

SMI3

Programmation I
Les fonctions

3
• Une fonction permet de :
– Remplacer une partie qui se répète
– Découper un programme en parties isolées -> débogage, lisibilité, etc..
• Exemples : fonctions d'E/S (scanf, printf, …), mathématiques (sin, cos, …)
• Organisation d'un programme :
type fonction1 (arguments) {
Déclarations de variables et de types locaux à la fonction
Instructions
}
type fonction2 (arguments) {
Déclarations de variables et de types locaux à la fonction
Instructions
}
...
void main (arguments) {
Déclarations de variables et de types locaux à la fonction
Instructions 4
Type de la
valeur de
retour Arguments

float plusGrand(float val1, float val2, float val3)


{ float grand;
if(val1>val2)
grand = val1;
else grand = val2; Instructions
if(grand < val3)
grand = val3;
return(grand) ;
} Valeur renvoyée

void main() {
float taille1, taille2, plusG;
printf("Donner deux tailles \n");
scanf("%f %f" ,&taille1,&taille2);
plusG = plusGrand( taille1, taille2, 1.85); Appel de la fonction
printf ("Le plus grand est %f\n",plusG); 5
}
type_fonction nom_fonction (type_arg1 arg1, …, type_argn argn) {

return (valeur retournée);
}

Dans l'exemple précédent :


type_fonction : float, c'est le type de la valeur renvoyée par return
nom_fonction : plusGrand

Le nombre d'arguments est quelconque, éventuellement aucun, les parenthèses


doivent toujours figurer (ex: main () )

6
• Une fonction peut ne pas renvoyer de valeur.
• Exemple void plusGrand(float val1, float val2, float val3)
{ float grand;
if(val1>val2)
grand = val1;
else grand = val2;

if(grand < val3)


grand = val3;
printf ("Le plus grand est %f\n",grand);
return() ;
}

• Dans ce cas, le type de la fonction est : void


• Le type de la fonction ne peut être que :
• int, float, char, ou adresse de
• ni tableau, ni autre type complexe
7
1/ Indique la valeur de retour de la fonction.
2/ Arrête l'exécution de la fonction
float plusGrand(float val1, float val2, float val3)
{ float grand;
if(val1>val2)
grand = val1;
else grand = val2;
if(grand < val3)
grand = val3;
return(grand) ;
printf ("%f",grand); /*jamais exécutée*/
}
Pour les fonction de type void, return est optionnel
void plusGrand(float val1, float val2, float val3)
{ float grand;
if(val1>val2)
grand = val1;
else grand = val2;
if(grand < val3)
grand = val3;
printf ("%f",grand); 8
}
• L'appel d'une fonction se fait en donnant son nom, suivi de la liste des
paramètres entre parenthèses. L'ordre des paramètres correspond à celui des
arguments.
• Exemple
float puiss (float x, int n) {
int i;
float y=1.0;
if (n>0) for (i=1;i<=n;i++) y = y*x;
else if(n<0) for (i=1;i<=(-n);i++) y = y/x;
return (y);
}

void main () {
float z,t;
z = puiss(10.7,2);
t = puiss (z, 6);
... 9
• Un appel de fonction peut se faire comme opérande d'une expression, soit comme
paramètre d'un autre appel de fonction.
• Exemple
int maximum (int x, int y) {
return((x>y)?x,y);
}
void main () {
int v1,v2,v3,m1;
scanf("%d %d %d" , &v1,&v2,&v3);
m1 = maximum(v1,v2);
m1 = maximum(m1,v3);
printf("valeur maximale %d\n", m1);
}
ou bien
m1 =maximum(v1,v2);
printf("valeur maximale %d\n", maximum(m1,v3));
ou bien
printf("valeur maximale %d\n", maximum(maximum(v1,v2),v3)); 10
• Toute fonction ne peut appeler que des fonctions déclarées avant elle ou
elle-même (la fonction main ne peut pas s'appeler).
... f1 (..) {
...
}
... f2 (...) {
la fonction main peut appeler f1,f2,f3
...
la fonction f3 peut appeler f1,f2,f3
} la fonction f2 peut appeler f1, f2
... f3 (...) { la fonction f1 peut appeler f1
...
}
void main (...) {
...
}

• Lorsqu'une fonction s'appelle elle-même, on dit qu'elle est


"récursive".
11
• Règle précédente contraignante
• Solution : Prototype (Déclaration)
En début de programme on donne le type de chaque fonction , son nom, le
nombre et les types des arguments
• Information suffisante pour le compilateur.

float puiss (float,int); /*Prototype de la fonction puiss*/


void main(){
puiss (10.2, 5); /*Appel de la fonction */
...}

float puiss (float x, int n){


/*Définition de la fonction */
float y=1.0; int i;
if (n>0) for (i=1;i<=n;i++) y = y*x;
else if(n<0) for (i=1;i<=(-n);i++) y = y/x;
return (y);
}
12
• Rappel : les paramètres sont associés aux arguments suivant l'ordre de
déclaration.
• En c, cette association se fait par COPIE de la valeur du paramètre dans
l'argument. Chaque argument est en fait une variable locale de la fonction.
La fonction travaille sur l'argument.
• Conséquence : Une fonction ne modifie pas les paramètres d'appels
void f(int a){
a=a+1;
}
void main(){
int b;
b=0;
f(b);
printf("%d\n",b); ->0

}
13
void f (int a){
a=a+1; /*3*/
}
void main(){
int b;
b=0; /*1*/
f(b); /*2*/
printf("%d\n",b); /*4*/
}

b 0 b 0 b 0 b 0 Inchangé
Copie
a 0 a 1

/*1*/ /*2*/ /*3*/ /*4*/

14
• Si l'on veut qu'une fonction modifie un paramètre, on ne passe pas la
variable mais l'adresse de la variable. Il y a copie de l'adresse de la
variable. Dans la fonction on va chercher la variable par son adresse.

• Rappels :
opérateur & : & variable -> adresse de la variable
opérateur * : * adresse -> valeur qui se trouve à cette adresse

15
void f2 (int * a){ /* a est l'adresse, *a est l'entier */
*a=*a+1; /*t3 on incrémente le mot d'adresse a*/
}
void main(){
int b;
b=0; /*t1*/
f(&b); /*t2 &b est l'adresse de b */
printf("%d\n",b); /*t4*/ -> 1
}

b 0 728 b 0 b 1 *a b 1

&b 728 &b 728


Copie
a 728 a 728
/*t1*/ /*t2*/ /*t3*/ /*t4*/

Exemple : scanf ("%d",&v); 16


Exercice:
Ecrire une fonction qui permet d’échanger le
contenu de deux variable et tester la dans un
petit programme,

17
• Rappels:
– Lorsqu'on déclare un tableau, par ex int t[10], t est l'adresse du 1er
élément du tableau
– Chaque élément du tableau peut être accédé par t[i] ou *(t+i)
• Exemple
void printtab (int t1[50]) {
int i;
for (i=0;i<50;i++)
printf("%d",t1[i]);
}
void main () {
int t[50];
.....
printtab(t);
}
18
• Puisque la dimension n'est pas utilisée, on peut ne pas la
donner
void printtab (int t1[50]){
int i;
for (i=0;i<50;i++)
printf("%d",t1[i]); Syntaxes équivalentes
}
ou bien
void printtab (int t1[]) {
int i;
for (i=0;i<50;i++)
printf("%d",t1[i]);
}
19
Conséquence : on peut donc appeler cette fonction avec tout tableau d'entiers
quelle que soit sa dimension. C’est au programmeur à gérer les débordements
de tableau => donner le nombre de cases sur lequel travaille la fonction

void printtab (int t1[], int n){


int i;
for (i=0;i<n;i++)
printf("%d",t1[i]);
}

void main () {
int t[50],t2[100];
...
printtab(t,50); /*affiche toutes les cases de t de 0 à 49*/
printtab(t+20,30);/*affiche toutes les cases de t de 20 à 49*/
printtab(t+20,10);/*affiche toutes les cases de t de 20 à 30*/
20
}
Puisqu'en fait t1 est une adresse, on peut le déclarer comme tel

void printtab (int * t1, int n) {


int i;
for (i=0;i<n;i++)
printf("%d",t1[i]);
}

Fonction sans l’argument n ?

21
Conséquence :
Si un argument est de type tableau (c-à-d une adresse), la fonction peut
modifier les cases du tableau
void misea0 (int t1[], int n){
int i;
for (i=0;i<n;i++)
t1[i]=0;
}

void main () {
int t[10]={1,2,3,4,5,6,7,8,9,10};
printtab(t,10); -> 1 2 3 4 5 6 7 8 9 10
misea0(t,10);
printtab(t,10); -> 0 0 0 0 0 0 0 0 0 0
} 22
Pareil pour une chaine de caractères

int longueur_chaine(char *chaine)


{int i;
/* La marque de fin de chaîne est '\0' */
i =0;
while(chaine[i]!='\0') i++;
/*ou bien */
for (i=0; chaine[i]; i++) ;
return i;
}

23

You might also like