Upload
others
View
7
Download
0
Embed Size (px)
Citation preview
PROGRAMACIÓ 1!
Programació Modular!
Grau en Enginyeria en Informàtica
Objectius/competències
1. Utilitzar el disseny descendent per a resoldre problemes de relativa complexitat.
2. Comprendre les diferències entre procediments i funcions.
3. Saber modular programes en llenguatge C.
1
Índex
1. Descomposició modular
2. Comunicació entre mòduls
3. Procediments i funcions
4. Àmbit de les variables
5. Estructura general d’un programa
6. Funcions predefinides en llenguatge C
7. Fonts d’informació
2
Disseny descendent (top-down)
! Per a resoldre un problema es divideix en problemes més petits (subproblemes) " La descomposició del problema es fa en una sèrie de nivells o passos successius
de refinament, que formen una estructura jeràrquica. " Cada nivell de la jerarquia inclou un major nivell de detall.
Preparar el dinar
Ruta per a arribar a la
ciutat X Comprar-ne els
ingredients
quedar a dinar a casa d�un amic que viu en una altra ciutat i dur el dinar
Planificar la ruta per a arribar a sa casa
Cuinar Ruta per a arribar al seu
carrer Buscar el
núm. d�edifici
Agafar diners Anar al
supermercat Buscar llibre de receptes Seguir-ne els
passos Buscar plànol de carreteres
Buscar guia de carrers Connectar-
se a Internet Connectar-se a Internet
3
Concepte de mòdul
! Quan un programa és gran i complex no és convenient que tot el codi estiga dins del programa principal (funció main () en llenguatge C).
! Un mòdul o subprograma… " És un bloc de codi que s’escriu a part del programa
principal. " S’encarrega de fer un treball concret que resolga un
problema parcial del problema principal. " Pot ser invocat (cridat) des del programa principal o des
d’altres mòduls. " Permet ocultar els detalls de la solució d’un problema
parcial (caixa negra).
4
Caixa negra
! Cada mòdul és una caixa negra per al programa principal o per a la resta de mòduls.
! Per a utilitzar un mòdul des del programa principal o des d’altres mòduls…
" Necessitem conèixer la interfície, és a dir, les entrades i eixides
" No necessitem conèixer els detalls interns de funcionament
Entrada Eixida
Com ho fa?
Què fa?
5
Exemple de mòduls
main() { int n1, n2; // nombres introduïts per teclat (dades d’entrada) int major; // el major nombre dels dos introduïts (dada d’eixida) int menor; // el menor nombre dels dos introduïts (dada d’eixida) cout << “Introdueix dos nombres enters: “; cin >> n1 >> n2; major = maxim(n1, n2); menor = minim(n1, n2); cout << “El major nombre és:” << major; cout << “El menor nombre és:” << menor; cout << endl; }
// Aquest mòdul retorna el major de dos nombres
int maxim(int a, int b) { int m; // el major de dos nombres (dada d’eixida) if (a > b) m = a; else m = b; return(m); }
// Aquest mòdul retorna el menor de dos nombres
int minim(int a, int b) { int m; // el menor de dos nombres (dada d’eixida) m = a; if (b < m) m = b; return(m); }
Què fa el mòdul �màxim()�?
Com ho fa?
6
Declaració, definició i crida d’un mòdul
Declaració del mòdul
Nom_del_mòdul ( declaració_de_paràmetres )
int maxim(int a, int b) { int m; if (a > b) m = a; else m = b; return(m); }
int maxim(int a, int b);
Definició del mòdul
Nom_del_mòdul ( declaració_de_paràmetres )
Declaració_de_variables_locals
Cos del mòdul: sentències executables
Fi_del_mòdul
Crida del mòdul
Nom_del_mòdul ( llista_de_paràmetres ) major = maxim(n1, n2);
7
Avantatges de la programació modular
! Facilita el disseny descendent i la programació estructurada
! Redueix el temps de programació
" Reusabilitat: estructuració en llibreries específiques (biblioteca de mòduls).
" Divisió del treball de programació entre un equip de programadors.
! Disminueix el volum total del programa
" Un mòdul només està escrit una vegada i pot ser utilitzat diverses vegades des de diferents parts del programa.
! Facilita la detecció i correcció d’errors
" Mitjançant la comprovació individual dels mòduls.
! Facilita el manteniment del programa
" Els programes són més fàcils de modificar.
" Els programes són més fàcils d’entendre (més llegibles).
8
Transferència del flux de control
! Quan un mòdul A crida (invoca) un altre mòdul B, el flux de control (flux d’execució) passa al mòdul B.
! Quan acaba d’executar-se el mòdul B, el flux de control continua en el mòdul A, a partir de la sentència següent a la crida del mòdul B.
Cos del mòdul A
Crida al mòdul B
Cos del mòdul B
Fi del mòdul B Sentència següent
1
2
3
4 5
El programa principal pot ser considerat com un mòdul que pot invocar-ne d’altres, però que no pot ser invocat per cap mòdul.
9
Transferència d’informació
! La transferència d’informació entre mòduls es fa a través del pas de paràmetres o arguments.
! Un mòdul pot tenir paràmetres d’entrada i/o eixida.
Paràmetres d�entrada
Mòdul A Mòdul B
Paràmetres d�eixida
El mòdul A pot proporcionar dades d’entrada al mòdul B quan l’invoca.
El mòdul B pot rebre dades d’entrada i proporcionar dades d’eixida al mòdul A.
10
Paràmetres actuals i formals
! Paràmetres actuals o reals " Els que apareixen en la sentència de crida al mòdul
# nombre de paràmetres # tipus de paràmetres # ordre dels paràmetres " nom dels paràmetres
Nom_del_mòdul (pr1, pr2, …, prN) major = maxim(n1, n2);
! Paràmetres formals o ficticis $ Els que hi ha en la declaració del mòdul
Nom_del_mòdul (tipus1 pf1, tipo2 pf2… tipusN pfN)
! Correspondència entre paràmetres actuals i formals:
int maxim(int a, int b);
11
Pas de paràmetres per valor
! El mòdul rep una còpia del valor de la dada (paràmetre actual) que el mòdul invocador li passa.
! El paràmetre actual pot ser qualsevol expressió avaluable en el moment de la crida al mòdul.
! Si dins del mòdul es modifica el paràmetre formal corresponent, el valor del paràmetre actual es manté inalterable.
void rectangle( int ample, int alt, int &area_rect, int &perim ) { area_rect = ample * alt; perim = 2 * (ample + alt); }
main() { int base, altura, area, perimetre; cout << “Digues la base del rectangle:”; cin >> base; cout << “Digues-ne l’altura:”; cin >> altura; rectangle (base, altura, area, perímetre); cout << “Àrea: ” << area << endl; cout << “Perímetre: ” << perimetre; cout << endl; }
Pas de paràmetres per valor
Memòria
base
altura
ample
alt
12
Pas de paràmetres per referència
! El mòdul rep la referència a la posició de memòria on hi ha aquest valor (direcció de memòria d’una variable).
! El paràmetre actual ha de ser obligatòriament una variable, que pot contenir un valor o no.
! Si dins del mòdul es modifica el paràmetre formal corresponent, canviarà el contingut en memòria del paràmetre actual.
main() { int base, altura, area, perimetre; cout << “Digues la base del rectangle:”; cin >> base; cout << “Digues-ne l’altura:”; cin >> altura; rectangle (base, altura, area, perimetre); cout << “Àrea: ” << area << endl; cout << “Perímetre: ” << perimetre; cout << endl; }
void rectangle( int amplaria, int altura, int &area_rect, int &perim ) { area_rect = amplaria * altura; perim = 2 * (amplaria + altura); }
Pas de paràmetres per referència
Memòria
àrea
area_rect
perimetre
perim
13
Concepte de funció
! Retorna un valor que està associat al nom de la funció
! Sol definir-se amb N paràmetres (N ≥ 1)
! Només s’ha d’utilitzar pas de paràmetres per valor
bool es_par(int n) { return( (n % 2) = = 0); }
Tipus de dada del valor que retorna
Nom de la funció
Declaració de paràmetres
Sentència per a retornar el valor
if (es_par(3))
if (es_par(x) && (x > 10) )
int x; bool fin;
fin = es_par(x);
if (es_par(x) == true)
fin = es_par(4) || (x < 0);
Crida a la funció
es_par(x); Crida incorrecta
14
Concepte de procediment
! Es pot definir amb N paràmetres (N ≥ 0).
! Es pot utilitzar pas de paràmetres per valor i/o per referència.
! S’invoca amb una sentència composta pel seu nom i llista de paràmetres actuals (la crida és una sentència per si mateixa).
void Escriu_Caracter(char c, int n) { int i; for (i=1; i <= n; i++) cout << c; cout << endl; }
Sols es poden retornar valors amb els paràmetres
Nom del procediment
Declaració de paràmetres
Crida al procediment
Escriu_Caracter(‘*’,20); int num; char c;
Escriu_Caracter(c, num);
Escriu_Caracter(‘c’, 5);
15
Què he d’usar? Un procediment o una funció?
El mòdul ha de retornar un únic valor?
Sí No
procediment funció
16
Sobre la sentència return
! Finalitza l’execució del cos de la funció.
! S’encarrega de retornar el valor de retorn de la funció, després d’avaluar-ne l’expressió associada.
! És recomanable usar una única sentència return dins del cos d’una funció.
! Hauria de ser l’última sentència del cos de la funció.
return (expressió);
17
Concepte d’àmbit d’una variable
! L’àmbit d’una variable defineix la seua visibilitat, és a dir, des d’on es pot accedir a aquesta variable
main() { int n; // nombre introduït per teclat (dada d’entrada) cout << “Introdueix un nombre enter: “; cin >> n; if (es_primo(n)) cout << “El nombre és primer”; else cout << “El nombre no és primer”; cout << endl; }
// Aquest mòdul comprova si un nombre és primer o no
bool es_primer(int num) { int cont; // comptador (dada auxiliar) bool primer; // és primer o no (dada d’eixida) primo = true; cont = 2; while ( (cont < num) && primer) { // comprovar si és divisible per un altre nombre primo = ! (num % cont == 0); cont = cont + 1; } return (primer); }
àmbit de n
àmbit de num, cont, primer
18
Variables locals i variables globals
! Variable local $ El seu àmbit és el cos del mòdul en què està declarada. $ Es crea quan es declara i es destrueix quan finalitza l’execució del
mòdul.
! Variable global $ El seu àmbit és tot el programa (tots els mòduls i el programa
principal). $ Es crea quan es declara i es destrueix quan finalitza l’execució del
programa.
19
Prohibit utilitzar variables globals
Variables globals
La comunicació entre mòduls ha de fer-se a través de paràmetres i NO de variables globals.
20
Efecte lateral
! Qualsevol comunicació de dades entre mòduls al marge dels paràmetres i la devolució de resultats s’anomena efecte lateral.
#include <iostream> using namespace std;
int resultat; // declaració de variable global
int numMajor(int n1, int n2);
main() { int n1, n2; // nombres introduïts per teclat (dades d’entrada) int major; // el major dels dos nombres (dada d’eixida) cout << “Introdueix dos nombres:”; cin >> n1 >> n2; resultat = n1 + n2; major = numMajor(n1, n2); cout << “La suma dels nombres és: “ << resultat; cout << “ i el major és:” << major; cout << endl; }
// funció que retorna el major de dos nombres int numMajor(int n1, int n2) { if (n1 > n2) resultat = n1; else resultat = n2; return(resultat); }
Per què no funciona?
Com se soluciona?
21
Quin tipus de programes he de ser capaç de fer?
#directives del preprocessador
Declaració de constants
Declaració de procediments i funcions
main() {
Declaració de variables (de tipus simples)
Cos principal
sentències de control
crides a procediments i funcions
}
Definició de procediments i funcions
22
Exemple de programa
#include <iostream> using namespace std; // Canvis de moneda a euros const float US_DOLAR_EURO = 1,4696; const float LLIURA_ESTERLINA_EURO = 1,4696;
// Declaració de procediments i funcions void Llegir_Import(float &quantitat, char &moneda); float Canvi_En_Euros(float quantitat, char moneda);
main() { float quantitat; // quantitat de diners (dada d’entrada) char moneda; // tipus de moneda (dada d’entrada) char resposta; // resposta per a continuar (dada d’entrada) float euros; // quantitat en euros equivalent (dada d’eixida) do { Llegir_Import(quantitat, moneda); euros = Canvi_En_Euros(quantitat, moneda); cout << “El canvi en euros és:” << euros << endl; cout << “Vol introduir un altre import? (S/N) :”; cin >> resposta; } while ( (resposta == ‘s’) || (resposta == ‘S’)); }
Quan definiu un mòdul, recordeu incloure un comentari que explique què fa el mòdul
// Llegir de teclat un import i el tipus de moneda // validant les dades introduïdes fins que // siguen correctes void Llegir_Import(float &quantitat, char &moneda) { bool dades_correctes; do { cout << “Introdueix quantitat de diners i moneda (D/L):”; cin << quantitat << moneda; dades_correctes = (quantitat > 0.0) && ( moneda == ‘D’ || moneda == ‘L’); } while ( ! dades_correctes); } // Retornar el canvi en euros equivalent a l’import i moneda // especificats float Canvi_En_Euros(float quantitat, char moneda) { switch (moneda) { case ‘D’ : euros = quantitat * US_DOLAR; break; case ‘L’ : euros = quantitat * LLIURA_ESTERLINA_EURO; } return (euros); }
23
Biblioteques del llenguatge C / C++
! La majoria de llenguatges de programació proporciona una col·lecció de procediments i funcions d’ús comú (biblioteques o llibreries).
! En llenguatge C / C++, per a fer ús dels mòduls inclosos en una biblioteca s’utilitza la directiva del compilador #include
! Hi ha una gran varietat de biblioteques disponibles: $ Funcions matemàtiques $ Maneig de caràcters i de cadenes de caràcters $ Maneig d’entrada i eixida de dades $ Maneig del temps (data, hora, etc.) $ Etc.
24
Algunes funcions predefinides en llenguatge C / C++
Llibreria C++ Llibreria C Funció Descripció
<math.h> <math.h> double cos(double x) Retorna el cosinus de x
double sin(double x) Retorna el sinus de x
double exp(double x) Retorna ex
double fabs(double x) Retorna el valor absolut de x
double pow(double x, double y) Retorna xy
double round(double x) Retorna el valor de x arredonit
double sqrt(double x) Retorna l’arrel quadrada de x
<iostream> <ctype.h> int isalnum(int c) Retorna vertader si el paràmetre és una lletra o un dígit
int isdigit(int c) Retorna vertader si el paràmetre és un dígit
int toupper(int c) Retorna el caràcter en majúscula
<stdlib.h> int rand(void) Retorna un nombre aleatori entre 0 i RAND_MAX
Llibreria C++ Llibreria C Constants Descripció
<iostream> <stdint.h> INT_MIN Menor nombre enter representable
INT_MAX Major nombre enter representable
25
Exercicis
1. Quan fa fred, els meteoròlegs informen sobre un índex anomenat factor de refredament pel vent, que té en compte la velocitat del vent i la temperatura. Aquest factor es pot aproximar amb la fórmula:
W = 13.12 + 0.6215*t – 11.37 * v0.16 + 0.3965*t*v0.016
en què v = velocitat del vent en m/s t = temperatura en graus Celsius: t ≤ 10 W = índex de refredament del vent (en graus Celsius) Dissenya un mòdul que sol·licite el valor de la velocitat i la temperatura i calcule W,
tenint en compte la restricció imposada per a la temperatura.
2. Dissenya un mòdul que reba com a paràmetre un nombre n i dibuixe en pantalla un quadrat de grandària n format per asteriscs.
3. Millora l'exercici 2 afegint un altre paràmetre que permeta que el quadrat es dibuixe amb el caràcter enviat com a paràmetre.
4. Se t'ocorre alguna forma per indicar que el quadrat es dibuixi buit o sòlid?
5. Dissenya un mòdul que permeta llegir i validar una dada d'entrada de manera que el seu valor siga major que 0 i menor que 100 i retorne la suma i el compte dels nombres entre 1 i aquest valor.
26
Bibliografia recomanada
✔ Capítol 7
Fundamentos de Programación Jesús Carretero, Félix García i altres Thomson-Paraninfo 2007. ISBN: 978-84-9732-550-9
Resolución de Problemas con C++ Walter Savitch Pearson Addison Wesley 2007. ISBN: 978-970-26-0806-6
✔ Capítol 4
Problemas Resueltos de Programación en Lenguaje C Félix García, Alejandro Calderón i altres Thomson (2002) ISBN: 84-9732-102-2
✔ Capítol 5
27