Herramientas de usuario

Herramientas del sitio


curso-cpp:modularizacion-funciones

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
Última revisión Ambos lados, revisión siguiente
curso-cpp:modularizacion-funciones [2017/03/20 01:51]
santo [Ejemplos de implementación de funciones]
curso-cpp:modularizacion-funciones [2017/09/22 16:26]
santo [Algunos ejemplos de macros muy útiles]
Línea 93: Línea 93:
 ==== Facilitar un enfoque top-down ==== ==== Facilitar un enfoque top-down ====
  
-Esta ventaja está estrechamente relacionada con la anterior. Supongamos que nos dieran la siguiente ​consiga:+Esta ventaja está estrechamente relacionada con la anterior. Supongamos que nos dieran la siguiente ​consigna:
  
 "Crear un programa que lea dos números ''​a''​ y ''​b'',​ que indican un rango de números (inclusive),​ y calcule y muestre en la pantalla dos valores: La suma de los cuadrados de todos los números primos entre a y b, y además, la suma de todos los números entre a y b que son múltiplos de 3 y de 10, pero no de 30." "Crear un programa que lea dos números ''​a''​ y ''​b'',​ que indican un rango de números (inclusive),​ y calcule y muestre en la pantalla dos valores: La suma de los cuadrados de todos los números primos entre a y b, y además, la suma de todos los números entre a y b que son múltiplos de 3 y de 10, pero no de 30."
Línea 231: Línea 231:
 ===== Parámetros ===== ===== Parámetros =====
  
-No siempre queremos que una función haga exactamente lo mismo cada vez que usa. A veces, queremos que haga **casi** lo mismo, pero cambiando algún **dato** entre usos. Por ejemplo, podríamos querer una función que eleve un número al cuadrado, es decir, que permita calcular ''​x*x''​ si ya tenemos un entero ''​x''​. Así, cuando usamos la función con 3, queremos que devuelva ''​3*3 == 9'',​ y cuando la usamos con -4 queremos que devuelva ''​(-4)*(-4) == 16''​.+No siempre queremos que una función haga exactamente lo mismo cada vez que se usa. A veces, queremos que haga **casi** lo mismo, pero cambiando algún **dato** entre usos. Por ejemplo, podríamos querer una función que eleve un número al cuadrado, es decir, que permita calcular ''​x*x''​ si ya tenemos un entero ''​x''​. Así, cuando usamos la función con 3, queremos que devuelva ''​3*3 == 9'',​ y cuando la usamos con -4 queremos que devuelva ''​(-4)*(-4) == 16''​.
  
 En el ejemplo anterior la función no hace siempre lo mismo, porque a veces hace 3*3 y a veces (-4)*(-4), pero más allá del número que vamos a elevar, las **operaciones** que hace la función son siempre las mismas, y solo cambia este **dato** inicial. A ese **dato que cambia**, lo llamamos en programación un **parámetro** de la función. Una función puede tener 1 o más parámetros,​ o incluso cero: Las funciones que vimos antes tenían cero parámetros. La función de elevar al cuadrado tendría un único parámetro: El número entero que vamos a querer elevar. En el ejemplo anterior la función no hace siempre lo mismo, porque a veces hace 3*3 y a veces (-4)*(-4), pero más allá del número que vamos a elevar, las **operaciones** que hace la función son siempre las mismas, y solo cambia este **dato** inicial. A ese **dato que cambia**, lo llamamos en programación un **parámetro** de la función. Una función puede tener 1 o más parámetros,​ o incluso cero: Las funciones que vimos antes tenían cero parámetros. La función de elevar al cuadrado tendría un único parámetro: El número entero que vamos a querer elevar.
Línea 554: Línea 554:
  
   * Nuestro primer ejemplo es la función ''​main'',​ que ya venimos usando en todos nuestros programas: Es una función que devuelve un ''​int'',​ que usa la computadora para saber si hubo errores. Por convención,​ se debe devolver cero si todo salió bien, y por eso es buena costumbre terminar todos los programas con ''​return 0''​. La función ''​main''​ es importante porque tiene la característica especial de que allí comienzan a ejecutarse todos nuestros programas, aunque tengan otras funciones.   * Nuestro primer ejemplo es la función ''​main'',​ que ya venimos usando en todos nuestros programas: Es una función que devuelve un ''​int'',​ que usa la computadora para saber si hubo errores. Por convención,​ se debe devolver cero si todo salió bien, y por eso es buena costumbre terminar todos los programas con ''​return 0''​. La función ''​main''​ es importante porque tiene la característica especial de que allí comienzan a ejecutarse todos nuestros programas, aunque tengan otras funciones.
-  * Como ejemplo de pensamiento top-down, supongamos que debemos realizar un programa que lea una secuencia de números, y luego calcule y muestre por pantalla la suma, el máximo y el mínimo de todos estos números. Podemos programar primero que anda el main de la siguiente manera: +  * Como ejemplo de pensamiento top-down, supongamos que debemos realizar un programa que lea una secuencia de números, y luego calcule y muestre por pantalla la suma, el máximo y el mínimo de todos estos números. Podemos programar primero que anda el main de la siguiente manera:<​code>​ 
-    ​<​code>​ +int main() 
-    int main() +
-    +    vector<​int>​ v; 
-        vector<​int>​ v; +    v = leerNumeros();​ 
-        v = leerNumeros();​ +    imprimirResultados(suma(v),​ maximo(v), minimo(v));​ 
-        imprimirResultados(suma(v),​ maximo(v), minimo(v));​ +    return 0; 
-        return 0; +
-    +</​code>​ Donde nos hemos ordenado y hemos logrado **descomponer** el problema entero en tareas más pequeñas. Luego podríamos agregarle las funciones que faltan al programa, para completarlo, dejando inalterado el mismo main que ya escribimos: <​code>​ 
-    </​code>​ +vector<​int>​ leerNumeros() 
-     +
-    ​Donde nos hemos ordenado y hemos logrado **descomponer** el problema entero en tareas más pequeñas. Luego podríamos agregarle las funciones que faltan al programa, para completarlo:​ +    // instrucciones... 
-     +}
-    ​<​code>​ +
-    vector<​int>​ leerNumeros() +
-    { +
-        // instrucciones... +
-    ​+
-     +
-    int suma(vector<​int>​ v) +
-    { +
-        ​// instrucciones... +
-    } +
-     +
-    int maximo(vector<​int>​ v) +
-    { +
-        // instrucciones... +
-    } +
-     +
-    int minimo(vector<​int>​ v) +
-    { +
-        // instrucciones... +
-    } +
-     +
-    void imprimirResultados(int laSuma,int elMaximo, int elMinimo) +
-    { +
-        // instrucciones... +
-    } +
-    </​code>​+
  
 +int suma(vector<​int>​ v)
 +{
 +    // instrucciones...
 +}
 +
 +int maximo(vector<​int>​ v)
 +{
 +    // instrucciones...
 +}
 +
 +int minimo(vector<​int>​ v)
 +{
 +    // instrucciones...
 +}
 +
 +void imprimirResultados(int laSuma,int elMaximo, int elMinimo)
 +{
 +    // instrucciones...
 +}
 +</​code>​
 +
 +  * El siguiente es un ejemplo con funciones que calculan áreas de figuras geométricas,​ que muestra como podemos reutilizar ciertas funciones dentro de otras: <​code>​
 +int areaParalelogramo(int base, int altura)
 +{
 +    return base * altura;
 +}
 +int areaCuadrado(int lado)
 +{
 +    return areaParalelogramo(lado,​ lado);
 +}
 +int areaTriangulo(int base, int altura) // Trabaja con enteros: Redondea hacia abajo
 +{
 +    return areaParalelogramo(base,​ altura) / 2;
 +}
 +</​code>​
 +  * El siguiente es un ejemplo de función que recibe dos variables enteras, e intercambia sus valores. ¡Notar el uso del ampersand! <​code>​
 +void intercambiar(int &​variable1,​ int &​variable2)
 +{
 +    int auxiliar = variable1; // Es necesario un auxiliar: ¿Por qué?
 +    variable1 = variable2;
 +    variable2 = auxiliar;
 +} </​code>​ Similarmente,​ el siguiente ejemplo permite "​rotar"​ los valores de tres variables dadas: Es decir, transforma [a,b,c] en [b,c,a]: <​code>​
 +void rotar3(int &a, int &b, int &c)
 +{
 +   int auxiliar = a; // Nuevamente, ¿Por qué es necesario el auxiliar?
 +   a = b;
 +   b = c;
 +   c = auxiliar;
 +}
 +</​code>​
 ===== Algunas funciones predefinidas ===== ===== Algunas funciones predefinidas =====
  
Línea 603: Línea 627:
  
 Todas estas funciones requieren utilizar ''#​include <​algorithm>''​ para tenerlas disponibles. Todas estas funciones requieren utilizar ''#​include <​algorithm>''​ para tenerlas disponibles.
 +
 +===== Algunos errores comunes =====
 +
 +   * Pasar a la función una cantidad de parámetros diferente de las que la función necesita, o con el tipo incorrecto. Por ejemplo si tenemos la función <​code>​
 +int mayor(int num1, int num2)
 +{
 +    if (num1 > num2)
 +        return num1;
 +    else
 +        return num2;
 +}
 +</​code>​ serían incorrectas las siguientes llamadas: <​code>​
 +mayor(k,​m,​n) // Pasa 3 parámetros,​ pero la función toma solamente 2
 +mayor(23, "​miliwatt"​) // Pasa 2 parámetros,​ pero el segundo es una cadena y debería ser un int
 +</​code>​
 +   * Diseñar una función con la idea de que **modifique** uno de sus parámetros,​ pero trabajar con una copia por no utilizar el ampersand ''&''​.
 +   * Intentar utilizar un parámetro (con su nombre) **fuera** de una función: Los parámetros solamente están definidos dentro de la función, y no tiene sentido utilizarlos fuera de ella (son variables locales).
 +   * Utilizar una función que todavía no se definió. Se debe programar el código de una función, antes de utilizarla.
 ===== Ejercicios ===== ===== Ejercicios =====
  
Línea 609: Línea 651:
 Por ejemplo, en los ejercicios en los que se hablaba de números primos, se podría escribir una función que toma un ''​int N'',​ y devuelve un ''​bool''​ indicando si es primo. O por ejemplo, escribir una función ''​sumaDeDivisores''​ puede ser útil para escribir de forma más fácil y clara programas que buscan números perfectos. Por ejemplo, en los ejercicios en los que se hablaba de números primos, se podría escribir una función que toma un ''​int N'',​ y devuelve un ''​bool''​ indicando si es primo. O por ejemplo, escribir una función ''​sumaDeDivisores''​ puede ser útil para escribir de forma más fácil y clara programas que buscan números perfectos.
  
 +Otros ejercicios:
 +
 +   * Escribir una función ''​string escribirEnBase(int numero, int base)'',​ que tome un número y una base (Entre 2 y 16 inclusive) y devuelva una cadena con la escritura de ese número en la base indicada.
 +   * Escribir una función ''​int leerNumeroEnBase(string escritura, int base)'',​ que tome la escritura de un cierto número en la base indicada (Entre 2 y 16 inclusive) y devuelva el número en cuestión.
 +
 +Puede ver aquí [[algoritmos-oia:​enteros:​cambio-de-base|cómo realizar cambios de base]].
 ===== Los #define ===== ===== Los #define =====
  
Línea 700: Línea 748:
 Vemos que ahora solamente hace falta especificar **una vez** el nombre de la variable, y todo lo demás es copiado automáticamente en forma mecánica por el ''#​define''​. Vemos que ahora solamente hace falta especificar **una vez** el nombre de la variable, y todo lo demás es copiado automáticamente en forma mecánica por el ''#​define''​.
  
-Se puede consultar [[cpp-avanzado:​macros |aquí]] otros ejemplos de macros muy útiles para programación competitiva,​ además del ''​forn''​ ya mostrado.+Se puede consultar [[cpp-avanzado:​macros |aquí]] otros ejemplos de macros ​más avanzadas, ​muy útiles para programación competitiva,​ además del ''​forn''​ ya mostrado.
 ==== Por qué es mejor usar funciones ==== ==== Por qué es mejor usar funciones ====
  
curso-cpp/modularizacion-funciones.txt · Última modificación: 2017/10/29 19:24 por santo