Funciones inline
Las funciones inline ayudan a reducir el llamado excesivo de funciones, en especial cuando son pequeñas. Utilizar el calificador inline le "aconseja" al compilador que genere una copia del código de la función en el lugar, cuando sea apropiado, para evitar un llamado a la misma. La diferencia es que múltiples copias del código de la función son insertadas en el programa, en vez de existir una sola copia de la funcion a la cual es pasada el control cada vez que es llamada. El compilador puede ignorar el calificador inline y normalmente lo hace, con excepcin de las funciones más pequeñas.
Usar funciones inline puede reducir el tiempo de ejecución, pero también aumentar el tamaño del programa.
Ejercicio 6.55 - How to Program, 5th Edition
Referencias y parámetros de referencias
Dos formas de pasar argumentos a funciones son por valor y por referencia. Cuando un argumento es pasado por valor, una copia del valor del argumento es creada y pasada a la función llamada. Cambios a la copia no afectan el valor de la variable original en la que llamó.
Pasando argumentos por valor y por referencia
Figura 6.19 compara un paso por valor y uno por referencia con parámetros de refenrecia. Los "estilos" de los argumentos en las llamadas a squareByValue y squareByFunction son idénticos. Ambas variables son simplemente llamadas por nombres in las llamadas de función. Sin revisar los prototipos o definiciones de función, no es posible decir, a partir solamente de las llamadas, si alguna de las funciones puee modificar sus argumentos.
1 // Fig. 6.19: fig06_19.cpp
2 // Comparing pass-by-value and pass-by-reference with references.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6
7 int squareByValue( int ); // function prototype (value pass)
8 void squareByReference( int & ); // function prototype (reference pass)
9
10 int main()
11 {
12 int x = 2; // value to square using squareByValue
13 int z = 4; // value to square using squareByReference
14
15 // demonstrate squareByValue
16 cout << "x = " << x << " before squareByValue\n";
17 cout << "Value returned by squareByValue: "
18 << squareByValue( x ) << endl;
19 cout << "x = " << x << " after squareByValue\n" << endl;
20
21 // demonstrate squareByReference
22 cout << "z = " << z << " before squareByReference" << endl;
23 squareByReference( z );
24 cout << "z = " << z << " after squareByReference" << endl;
25 return 0; // indicates successful termination
26 } // end main
27
28 // squareByValue multiplies number by itself, stores the
29 // result in number and returns the new value of number
30 int squareByValue( int number )
31 {
32 return number *= number; // caller's argument not modified
33 } // end function squareByValue
34
35 // squareByReference multiplies numberRef by itself and stores the result
36 // in the variable to which numberRef refers in function main
37 void squareByReference( int &numberRef )
38 {
39 numberRef *= numberRef; // caller's argument modified
40 } // end function squareByReference
|
Ejercicio 6.56 - How to Program, 5th Edition
Sobrecarga de función
C++ permite la definición de varias funciones con el mismo nombre, siempre y cuando estas funciones tengan diferentes sets de parámetros. Cuando una función sobrecargada es llamada, el compilador C++ selecciona la función apropiada examinando el número, tipo y orden de los argumentos en la llamada. Sobrecarga de funciones es comunmente usada para crear varias funciones con el mismo nombre que llevan a cabo tareas similares, pero con diferentes tipos de data.
1 // Fig. 6.24: fig06_24.cpp
2 // Overloaded functions.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6
7 // function square for int values
8 int square( int x )
9 {
10 cout << "square of integer " << x << " is ";
11 return x * x;
12 } // end function square with int argument
13
14 // function square for double values
15 double square( double y )
16 {
17 cout << "square of double " << y << " is ";
18 return y * y;
19 } // end function square with double argument
20
21 int main()
22 {
23 cout << square( 7 ); // calls int version
24 cout << endl;
25 cout << square( 7.5 ); // calls double version
26 cout << endl;
27 return 0; // indicates successful termination
28 } // end main
|
Ejercicio 6.58 - How to Program, 5th Edition
Plantillas de funciones
Las funciones sobrecargadas son normalmente usadas para llevar a cabo operaciones similares que toman en cuenta lógica diferente sobre tipos de data diferentes. Si la lógica y operaciones son idénticas para cada tipo de data, la sobrecarga podría ser realizada de manera más compacta y conveniente usando plantillas de funciones. El programados escribe una única definición de plantilla de función. Dados los tipos de argumentos en las llamadas a esta función, C++ genera automaticamente especializaciones separadas de la plantilla de función para manejar cada tipo de llamada de forma apropiada. Así, define una única plantilla de función que esencialmente define una familia completa de funciones sobrecargadas.
La figura 6.26 contiene la definición de una plantilla. para una función maximum que determina el mayor de tres valores. Todas las plantillas de función comienzan con la palabra clave template seguida por una lista de parámetros de plantilla para la plantilla de función y encerrada en < >. Cada parámetro es antecedido por las palabras claves typename o class. Estos son placeholders para tipos definidos por el usuario. Estos placeholders son usados para especificar tipos de parámetros para la función, tipos de retorno y para declarar variables dentro del cuerpo de la definición de la función.
1 // Fig. 6.26: maximum.h
2 // Definition of function template maximum.
3
4 template < class T > // or template< typename T >
5 T maximum( T value1, T value2, T value3 )
6 {
7 T maximumValue = value1; // assume value1 is maximum
8
9 // determine whether value2 is greater than maximumValue
10 if ( value2 > maximumValue )
11 maximumValue = value2;
12
13 // determine whether value3 is greater than maximumValue
14 if ( value3 > maximumValue )
15 maximumValue = value3;
16
17 return maximumValue;
18 } // end function template maximum |
Ejercicio 6.59 - How to Program, 5th Edition
Recursividad
Una función recursiva es una función que se llama a sí misma, ya sea directa o indirectamente(a través de otra función). Recursividad es un tema importante my discutido en los cursos avanzados de las carreras ligadas a la informática.
Demonstrating function factorial.
1 // Fig. 6.29: fig06_29.cpp
2 // Testing the recursive factorial function.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6
7 #include <iomanip>
8 using std::setw;
9
10 unsigned long factorial( unsigned long ); // function prototype
11
12 int main()
13 {
14 // calculate the factorials of 0 through 10
15 for ( int counter = 0; counter <= 10; counter++ )
16 cout << setw( 2 ) << counter << "! = " << factorial( counter )
17 << endl;
18
19 return 0; // indicates successful termination
20 } // end main
21
22 // recursive definition of function factorial
23 unsigned long factorial( unsigned long number )
24 {
25 if ( number <= 1 ) // test for base case
26 return 1; // base cases: 0! = 1 and 1! = 1
27 else // recursion step
28 return number * factorial( number - 1 );
29 } // end function factorial
|
La función factorial ha sido declarada para recibir un parámetro de tipo unsigned long y regresar un resultado de tipo unsigned long. Escogemos unsignes long para que el programa pueda calcular factoriales mayores que 7!, aún cuando al final de cuentas ni siquiera este tipo alcanza con lo rápido que crece la función factorial.
Ejercicio 6.42 - How to Program, 5th Edition
Recursividad vs. Iteración
Iteración usa una estructura de repetición y recursividad una estructura de selección. Ambas tienen que ver con repetición.Ambas llevan a cabo un test de terminación. Ambas pueden ocurrir infinitamente.
Solución factorial por iteración.
1 // Fig. 6.32: fig06_32.cpp
2 // Testing the iterative factorial function.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6
7 #include <iomanip>
8 using std::setw;
9
10 unsigned long factorial( unsigned long ); // function prototype
11
12 int main()
13 {
14 // calculate the factorials of 0 through 10
15 for ( int counter = 0; counter <= 10; counter++ )
16 cout << setw( 2 ) << counter << "! = " << factorial( counter )
17 << endl;
18
19 return 0;
20 } // end main
21
22 // iterative function factorial
23 unsigned long factorial( unsigned long number )
24 {
25 unsigned long result = 1;
26
27 // iterative declaration of function factorial
28 for ( unsigned long i = number; i >= 1; i-- )
29 result *= i;
30
31 return result;
32 } // end function factorial
|
Recursividad tiene varios contras. Invoca repetidamente el mecanismo y consecuentemente el sobrellamado de funciones. Esto puede resultar caro tanto en tiempo de procesador, como espacio de memoria. Cada llamada recursiva causa que otra copia sea creada, lo cual puede consumir mucha memoria. Iteración normalmente ocurre dentro de una función, por lo que el sobrellamado de funciones repetidas y asignación de memoria es omitido.
Arreglos
Un arreglo es un grupo consecutivo de locaciones en memoria, los cuales todos tienen el mismo tipo. Para referenciar una posición en particular, se especifíca el nombre del arreglo y el número de posición de dicho elemento dentro del arreglo.
Ejercicio 7.8- How to Program, 5th Edition
Precedencia y asociatividad de operadores
| Operators |
Associativity |
Type |
||||||
|---|---|---|---|---|---|---|---|---|
() |
[] |
left to right |
highest |
|||||
++ |
-- |
static_cast<type>( operand ) |
left to right |
unary (postfix) |
||||
++ |
-- |
+ |
- |
! |
right to left |
unary (prefix) |
||
* |
/ |
% |
left to right |
multiplicative |
||||
+ |
- |
left to right |
additive |
|||||
<< |
>> |
left to right |
insertion/extraction |
|||||
< |
<= |
> |
>= |
left to right |
relational |
|||
== |
!= |
left to right |
equality |
|||||
&& |
left to right |
logical AND |
||||||
|| |
left to right |
logical OR |
||||||
?: |
right to left |
conditional |
||||||
= |
+= |
-= |
*= |
/= |
%= |
right to left |
assignment |
|
, |
left to right |
comma |
||||||