Índex

 
Capítol6.zip Exercicis06.zip
Capítol 6

LA PROGRAMACIÓ DESCENDENT

  1. Introducció a la programació descendent.
  2. Aplicació de la programació descendent per fer un petit programa.
  3. Aplicació de la programació descendent per fer un menú.
  4. Aplicació de la programació descendent per fer pantalles amb marcs.
  5. Les funcions
    1. Definició de funció.
    2. Les funcions més senzilles.
    3. Les funcións amb pas de paràmetres o arguments.
    4. Les funcións que reben arguments i retornen un paràmetre.
    5. Les funcions i els tipus de dades.
  6. La programació per mitjà de funcions
  7. 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

  1. 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.

  2.  
  3. 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].

  4.  
  5. En aquest problema tractarem d'escriure a pantalla les 10 sèries de números de l'ú al deu de la figura:
  6. 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.
  7. 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.

  8.  
  9. Escriu les funcions descrites a l'apartat 4 amb rectangles. Fes ús d'aquesta funció per fer una figura com les següents:

  10. Els codis ASCII dels caràcters necessaris els tens a la següent taula:

  1. Fes ús del'anterior funció per fer una figura com la següent:

  2. Fes un estudi de programació descendent per tal de presentar una pantalla com la següent:

  3. 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.
     

  4. Fes el programa en C, de l'exercici anterior.

  5.  
  6. 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.

  7.