EXERCICE
1.)
Ce programme affiche : X=10, Y=9
En effet le deuxième paramètre, noté
M, de la procédure P est "passé par adresse". Cela signifie
que, quand on exécute P(X,Y), la variable Y elle-même sera
modifiée dans la mesure où le paramètre M le sera.
Ainsi l'affectation M:=M-1 enlèvera 1 à la variable globale
Y. Par conséquent, à la fin de l'exécution de la procédure
P, la variable Y contiendra 9.
Par contre, le premier paramètre, noté
N, de la procédure P est "passé par valeur". Cela signifie
que, quand on exécute P(X,Y), la valeur de la variable X elle-même
ne sera pas modifiée par une quelconque modification de N.
Par conséquent, à la fin de l'exécution de la procédure
P, la variable X contiendra toujours 10.
2.)
Nous avons choisi ici une fonction retournant la nouvelle valeur de M.
PROGRAM PassageDeParametres ;
Var X, Y : integer ;
FUNCTION P(N,M : integer) : integer ;
Begin
N:=N-1 ; M:=M-1 ;
P:=M ;
End ;
BEGIN
X:=10 ; Y:=10 ;
Y:=P(X,Y) ;
writeln('X= ',X:1,' , Y=',Y:1) ;
END.
3.)
En Pascal, une fonction retourne une valeur ce qui
n'est pas le cas d'une procédure. Par conséquent, on utilise
une procédure comme une nouvelle instruction du programme (instruction
qui possède éventuellement des paramètres) ;
au contraire une fonction sera utilisée comme une expression et
pourra être intégrée comme telle dans une affectation,
un test, etc.
Le choix alternatif entre fonction et procédure
dans un programme sera donc déterminé par ce qu'on veut faire.
Pour fixer les idées : pour décomposer un bloc de programme
trop long, par exemple, on utilisera une procédure, on utilisera
une fonction par contre pour effectuer un calcul donnant un résultat
(comme le fait une fonction mathématique).
Pour aller plus loin, ce qui précède
doit être nuancé par le fait qu'une "function", en Turbo Pascal,
ne peut pas retourner tout type de variable et qu'on est parfois amené
à remplacer une "function" par une "procedure". Au contraire, on
ne peut pas toujours remplacer, en Pascal, une "procedure" par une "function".
PROBLEME
Première partie :
1.1.)
Affichage* pour S='aha' :
1 , a : OK Retour : TRUE |
Affichage* pour S='houhou' :
2 , o : OK Retour : FALSE |
Affichage* pour S='ahaha' :
1 , a : OK 2 , h : OK Retour : TRUE |
Affichage* pour S='ohe' :
Retour : FALSE |
1.2.) On a choisi une fonction :
FUNCTION CREER(M:integer) : CHAINE ;
Var S, T : CHAINE ;
i : integer ;
c : char ;
Begin
(* initialisation *)
randomize ;
S:='' ; T:='' ;
(* construction de la chaîne par les deux bouts S et T *)
for i:=1 to (M div 2) do
begin
c:=CHR(random(26)+97) ;
S:=S+c ; T:=c+T ;
end ;
(* si la chaîne est de longueur impaire *)
(* il faut rajouter le caractère du milieu *)
if (M mod 2)=1
then S:=S+CHR(random(26)+97) ;
(* on retourne la chaîne obtenue *)
CREER:=S+T ;
End ;
Deuxième partie :
2.1.)
CONST NMAX=20 ; MMAX=25 ; (* par exemple *)
TYPE GRILLE = array[1..NMAX,1..MMAX] of char ;
2.2.) on a choisi ici une procédure.
PROCEDURE SAISIR(N,M : integer ; Var G : GRILLE) ;
Var i, j : integer ;
S : CHAINE ;
Begin
writeln('saisie de ',n,' chaînes de caractères') ;
for i:=1 to n do
(* pour chaque ligne *)
begin
(* saisie d'une chaine de longueur M *)
repeat
write(i,'-ième
chaîne ? ') ; readln(S) ;
if length(S)>M
then writeln('chaîne trop longue') ;
if length(S<M)
then writeln('chaîne trop courte) ;
until length(S)=M ;
(* rajouter la i-ième chaîne *)
(* dans la i-ième ligne de la grille
*)
for j:=1 to M do G[i,j]:=S[j] ;
end ;
End ;
2.3.) on a choisi ici une procédure.
PROCEDURE MODIFIER(N,M : integer ; Var G: GRILLE) ;
Var i, j : integer ;
c : char ;
Begin
writeln('Modifier une case G[ligne,colonne]')
(* saisir le numéro de la ligne *)
repeat
write('quelle ligne (1 à ',n,') ? ') ; readln(i) ;
until (i>=1) and (i<=N) ;
(* saisir le numéro de la colonne *)
repeat
write('quelle colonne (1 à ',M,') ? ') ; readln(j) ;
until (j>=1) and (j<=M) ;
(* saisir le nouveau caractère *)
writeln('l''ancien caractère en ',i,',',j,' est ',G[i,j]) ;
repeat
write('quel nouveau caractère (entre
''a'' et ''z'') ? ') ;
readln(c) ;
until (c>='a') and (c<='z') ;
(* modifier la grille *)
G[i,j]:=c ;
End ;
2.4.)
PROCEDURE AFFICHER(N,M : integer ; G : GRILLE) ;
Var i, j : integer ;
Begin
(* afficher l'en-tête *)
writeln('N=',N,' et M=',M) ; writeln ;
(* afficher les numéros de colonnes *)
writeln(' ':4) ;
for j:=1 to M do write(j:3) ;
writeln ;
(* afficher la grille *)
for i:=1 to N do
(* pour chaque ligne de la grille *)
begin
(* afficher le numéro de la ligne... *)
write(i:4) ;
(* ... et son contenu *)
for j:=1 to M do write(G[i,j]:3) ;
writeln ;
end ;
End ;
N.B. : Cette affichage est conçu pour des valeurs N<=20 et M<=25 afin de tenir dans un écran 24x80.
2.5.)
Cette première version est basée sur la fonction AGREABLE :
FUNCTION AGRILLABLE(N,M : integer ; G : GRILLE) : boolean ;
Var i, j : integer ;
test : boolean ;
S : CHAINE ;
Begin
test:=true ;
(* vérifier les lignes *)
for i:=1 to N do
begin
S:='' ;
for j:=1 to M do s:=s+G[i,j] ;
test:=(test and AGREABLE(S));
end ;
(* vérifier les colonnes *)
for j:=1 to M do
begin
S:='' ;
for i:=1 to N do S:=S+G[i,j] ;
test:=(test and AGREABLE(S)) ;
end ;
AGRILLABLE:=test ;
End ;
Voici une deuxième version n'utilisant pas la fonction AGREABLE :
FUNCTION AGRILLABLE(N,M : integer ; G : GRILLE) : boolean ;
Var i, j : integer ;
test : boolean ;
Begin
test:=true ;
for i:=1 to (N mod 2) do
for j:=1 to (M mod 2) do
if (G[i,j]<>G[i,M+1-j])
or
(G[i,j]<>G[N+1-i,j])
or
(G[i,j]<>G[N+1-i,M+1-j])
then
test:=false ;
AGRILLABLE:=test ;
End ;
2.6.) on a choisi ici aussi une procédure.
PROCEDURE CONSTRUIRE(N, M : integer ; Var G : GRILLE) ;
Var i, j : integer ;
S : CHAINE ;
Begin
for i:=1 to (N div 2)+(N mod 2) do
begin
S:=CREER(M) ;
for j:=1 to M do
begin
G[i,j]:=S[j] ;
G[N+1-i,M+1-j]:=S[j] ;
end ;
end ;
End ;
2.7.)
PROGRAM Probleme ;
CONST NMAX=20 ;
MMAX=25 ;
TYPE GRILLE = array[1..NMAX,1..MMAX] of char ;
VAR G : GRILLE ;
N, M : integer ;
choix : integer ;
BEGIN
(* reprendre au début du programme si on le souhaite *)
repeat
(* saisir N, M, puis la grille G *)
repeat
write('nombre de lignes
(1 à ',NMAX,') ? ') ;
readln(N) ;
until (N>=1) and (N>=NMAX) ;
repeat
write('nombre de colonnes
(1 à ',MMAX,') ? ') ;
readln(M) ;
until (M>=1) and (M>=MMAX) ;
SAISIR(N,M,G) ;
(* afficher la grille *)
AFFICHER(N,M,G) ;
(* vérifier si la grille est agréable et sinon ... *)
if (not AGRILLABLE(N,M,G))
then begin
writeln('Cette grille n'est pas agréable') ;
writeln ;
(* menu *)
writeln('Pour avoir une grille agréable : ') ;
writeln('1 : modifier la grille') ;
writeln('2 : remplacer la grille automatiquement') ;
repeat
write('votre choix ?') ;
readln(choix) ;
until (choix=1) or (choix=2) ;
case choix of
1 : repeat MODIFIER(N,M,G) ;
until AGRILLABLE(N,M,G) ;
2 : CONSTRUIRE(N,M,G) ;
end ;
end ;
(* demander si on reprend ... *)
write(reprendre (1 pour oui, 0 pour non) ? ')
;
readln(choix) ;
until choix=0 ;
END.