Date post: | 02-Apr-2015 |
Category: |
Documents |
Upload: | herberto-torralba |
View: | 108 times |
Download: | 3 times |
Chapter 7
Functions
Dale/Weems/Headington
2
Tópicos Capítulo 7
Writing a Program Using Functional Decomposition
Writing a Void Function for a Task Using Function Arguments and Parameters Differences between Value Parameters and
Reference Parameters Using Local Variables in a Function Function Preconditions and Postconditions
3
Funciones
Cada programa en C++ debe tener una función llamada “main”
La ejecución del programa siempre comienza con la función “main”
Cualquier otra función es un subprograma y necesita ser invocada (llamada)
4
Function Calls (Llamadas de Funciones)
Una función llama a otra utilizando el nombre de la función llamada seguido de los paréntesis () los cuales podrían incluir una lista de argumentos.
Una llamada de función (“function call”) transfiere temporeramente control de la función que invoca a la función invocada.
5
FunctionName ( Argument List )
La lista de argumentos (“argument list”) es una forma de las funciones poder comunicarse entre si y de pasar información.
La lista de argumentos (“argument list”) puede contener o, 1 o más argumentos separados por coma, dependiendo de la función.
Function Call Syntax
6
Las Dos Partes de la Definición de una Función
int Cube ( int n ) heading{
body return n * n * n ;
}
7
¿Qué es el “heading”?
int Cube ( int n )
tipo de valor que devuelve nombre de la
función
Lista de parametros
8
¿ Qué es un prototipo (“prototype”)?
Un prototipo se ve similar al “heading”, sin embargo termina con un punto y coma (;) y se necesita identificar en el, los tipos de datos de los parámetros que va a utilizar la función como tal.
int Cube( int ); // prototype
9
Cuando se invoca una función…Se define una memoria temporera ( para los valores de los parámetros y cualquier variable local. También se define para el valor que devuelve si la función no es “void”).
Entonces el flujo de control pasa al primer enunciado (“statement”) en el cuerpo (“body”) de la función invocada. Las demas instrucciones del cuerpo son invocadas hasta que ocurre una de las siguientes condiciones:
return statement (con o sin un “return value”),
or,
se encuentra las llaves que indican el final del “body”.
Entonces el control se devuelve a la función que invoco.
10
#include <iostream>using namespace std; int Cube ( int ) ; // prototype
void main ( ){ int yourNumber ; arguments int myNumber ; yourNumber = 14 ; myNumber = 9 ;
cout << “My Number = “ << myNumber ; cout << “its cube is “ << Cube (myNumber) << endl ; cout << “Your Number = “ << yourNumber ; cout << “its cube is “ << Cube (yourNumber) << endl ;}
11
Para Compilar exitosamente…
Antes de que se invoque una función en el programa, el compilador debe procesar previamente el prototipo de la función o la definición de la función (“heading and body”)
12
Una función de C++ puede devolver
En su enunciado, un valor del tipo especificado (llamado “return type”) en su “heading” y “prototype”.
Sin embargo, una función “void” no puede devolver ningún valor en sus enunciados.
13
Escribir una función “void”
llamada DisplayMessage ( ) que sea invocada de la función main ( ) para describir el índice de contaminación el cual recibe como parámetro.
Tu ciudad clasifica los niveles de contaminación como: Menor que 35 como “Placentero”, 35 a 60 como “Desagradable”, y sobre 60 como “Peligroso”
14
parametro
void DisplayMessage( int index )
{
if ( index < 35 )
cout << “Pleasant”;
else if ( index <= 60 )
cout << “Unpleasant”;
else
cout << “Health Hazard”;
}
15
#include <iostream>using namespace std; void DisplayMessage (int); // prototype
int main ( ) argument{
int pollutionIndex;
cout << “Enter air pollution index”;cin >> pollutionIndex;DisplayMessage(pollutionIndex); // callreturn 0;
}
Resto del Programa
15
16
return;
Es válido solamente en el “body block”de las funciones que no sean “void”
Causa que el control deje la función y vuelva al bloque que la llamo dejando las subsequentes instruciones (si quedaban) sin ejecutarse.
17
Los “Header files” contienen declaraciones de…
Definir constantes como..const int INT_MAX = 32767;
Prototipos de funciones como…float sqrt( float );
clases como….
string, ostream, istream
Objetos como….
cin, cout
18
Programa con varias Funciones
Square function
Cube function
function prototypes
main function
19
Funciones que devuelven un valor
#include <iostream>
int Square ( int ) ; // prototypesint Cube ( int ) ;using namespace std;
int main ( ){ cout << “The square of 27 is “
<< Square (27) << endl; // function call cout << “The cube of 27 is “ << Cube (27) << endl; // function call
return 0;}
19
20
Resto del Programa
int Square ( int n ) // header and body{ return n * n;}
int Cube ( int n ) // header and body{ return n * n * n;}
21
Una función “void” se invoca ella sola
#include <iostream>
void DisplayMessage ( int ) ; // prototype
using namespace std;
int main ( ) argument{ DisplayMessage(15); // function call
cout << “Good Bye“ << endl;
return 0;} 21
22
Una función “void” no devuelve un valor
parameter void DisplayMessage ( int n ){ cout << “I have liked math for “ << n << “ years” << endl ;
return ;}
23
Lista de Parametros
Es el medio que utiliza una función para compartir datos con el bloque que contiene la llamada
24
Clasificación por Localización
Siempre aparecen en el “function call“ dentro del bloque que llama.
Siempre aparece en la función “heading”, o en la función “prototype”.
Argumentos Parametros
25
Algunos Términos importantes
use el termino “actual parameters” para los argumentos
algunos libros se refieren a los parámetros como “formal parameters”.
26
“Value Parameter” “Reference Parameter”
El valor (25) del argumento se pasa a la funciónCuando es invocada.
La dirección de memoria (4000)del argumento se pasa a lafunción cuando es invocada.
25
4000
age
En este caso, el argumento puede ser una variable, constante,o expresión.
En este caso, el argumentodebe ser una variable.
Argumento
en el Bloque que llama
26
27
Por “default”, los parametros… simples (como int, char, float, double) son siempre parametros por valor (“value parameters”), a menos que se haga algo para cambiar eso. Para obtener un parámetro por referencia (“reference parameter”) se necesita poner un & despues de tipo de dato en la función “heading” y “prototype”.
28
Cuando usar Parámetros por Referencia (“Reference Parameters”)
Los parámetros por referencia deben ser usados cuando se quiere modificar el valor de una de las variables del bloque que invoca sin que se asigne el valor al volver de la llamada.
29
Utilizar un Parámetro por Referencia
Es como darle a alguien la llave de la casa.
La llave puede ser usada por la otra persona para cambiar el contenido de la casa.
30
MEMORIA EN EL “MAIN PROGRAM”
25
4000
age
Si sólo se pasa una copia del valor 25 a una función, se le llama “pass-by-value” y la función no será capaz de cambiar el contenido de age. Seguirá siendo 25 cuando el control vuelva a la función que invoco.
31
MEMORIA EN EL “MAIN PROGRAM”
PERO, si pasas la dirección (4000), de age a la función, se le llama “pass-by-reference” y la función será capaz de cambiar el contenido de age. Puede ser 23 o 90 cuando se devuelva el control.
25
4000
age
32
“Pass-by-reference” también se le llama . . .
“pass-by-address”, o
“pass-by-location”
33
Ejemplo de “Pass-by-Reference”
Queremos encontrar 2 raizes cuadradas de una ecuación cuadrática con coeficientes a,b,c. Escribiremos un prototipo para una función “void” llamada GetRoots( ) con 5 parámetros. Los primeros 3 parámetros son tipo float. Los próximos 2 son parámetros por referencia de tipo float.
34
void GetRoots ( float , float , float , float& , float& );
Ahora escribiremos la definición de la función utilizando esta información.
Esta función usa 3 valores de entrada (a,b,c) que vienen del bloque que invoca. Calcula como resultado dos valores que tiene que devolver. Esos valores son las dos raizes cuadradas de la ecuación cuadrática con coeficientes a,b,c.
// prototype
35
void GetRoots( float a, float b, float c, float& root1, float& root2)
{ float temp; // local variable
temp = b * b - 4.0 * a * c;
root1 = (-b + sqrt(temp) ) / ( 2.0 * a );
root2 = (-b - sqrt(temp) ) / ( 2.0 * a );
return;}
Definición de la Función
35
36
#include <iostream>
#include <fstream>
#include <cmath>
void GetRoots(float, float, float, float&, float&);
using namespace std;
void main ( )
{ ifstream myInfile;
ofstream myOutfile;
float a, b, c, first, second;
int count = 0;
...... // open files
while ( count < 5 ) { myInfile >> a >> b >> c;
GetRoots(a, b, c, first, second); //call
myOutfile << a << b << c << first << second << endl;
count++ ;
} // close files
...... }
36
37
“Pass-by-value”
CALLINGBLOCK
FUNCTION CALLED
“incoming”
value ofargument
38
“Pass-by-reference”
CALLINGBLOCK FUNCTION
CALLED
“incoming”
valor original del argumento
“outgoing”
Valor cambiadodel argumento O,
39
“Pass-by-reference”
CALLINGBLOCK FUNCTION
CALLED
El argumento no tiene valor todavía cuando ocurre la llamada
“outgoing”
Nuevo valor delargumento
40
El Flujo de Datos Determina el Mecanismo para pasar los Datos
Incoming /* in */ Pass-by-value
Outgoing /* out */ Pass-by-reference
Incoming/outgoing Pass-by-reference
/* inout */
Parameter Data Flow Passing-Mechanism
41
Preguntas
¿Porqué se utlizan las funciones para las tareas?
Para acortar la cantidad de detalles en el modulo principal (encapsulation).
¿Puede una función llamar a otra función?
Si ¿Puede una función llamarse a si misma?
Si, eso se llama recursión.
42
Más Preguntas
¿Hace diferencia los nombres que se utilizan para los parámetros?
NO. Solo se utilizan en el “body”. ¿Los nombres de los parámetros y
argumentos tienen que ser los mismos?
NO. ¿ Qué ventaja hay en eso? Ninguna,
eso tiende a confundir.
43
Ejemplo – escribe el prototipo y definnición de función para…
Una función void llamadaGetRating( ) con un parámetro de referencia de tipo char
La función repetídamente pide al usuario que entre un caracter por el teclado hasta que una de estas letras se entre: E, G, A, P que representan “Excellent”, ”Good”, ”Average”, ”Poor”.
44
void GetRating( char& ); // prototype
void GetRating (char& letter)
{ cout << “Enter employee rating.” << endl;
cout << “Use E, G, A, or P : ” ;
cin >> letter;
while ( (letter != ‘E’) && (letter != ‘G’) && (letter != ‘A’) && (letter != ‘P’) )
{
cout << “Rating invalid. Enter again: ”;
cin >> letter;
}
}44
45
¿Qué es un driver?
Es un programa corto (main) cuyo único propósito es llamar una función que se haya escrito. De este modo se puede determinar si cumple con las especificaciones y trabaja como se desea.
Escriba un “driver”para la función GetRating( )
46
#include <iostream>
void GetRating( char& ); // prototype
using namespace std;
int main( ){ char rating; rating = ‘X’;
GetRating(rating); // call
cout << “That was rating = “ << rating << endl;
return 0;}
46
47
Un “Assertion”
es un “truth-valued statement”que puede ser cierto o falso (no necesariamente in código de C++)
EJEMPLOS
studentCount > 0
sum is assigned && count > 0
response == ‘y’ or ‘n’
0.0 <= deptSales <= 25000.0
beta == beta @ entry * 2
48
“Preconditions” y “Postconditions” El “precondition” es un “assertion” que
describe todo lo que la función requiere para ser cierto al momento de la función ser invocada.
El “postcondition” describe el estado en el momento que la función termina de ejecutarse.
El que llama es responsable de cotejar la “precondition”, y la función llamada, la “postcondition”. EJEMPLO . . .
49
Function con “Postconditions”
void GetRating ( /* out */ char& letter)
// Precondition: None
// Postcondition: User has been prompted to enter a character
// && letter == one of these input values: E,G,A, or P
{ cout << “Enter employee rating.” << endl;
cout << “Use E, G, A, or P : ” ;
cin >> letter;
while ( (letter != ‘E’) && (letter != ‘G’) && (letter != ‘A’) && (letter != ‘P’) )
{
cout << “Rating invalid. Enter again: ”;
cin >> letter;
}
} 49
50
Función con Preconditions y Postconditions
void GetRoots( /* in */ float a, /* in */ float b, /* in */ float c, /* out */ float& root1, /* out */ float&
root2 )// Precondition: a, b, and c are assigned// && a != 0 && b*b - 4*a*c != 0// Postcondition: root1 and root2 are assigned // && root1 and root2 are roots of quadratic with coefficients a, b, c{
float temp;
temp = b * b - 4.0 * a * c;
root1 = (-b + sqrt(temp) ) / ( 2.0 * a );
root2 = (-b - sqrt(temp) ) / ( 2.0 * a );
return;}
50
51
Función con Preconditions y Postconditions
void Swap( /* inout */ int& firstInt,
/* inout */ int& secondInt )
// Precondition: firstInt and secondInt are assigned
// Postcondition: firstInt == secondInt@entry
// && secondInt == firstInt@entry
{ int temporaryInt ;
temporaryInt = firstInt ;
firstInt = secondInt ;
secondInt = temporaryInt ;
} 51
52
G etD ata () C a lcD ivis ion () S h ow R esu lts ()
m a in ()a, bParámetros por referencia
a, b q, r
q, rParámetros por valor
Laboratorio # 1- ParámetrosDe acuerdo al siguiente Structure Chart
Pasa el siguiente código al compilador y pruebalo
53
Laboratorio 1 – (cont.)// Programa: división.cpp// Calcula el cociente y el residuo de 2 numeros enteros# include <iostream>using namespace std;// Prototiposvoid GetData (int &a, int &b)void CalcDivision (int a, int b, int &q, int &r);void ShowResults (int q, int r);int main(){
int num1, num2, quotient, remainder;GetData (num1, num2);CalcDivision(num1, num2, quotient, remainder);ShowResults(quotient, remainder);return 0;
}
54
Laboratorio 1 – (cont.)void GetData(int &a, int &b){
cout << “Enter two integres: “;cin >> a >> b;
}void CalcDivision(int a, int b, int &q, int &r){
q = a / b;r = a % b;
}void ShowResults(int q, int r){
cout << “The quotient is “ << q << “and the remainder is “ << r << endl;
}
55
Laboratorio 1 – completo// Programa: división.cpp// Calcula el cociente y el residuo de 2 numeros enteros# include <iostream>using namespace std;// Prototiposvoid GetData (int &a, int &b)void CalcDivision (int a, int b, int &q, int &r);void ShowResults (int q, int r);int main(){
int num1, num2, quotient, remainder;GetData (num1, num2);CalcDivision(num1, num2, quotient, remainder);ShowResults(quotient, remainder);return 0;
}void GetData(int &a, int &b){
cout << “Enter two integres: “;cin >> a >> b;
}void CalcDivision(int a, int b, int &q, int &r){
q = a / b;r = a % b;
}void ShowResults(int q, int r){
cout << “The quotient is “ << q << “and the remainder is “ << r << endl;}
56
Laboratorio 1 – (cont.)
Si queremos devolver uno de los valores de forma directa, podemos poner:int CalcDivision (int a, int b, int &q){
q = a / b;return a % b;
}
Y en la instrucción se tiene que poner:remainder = CalcDivision(num1, num2, quotient) Se puede aunque es
un poco confuso.
main() GetData() CalcDivision()
num1 [6] a [dirección num1] a [6]
num2 [3] b [dirección num2] b [3]
quotient [2] q [dirección quotient]
remainder [0] r [dirección remainder]
57
Laboratorio # 2 – Archivos y Parámetros
Vamos a leer de un archivo (rectángulo.dat) el id del rectángulo (numero), la base y altura. Finalmente guardamos el id del rectángulo y su area en un archivo llamado areas.dat.
a:\rectangulo.dat a:\areas.dat1 4.3 5.82 6.7 2.43 5.6 6.5
1 24.92 16.03 36.4
58
Laboratorio # 2 – (cont.)
G etD ataF rom F ile () C a lcA rea() W riteR esu lts In toF ile ()
m a in ()while ¡eof
59
Laboratorio # 2 – (cont.)// Programa: rect.cpp// Este programa lee de un archivo la base y altura de un
rectángulo y calcula el area.// El área se guarda en otro archivo. Este programa utiliza
funciones, parámetros por valor y por// referencia y manejo de archivo. También utiliza ciclo while.# include <fstream># include <iomanip>using namespace std;// Prototiposvoid GetDataFromFile(ifstream &ArchDatos, int &id, float
&base, float &altura);float CalcArea(float base, float altura);void WriteDataIntoFile(ofstream &ArchResultado, int id, float
area);
60
Laboratorio # 2 – (cont.)int main(){
ifstream ArchRectangulos;ofstream ArchAreas;int IdRect;float BaseRect, AlturaRect, AreaRect;ArchRectangulos.open(“a:\\rectangulos.dat”);ArchAreas.open(“a:\\areas.dat”);ArchAreas << fixed << Showpoint << setpresicion(1);GetDataFromFile(ArchRectangulos, IdRect, BaseRect, AlturaRect);while (¡ArchRectangulos.eof()){
AreaRect = CalcArea(BaseRect, AlturaRect);WriteDataIntoFile(ArchAreas, IdRect);GetDataFromFile(ArchRectangulos, IdRect, BaseRect,
AlturaRect);}ArchRectangulos.close();ArchAreas.close();return 0;}
61
Laboratorio # 2 – (cont.)
void GetDataFromFile (ifstream &ArchDatos, int &id, float &base, float &altura)
{ArchDatos >> id >> base >> altura;
}float CalcArea(float base, float altura){
return base * altura;}void WriteDataIntoFile(ofstream &ArchResultados, int id, float area){
ArchResultados << id << “ “ << area << endl;}
62
Laboratorio # 2 completo– (cont.)// Programa: rect.cpp// Este programa lee de un archivo la base y altura de un rectángulo y calcula el area.// El área se guarda en otro archivo. Este programa utiliza funciones, parámetros por valor y por// referencia y manejo de archivo. También utiliza ciclo while.# include <fstream># include <iomanip>using namespace std;// Prototiposvoid GetDataFromFile(ifstream &ArchDatos, int &id, float &base, float &altura);float CalcArea(float base, float altura);void WriteDataIntoFile(ofstream &ArchResultado, int id, float area);int main(){
ifstream ArchRectangulos;ofstream ArchAreas;int IdRect;float BaseRect, AlturaRect, AreaRect;ArchRectangulos.open(“a:\\rectangulos.dat”);ArchAreas.open(“a:\\areas.dat”);ArchAreas << fixed << Showpoint << setpresicion(1);GetDataFromFile(ArchRectangulos, IdRect, BaseRect, AlturaRect);while (¡ArchRectangulos.eof()){
AreaRect = CalcArea(BaseRect, AlturaRect);WriteDataIntoFile(ArchAreas, IdRect);GetDataFromFile(ArchRectangulos, IdRect, BaseRect, AlturaRect);
}ArchRectangulos.close();ArchAreas.close();return 0;}
void GetDataFromFile (ifstream &ArchDatos, int &id, float &base, float &altura){
ArchDatos >> id >> base >> altura;}float CalcArea(float base, float altura){
return base * altura;}void WriteDataIntoFile(ofstream &ArchResultados, int id, float area){
ArchResultados << id << “ “ << area << endl;}