Capítol 6
LA PROGRAMACIÓ DESCENDENT
- Introducció a la programació descendent.
- Aplicació de la programació descendent per fer un petit programa.
- Aplicació de la programació descendent per fer un menú.
- Aplicació de la programació descendent per fer pantalles amb marcs.
- Les funcions
- Definició de funció.
-
Les funcions més senzilles.
-
Les funcións amb pas de paràmetres o arguments.
-
Les funcións que reben arguments i retornen un
paràmetre.
-
Les funcions i els tipus de dades.
-
La programació per mitjà de funcions
-
Exercicis
6.1. Introducció a la programació descendent.
Es tracta de dividir una acció en accions més simples i aquestes
accions en accions més simples i així successivament. Per
fer-ho tenim a l'abast els procediments i les funcions. En el llenguatge
C només es parla de funcions. Un exemple de programació descendent
és el següent en el que fem l'algorisme del que fem els cinc
dies de treball durant la setmana:
Algoritme per treballar durant la setmana |
Procediment principal
Des de dia=1 fins a 5 de 1 en 1
Lleva't de la cama
Esmorza
Realitza les activitats
del matí
Dina
Realitza les activitats
de la tarda
Sopa
Mira la tele
Ves al llit
Fi del Des de
Fi del principal |
|
Procediment Esmorza
Fes bullir la llet
Prepara el cafe
Cerca les galetes
Menja
Fi del procediment Esmorza |
Procediment Activitats Mati
Si (no has començat les p. d'empresa)
Estudia les matèries de
la tarda
Sinó
Ves a treballar
Fi del Si
Fi el procediment Activitats Mati |
Procediment Dina
Ves al menjador
Para la taula
Serveix el dinar
Menja.
Fi del procediment Dina |
Procediment Activitats tarda
Ves a l'institut
Des de i=1 fins a 3 de 1 en 1
Assisteix a la classe i
Fi del des de
Fes l'esbarjo
Des de i=4 fins a 6 de 1 en 1
Assisteix a la classe i
Fi del des de
Torna a casa
Fi del procediment Activitats Tarda |
El procediment principal es divideix en quatre subprocediments. Ara
pensa que moltes accions d'aquests 4 procediments es poden subdividir.
Així l'acció de "cerca les galetes" es pot fer en un procediment
com el que segueix:
Procediment Cercar galetes
Repeteix fins que trobis les galetes o no tinguis
més portes
Obre una porta nova i mira si les galetes hi son
Si hi son agafa'ls
Fi del repeteix
Fi del procediment Cercar galetes |
6.2. Aplicació de la programació descendent per fer un petit
programa.
Un programa, com a mínim, ha de presentar uns títols, elaborar
informació i presentar uns resultats.
En el següent programa seguim aquest esquema per fer el diseny
descendent i per tal de crear les funcions adients.
#include <stdio.h>
void PresentaTitulos(void);
void EsMultipleDeTres(int Numero);
void PresentaResultats(void);
int MultiplesDeTres = 0;
int SumaMultiplesDeTres = 0;
void main(void)
{
int Num;
PresentaTitulos( );
for(Num=1; Num<=100; Num++) EsMultipleDeTres(Num);
PresentaResultats( );
}
void PresentaTitulos(void)
{
printf("Aquest programa escriu el mútiples
de tres menors que 100\n");
printf("els compta i calcula la seva suma\n\n");
}
void EsMultipleDeTres(int Numero)
{
if (Numero % 3 == 0)
{
printf("%5d",Numero);
MultiplesDeTres++;
SumaMultiplesDeTres += Numero;
}
}
void PresentaResultats(void)
{
printf("\n\nExisteixen %d múltiples de tres
entre 1 i 100\n",MultiplesDeTres);
printf("La seva suma és %d",SumaMultiplesDeTres);
} |
Observa que per primera vegada apareixen variables locals i variables
globals:
Variables locals |
Variables Globals |
Num |
Funció Main |
MultiplesDeTres |
Numero |
Funció EsMultipleDeTres |
SumaMultiplesDeTres |
6.3. Aplicació de la programació descendent per fer un menú.
Pots pensar que un fer menú consisteix en presentar unes opcións
per pantalla, demanar a l'usuari quina opció vol i executar aquesta
opció triada.
Bé el programa següent presenta un títol de menú
amb dues opcións:
Aquest si que és el meu primer menú
0 Acabar
1 Sorpresa
L'opció 0 i l'oció 1 fan alguna tasca (qualsevol) i després
torna a aparèixer el menú.
#include <stdio.h>
void PresentaMenu(void);
char DemanaCaracter(void);
void Executa(char Caracter);
int main(void)
{
char Opcio = ' ';
while (Opcio != '0')
{
PresentaMenu();
Opcio=DemanaCaracter();
Executa(Opcio);
}
return 0;
}
void PresentaMenu(void)
{
printf("\n\nAquest si que és el meu primer
menú\n");
printf("\n0 Acabar\n");
printf("1 Sorpresa\n");
}
char DemanaCaracter(void)
{
char CaracterEntrado;
fflush(stdin);
CaracterEntrado = getchar();
return CaracterEntrado;
}
void Executa(char Caracter)
{
switch (Caracter)
{
case '0':
printf("\nAquí
acaba el programa\n");
break;
case '1':
printf("\nÉs
molt difícil fer una sorpresa aqui\n");
break;
default:
printf("No has
triat bé");
}
} |
6.4. Aplicació de la programació descendent per fer pantalles
amb marcs.
En les pantalles de presentació de programes es fan marcs i es posen
texts dins de diferents finestres. Per fer tot allò es fan unes
funcions amb un anàlisi que pot ser el següent:
Programa marc(x1,y1,x2,y2,color,fons)
Línia Horitzontal(x1,y1,x2,y1,color,fons)
Línia Horitzontal(x1,y2,x2,y2,color,fons)
Línia Vertical(x1,y1,x1,y2,color,fons)
Línia Vertical(x2,y1,x2,y2,color,fons)
Borra Fons(x1,y1,x2,y2,color,fons)
PonCantons(x1,y1,x2,y2,color,fons)
fi del programa marc |
6.5. Les funcions
6.5.1. Definició de funció.
Són trams independents de programa que es criden des de una altra
part del programa. S'han de declarar al començament i s'escriuen
(es defineixen) després. Les funcions tenen un prototip i la instrucció
de declaració es diu prototipat de la funció. A l'exemple
de la figura es veu que el prototip de la funció és de tipus
enter, això vol dir que la funció ens retornarà una
dada de tipus enter després de cridar-la. A més la funció
rep una dada de tipus float.
int PartSencera (float);
6.5.2. Les funcions més senzilles.
Son les funcions que ni reben una dada ni la retornen. En el prototipat
s'ha d'utilitzar el tipus void, que podem dir que és un tipus de
dades inexistents. En altres llenguatges de programació aquest tipus
de funció es diu procediment. Observa en el següent programa
com es fa per escriure i utilitzar una funció d'aquest tipus:
#include <stdio.h>
void RallaAsteriscos(void);
void main(void)
{
char nombre[45]="Ordenatas S.A";
char direc[35]="Plaza del Byte 12";
char ciudad[20]="Villabits, E 6006";
RallaAsteriscos();
printf("%s\n",nombre);
printf("%s\n",direc);
printf("%s\n",ciudad);
RallaAsteriscos();
}
void RallaAsteriscos()
{
int i;
for(i=1; i<=45; i++) putchar('*');
putchar('\n');
} |
/*Prototipat de la funció*/
/*Primera crida de la funció*/
/*Segona crida de la funció*/
/*Aquí comença l'algoritme de la funció*/
/*Aquí acaba l'algoritme de la funció*/ |
La sortida per pantalla serà:
*********************************************
Ordenatas S.A.
Plaza del byte 12
Villabits, E 6006
*********************************************
6.5.3. Les funcións amb pas de paràmetres o arguments.
Són funcions que si reben dades però que no retornen cap
dada. Les dades que reben són passades a la funció des de
el lloc on son cridades. Aquestes dades es diuen paràmetres o arguments
de la funció. En altres llenguatges de programació es diuen
procediments amb pas de paràmetres. Podem millorar la funció
RallaAsterisc() del programa anterior, que es dirà Ralla per mitjà
d'un paràmetre que li digui a la funció amb quin caràcter
volem que s'imprimeixi:
#include <stdio.h>
void Ralla(char);
void main(void)
{
char nombre[45]="Ordenatas S.A";
char direc[35]="Plaza del Byte 12";
char ciudad[20]="Villabits, E 6006";
Ralla('_');
printf("%s\n",nombre);
printf("%s\n",direc);
printf("%s\n",ciudad);
Ralla('*');
}
void Ralla(char caràcter)
{
int i;
for(i=1; i<=45; i++) putchar(caràcter);
putchar('\n');
} |
Bé, la sortida per pantalla amb aquest programa serà:
_____________________________________________
Ordenatas S.A.
Plaza del byte 12
Villabits, E 6006
*********************************************
Observa que en el prototipat es fa la declaració del tipus de dades
que rebrà la funció char , i en el moment d'escriure la funció
es declara el nom de la variable que prendrà aquesta dada char caràcter.
Una funció pot rebre més d'una dada com en l'exemple següent
que fa marcs del tipus següent en el que es necessiten el número
de files i columnes que ocupa el marc:
+-----------------+
¦ ¦
¦ ¦
¦ ¦
¦ ¦
+-----------------+
#include <stdio.h>
void marc(short int, short int);
void main(void)
{
marc(4,4);
marc(4,20);
}
void marc (short int files, short int columnes)
{
short int i,j;
if ((files > 2) && (columnes > 2))
{
printf("+");
for (i=1; i<columnes-1;i++)
printf("-");
printf("+");
for (j=1; j<files-1;j++)
{
printf("¦");
for (i=1; i<columnes-1;i++)
printf(" ");
printf("¦");
}
printf("+");
for (i=1; i<columnes-1;i++)
printf("-");
printf("+");
}
} |
6.5.4. Les funcións que reben arguments i retornen un paràmetre.
Son la classe més general de funcions. l'exemple següent té
la funció major que rep dos números sencers i retorna el
major dels dos.
#include <stdio.h>
int major(int,int);
void main(void)
{
int a,num1,num2;
printf("Introdueix dos números sencers separats
per un espai ");
scanf("%d %d",&num1, &num2);
a=major(num1,num2);
printf("El número major es %d\n",a);
}
int major(int num1,int num2)
{
if (num1>num2)
return num1;
else
return num2;
} |
6.5.5.- Les funcions i els tipus de dades.
Les funcions es poden declarar al prototipat amb qualsevol tipus de dades
conegut fins ara, es a dir com en el quadre
2.2 del capítol 2. En el següent exemple fem una funció
que calcula potències de dos i que per tant a de tenir un tipus
de dades amb moltes xifres de precisió i s'ha declarat com long
double.
#include <stdio.h>
long double DosElevat(int);
int main(void)
{
printf("2 elevat a 10 ‚s %Lf\n",DosElevat(10));
printf("2 elevat a 20 ‚s %Lf\n",DosElevat(20));
printf("2 elevat a 30 ‚s %Lf\n",DosElevat(30));
printf("2 elevat a 40 ‚s %Lf\n",DosElevat(40));
return 0;
}
long double DosElevat(int num)
{
int i;
long double resultat=1;
for(i=1; i<num+1; i++) resultat *= 2;
return resultat;
} |
6.6. La programació per mitjà de funcions
Quan es programa es tracta de dividir cada acció en accions més
petites i d'aquesta manera fer procediments o funcions d'una mida petita
i manejable per al programador.
Un exemple típic és el de un menú d'opcions en
el que cada opció correspon a una acció programada en un
procediment o funció.
Observa l'exemple següent i tracta de veure que és un menú
amb tres opcions que estan programades en tres funcions distintes. Les
opcions són Castic, Joc de daus i Diagonal. Com veus hi ha tres
funcions que fan aquests tres programes. A més hi ha otra funció,
PresentaMenu, que ens retorna el valor de l'opció triada per l'usuari.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
int PresentaMenu(void);
void Castic(void);
void JocDeDaus(void);
void Diagonal(void);
int main(void)
{
int opcio = '1';
char tecla;
while (opcio != '0')
{
opcio = PresentaMenu();
switch (opcio)
{
case '1' :
Castic();
break;
case '2' :
JocDeDaus();
break;
case '3' :
Diagonal();
break;
case '0' :
clrscr();
printf("Bé, s'acabat...");
break;
default :
printf("\nNo has triat bé");
}
printf("\n\n\nPrem una tecla");
fflush(stdin); tecla = getch();
}
return 0;
}
int PresentaMenu(void)
{
clrscr();
printf("El primer programa amb funcions\n\n");
printf(" 0 Acabar \n\n");
printf(" 1 Càstic\n");
printf(" 2 Joc de daus \n");
printf(" 3 Diagonal\n\n");
printf(" Tria una opció\n");
return (getch());
}
void Castic(void)
{
int i;
clrscr();
for(i=1; i<21; i++)
printf("%3d.-Vaca s'escriu amb
v\n",i);
}
void JocDeDaus(void)
{
int sortit, resposta;
time_t t;
srand((unsigned) time(&t));sortit = 1 + (rand()
% 6);
clrscr();
printf("Escriu un número de l'u al sis ");
fflush(stdin);
scanf("%d",&resposta);
if (resposta == sortit)
printf("\n\nMolt bé, has
encertat, era el %d",sortit);
else
printf("\n\nBurro, havia sortit
el %d",sortit);
}
void Diagonal(void)
{
int i,j;
clrscr();
for(i=1; i<21; i++)
{
for(j=1; j<i; j++) printf("
");
printf("Hola\n");
}
} |
6.7.Exercicis
-
Fes l'estudi descendent per a un programa que comptarà i sumarà
els números parells menors que 100 d'una banda i els que no ho són
per una altra.Tradueix a C aquest estudi.
-
Fes l'estudi descendent per a un programa que compta les vegades que es
premen els dígits. Ho fa en els intervals [0,2], [3,5] y [6,9].
-
En aquest problema tractarem d'escriure a pantalla les 10 sèries
de números de l'ú al deu de la figura:
Fila número 1: 1 2 3 4 5 6 7 8 9 10
Fila número 2: 1 2 3 4 5 6 7 8 9 10
Fila número 3: 1 2 3 4 5 6 7 8 9 10
Fila número 4: 1 2 3 4 5 6 7 8 9 10
Fila número 5: 1 2 3 4 5 6 7 8 9 10
Fila número 6: 1 2 3 4 5 6 7 8 9 10
Fila número 7: 1 2 3 4 5 6 7 8 9 10
Fila número 8: 1 2 3 4 5 6 7 8 9 10
Fila número 9: 1 2 3 4 5 6 7 8 9 10
Fila número 10: 1 2 3 4 5 6 7 8 9 10
Pensa que pots fer una funció que escrigui una fila. Ha de rebre
el paràmentre que escriu el número de la fila.
-
Fes l'estudi descendent per a un programa que demana un número i
escriu la seva taula de multiplicar. Després demana que si vol una
altra taula de multiplicar. Es fan taules fins que l'usuari contesti que
no vol una altra.
-
Escriu les funcions descrites a l'apartat 4 amb rectangles. Fes ús
d'aquesta funció per fer una figura com les següents:
![](imagenes/cap0603.jpg)
Els codis ASCII dels caràcters necessaris els tens a la següent
taula:
-
Fes ús del'anterior funció per fer una figura com la següent:
![](imagenes/cap0601.gif)
-
Fes un estudi de programació descendent per tal de presentar una
pantalla com la següent:
![](imagenes/cap0602.jpg)
Has de tenir cura en prepara una funció que es digui TaulaDel
i que ha de rebre un paràmetre que és el número de
la taula. Es a dir per cridar aquesta funció hem de escriure TaulaDel(x)
i la funció escriurà la taula corresponent al valor x.
-
Fes el programa en C, de l'exercici anterior.
-
Fés un programa que presenti successivament les taules de multiplicar
de l'u al deu dins del recuadre.Hauràs de fer el procediment EsperaTecla.
-
Primer en psudocodi.
-
Després en C.