Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: FKT en 23 Agosto 2015, 17:14 pm



Título: Funciones
Publicado por: FKT en 23 Agosto 2015, 17:14 pm
Hola, quiero hacer un programa con funciones, se más o menos como funcionan pero necesito saber que significa el retorno y como funciona.
Siempre he tenido la necesidad de saber como funciona algo pero desde la raíz.
Si alguien puede explicarme como funciona para que sirve y algunos detalles más.

(Hize un tema referido a los retornos pero no me quedo claro, y me vuelve ha surgir la misma duda)

Gracias.


Título: Re: Funciones
Publicado por: avesudra en 23 Agosto 2015, 17:31 pm
El valor de retorno es lo que te devuelve la función.

Imagina que has programado la función multiplicarPorDos y que recibe un parámetro. El valor de retorno es la respuesta que esa función da a los datos que se le proporcionan.

Ejemplos:

multiplicarPorDos(2) ----------> Valor de retorno: 4
multiplicarPorDos(5) ----------> Valor de retorno: 10
multiplicarPorDos(7) ----------> Valor de retorno: 14

¿Cómo funciona? Pues así de sencillo(este programa imprime el valor devuelto por la función multiplicarPorDos)

Código
  1. #include <stdio.h>
  2.  
  3. int multiplicarPorDos(int argumento);
  4.  
  5. int main(int argc, char **argv)
  6. {
  7.     int valorDevuelto;
  8.  
  9.     valorDevuelto = multiplicarPorDos(4);
  10.  
  11.     printf("%d", valorDevuelto);
  12.  
  13.     return 0;
  14. }
  15.  
  16. int multiplicarPorDos(int argumento)
  17. {
  18.    return argumento * 2;
  19. }

Las funciones son algoritmos generalmente pequeños, que resuelven problemas concretos a partir de unos datos proporcionados. Las soluciones se pueden dar a través del valor de retorno o a través de parámetros (como punteros).


Título: Re: Funciones
Publicado por: engel lex en 23 Agosto 2015, 17:33 pm
Las funciones puedes separarlas como

Tipo Nombre(parametros){//aqui inicia
  Acciones
  Retorno //si no es void
}//aqui cierra

El tipo, es el tipo de valor que retornará, void, implica que no retorna nada

el nombre no debe contener espacios, caracteres especiales y no debe iniciar en número

Los parámetros son las variables que se le pasarán, el nombre es como se representarán dentro de la función y si tipo debe coincidir con el original

Las funciones tienen un "alcance" al que se le llama "scope" esto representa que verán y que no, al estar aparte del main, normalmente desconocen cualquier referencia a toda variable declarada allí

Por ultimo el retorno, es simplemente un valor que devolverán, si la función es asignada a una variable ejemplo

Código
  1. int variable = funcion_algo();

La variable contendrá lo que sea que la funcion retorne

Algo importante de recordar, el retorno es el fin de la función, si se hace la función termina

Código
  1. int ejecutar (){
  2. int a = 1;
  3. return a;
  4. Esto_nunca_pasara();
  5. }


Título: Re: Funciones
Publicado por: FKT en 23 Agosto 2015, 18:41 pm
Entiendo, entonces de momento lo único que no he entendido de lo que me habéis explicado es:
Lo que se pone entre "(Aquí)", los parámetros, son las variables que se podrán utilizar en main¿?


Título: Re: Funciones
Publicado por: engel lex en 23 Agosto 2015, 18:59 pm
los parámetros que van entre paréntesis son los valores que recibirá la función

Código
  1. int suma(int sumando1, int sumando2){
  2.  int resultado = sumando1 + sumndo2;
  3.  return resultado;
  4. }



Título: Re: Funciones
Publicado por: FKT en 23 Agosto 2015, 19:37 pm
Vale... Y porque en la función principal no se pone?

      
Código
  1.  
  2. int main(r1, r2)
  3.  
  4.    int resultado = r1 + r2;
  5.  
  6.    return resultado;
  7. }
  8.  
  9.  
Y otra cosa, para que necesitamos que los programas retornen un valor que no sea 0¿?
Eso indica que el problema ha finalizado con errores no es así?


Título: Re: Funciones
Publicado por: engel lex en 23 Agosto 2015, 19:44 pm
ahh sobre main!

el main tiene 2 parámetros predispuestos por el compilador, puedes usarlos o no...


cuando el programa se compila, a main se le pasan 2 valores

Código
  1. int argc, char **argv

el primero es un entero que indica la cantidad de argumentos pasados por consola (siempre será por lo menos 1 ya que el primero es el programa en si mismo) el segundo es un array que contiene uno o más char array con los argumentos (como dije el primero será el programa)

ejemplo en consola escribes

Código:
programa.exe

el ejecutará tu programa y argc será 1 y argv[0] será "programa.exe"

si ejecutas
Código:
programa.exe parametro1 parametro2

el ejecutará tu programa y argc será 3, argv[0] será "programa.exe", argv[1] será "parametro1" y argv[2] será "parametro2"

por eso solo se usan esos valores...

el return de main tiende a ser siempre 0, en este casi para la consola "0" significa todo bien...

siem embargo puedes hacer un programa suma.exe que retorne un valor diferente a 0, esto sería para que otro programa llamara a "suma.exe" y su valor de ejecución sería el que quieras... (sería similar a tu ejemplo, solo que los numeros a sumar sería argv[1] y argv[2])

muchas veces algo diferente de 0 tambien significa error (y el numero es el numero de error)


Título: Re: Funciones
Publicado por: Orubatosu en 23 Agosto 2015, 19:49 pm
Piensa en la función como en un bloque de código separado, que no tiene ninguna conexión con el principal (es mas sencillo así)

Consideralo un programa autónomo y separado, al que le suministras una serie de datos (los parámetros) y te devuelve un resultado (el retorno)

Los parámetros son variables que están en el programa principal, que puedes pasar para que maneje como una copia o directamente (eso quizás no has llegado a verlo). Por ahora imagina que solo le envías una copia de esos valores

Es decir, la función es un programa separado, con sus propias variables y constantes si las necesitara, que están completamente aislada del programa principal. De hecho, desde la función las variables del programa principal son invisibles, y las que uses en la función no existen fuera de la misma.

Cuando tienes el resultado deseado, devuelves el control al programa, y lo devuelves en forma de un resultado. Ese resultado es el que pones como "retorno"

Lo bueno es que no tiene que ser uno solo, puedes programar mas de un retorno dependiendo de lo que quieras.

Solo tienes que ser cuidado de que el tipo de función y el resultado tienen el mismo tipo (entero, coma flotante, caracter, booleano, etc).

Mira, un ejemplo cutre y pedreste

Código
  1. // vocal o consonante
  2. #include <iostream>
  3. using namespace std;
  4.  
  5. bool vocal(char n){
  6.    if (n == 65 || n == 97 || n == 69 || n == 101 || n == 73 || n == 105 || n == 79 || n == 111
  7.     || n == 85 || n == 117){
  8.     return true;
  9.     } else {return false;
  10.     }
  11. }
  12.  
  13. int main () {
  14.    char c;
  15.    int n;
  16.    cout << "Introduce un caracter ";
  17.    cin >> c;
  18.    n = int(c);
  19.    cout << "El caracter es :";
  20.    if (vocal (c)){
  21.        cout << " vocal";
  22.    }else {
  23.    cout << " consonante";}
  24. }

Código
  1. bool vocal(char n)

Bool es el típo de resultado que devuelve la función. "vocal" es el nombre de la función, y entre paréntesis está "char n". Eso quiere decir que la función recibe un parámetro desde el programa principal, que es de tipo caracter, y que dentro de la función llamaremos "n"

Luego, en el programa hacemos esto:

Código
  1. if (vocal (c))

Tenemos un "if", y como condición tenemos la función (podemos hacerlo porque la función devuelve un booleano). "c" es el nombre de la variable que usamos en el programa principal.

No hay mas misterio. Desde el programa cogemos un caracter "c" y en la función usamos "n", porque al ser programas distintos a efectos prácticos el nombre de la variable es irrelevante.

Al margen de esto, es posible que una función manipule los parámetros, pero eso lo verás mas adelante

De hecho, es posible, y se hace en otros lenguajes que esas funciones estén incluso en ficheros separados. Piensa siempre en las funciones como en otro programa, que accidentalmente está en la misma "hoja" que el principal, pero que no se relaciona con el mismo mas que a través de parámetros y retorno.


Título: Re: Funciones
Publicado por: FKT en 23 Agosto 2015, 20:40 pm
Para: egel lex.

No, lo estabas explicando bien jeje estaba hablando de las funciones que no son de int main(), lo que estaba preguntando es porque si en una funcion que no es main() no se declaran las variables en los parametros también?, aparte de que me has aclarado algunas dudas, has echo que me surgan otras como por ejemplo que es un array y que significan los "**" de argv?, es lo mismo si pones los parametros o no en una función main()?

Para: Orubatosu.

Cuando dices que me devuelve un resultado (el retorno) es para que en tu función principal puedas llamar a tu subprograma?
Y si por ejemplo fuera un subprograma con void, para que sirve si no puedes llamarlo en main() ya que su retorno es 0?
              
Citar

Solo tienes que ser cuidado de que el tipo de función y el resultado tienen el mismo tipo (entero, coma flotante, caracter, booleano, etc).


O no lo entiendo o lo has escrito mal, te refieres a que no puedo tener dos funciones que se llamen "int funcion" o que no puedo hacer dos funciones con el mismo tipo de dato?

Ahora leyendo tu ejemplo lo he entendido pero he seguido y al final me has liado jeje.
Aver como has dicho es un programa "paralelo", pues que pinta el:
          
Código
  1. n = int(c)

si "C" es un caracter.

Y lo que no entiendo es lo que conecta los dos programas es solo el retorno o el parametro también?

(Uso C y no C++) así que me cuesta un poco mas entenderlo.


Título: Re: Funciones
Publicado por: Orubatosu en 23 Agosto 2015, 21:47 pm
Bueno, C++ y C son muy muy parecidos, lo que vale en C vale en C++ en principio.

A ver, una función void puede funcionar perfectamente, por ejemplo en casos donde la función trabaja directamente con valores del programa principal. Eso es lo que se llama "pasar valores por referencia" (de momento no te preocupes por eso) y que entre otras utilidades tiene la de ahorrar memoria. Eso es así, porque al pasar un valor como argumento a la función, lo que haces es crear una copia de esa variable, usarla en la función y destruirla al finalizar esa función.

Esto es irrelevante cuando lo que pasas como argumento es un entero, o un caracter. En cambio si pasas (por ejemplo) un vector de 1000 elementos la cosa cambia mucho (un vector es un contenedor, una clase de C++). Bueno, ese no es el tema.

Puedes tener las funciones que quieras, pero siempre hay que asegurarse de que el valor que devuelves sea del mismo tipo que la función.

Es decir, si tu función empieza así:

int nombredefunción(int a, int b)

El valor que devuelves en return debe de ser de tipo entero. No de otro, en ese caso probablemente ni siquiera compile.

Mi ejemplo usa  boolean porque es un caso donde creo se ilustra mejor como trabajan las funciones. Si en mi ejemplo hago un "return x" donde "x" es un entero, daría fallo.

El "n = int(c)" convierte a entero el valor ascii del caracter introducido por CIN. Eso es C++, no se si en C funciona igual lo de la conversión de tipos (en Java es igual)

El retorno de la función, es un valor "true" o "false". Un "If" requiere entre los parentesis una expresión booleana, por ejemplo:

"If (a < b)...."

El contenido de los parentesis debe de ser una expresión de ese tipo, o por ejemplo:

"If (true) "...

En este caso, el if se cumple siempre

por lo tanto

Código
  1. if (vocal (c))

Quiere decir: "Si el retorno de la función "vocal" con el parámetro "c" es true"

Espero que haya quedado claro, si no pregunta


Título: Re: Funciones
Publicado por: FKT en 23 Agosto 2015, 23:09 pm
La explicación de void y ese apartado lo he entendido bastante, lo que no he entendido es bueno, lo primero, porque una funcion que retorna x, x es entero porque no compilara o porque no lo aceptara si 0 es entero y ponemos:
Código
  1. int main(){
  2.  
  3. (Aquí el codigo)
  4.  
  5. return 0;
  6. }
No se si me entiendes, lo que quiero decir es que por el int de main() dice que va ha retornar un entero, y como 0 es entero pues no entiendo tu explicación.

Lo siguiente jeje, sigo sin entender lo de:
Código
  1. if (vocal (c))
No se si es sintaxis propia de C++ o es porque aún no he llegado a estudiarla.
Te explico lo que he entendido.
Si el
Código
  1. return true;
de la funcion vocal es "true;" que en este caso si lo es, y "c" también es true se ejecutara el if y en caso contrario el else.


Título: Re: Funciones
Publicado por: Mientras en 23 Agosto 2015, 23:44 pm
Pongo un ejemplo:

Código
  1. #include<iostream>
  2. using namespace std;
  3.  
  4. int funcionPromedio(int nota1,int nota2,int nota3){
  5.    int promedio = (nota1 + nota2 + nota3)/3;
  6.    return promedio;
  7. }
  8.  
  9. int main(){
  10.  
  11.    int resultado;
  12.  
  13.    resultado = funcionPromedio(5,9,4);
  14.    cout << resultado;
  15.  
  16.    return 0;
  17. }


En la linea 4 hay una función "funcionPromedio", antes del nombre dice "int" quiere decir que lo que va a devolver es de tipo "int" (que es la variable "promedio").

En la linea 13 lo que haces es "ASIGNAR a la variable resultado, lo que nos retorna la funcionPromedio". La parte que dice (5,9,4) es lo que le vas a "mandar" a la funcion, son 3 valores por que son 3 parametros nota1 nota2 nota3. Con esto lo que haces es prácticamente nota1=5, nota2=9, nota3=4, promedio=(5+9+4)/3, promedio=6, return 6. Con este return es como si la función te dijera "toma esta es la respuesta". Luego queda resultado = 6.

En esta función si le pasas 3,5,6 la suma es 4,666 pero como están como enteros(int) te devolverá solo la parte entera: 4 (Ojo: no redondea a máximo o a mínimo). Si quieres con decimales tendrías que cambiar los tipos de datos a float o double.
--
*No es necesario que los parametros tengan el mismo tipo q el valor de retorno. Puede existir una función algo así "int funcionX(float a, String texto, bool bandera)" , incluso podría no tener parámetros.


Título: Re: Funciones
Publicado por: FKT en 24 Agosto 2015, 09:20 am
A vale, ahora si que lo entiendo ;-)

Gracias por vuestro tiempo que este tema se ha echo bastante largo ;D


Título: Re: Funciones
Publicado por: Orubatosu en 24 Agosto 2015, 09:50 am
La explicación de void y ese apartado lo he entendido bastante, lo que no he entendido es bueno, lo primero, porque una funcion que retorna x, x es entero porque no compilara o porque no lo aceptara si 0 es entero y ponemos:
Código
  1. int main(){
  2.  
  3. (Aquí el codigo)
  4.  
  5. return 0;
  6. }
No se si me entiendes, lo que quiero decir es que por el int de main() dice que va ha retornar un entero, y como 0 es entero pues no entiendo tu explicación.

Lo siguiente jeje, sigo sin entender lo de:
Código
  1. if (vocal (c))
No se si es sintaxis propia de C++ o es porque aún no he llegado a estudiarla.
Te explico lo que he entendido.
Si el
Código
  1. return true;
de la funcion vocal es "true;" que en este caso si lo es, y "c" también es true se ejecutara el if y en caso contrario el else.

A ver.

En C (o C++) todo programa es una función. Las funciones son programas, separados entre si a los que pasas datos, o que usan datos globalmente, etc. El acceso a variables es un tema aparte, ya verás que hay locales y de otro tipo, eso ya saldrá.

¿Porque la función main tiene que devolver un entero?

En otros lenguajes con sintaxis similar (por ejemplo Java) la función principal puede ser (y de hecho es) void

Por ejemplo, un inicio típico de código en Java seria:

Código
  1. public static void main(String args[]){ ... }

En C (al menos en C++) puedes obviar el "return 0" al finalizar el programa, en principio ese es el valor por defecto que se devuelve.

Pero, Tu programa puede que sea llamado desde el sistema operativo, o desde otro programa para que haga un trabajo (el que sea). Al finalizar el mismo, puede ser interesante para el programa que le ha llamado, o para el própio sistema operativo saber que ese trabajo se ha realizado correctamente.

Por eso el programa devuelve un entero, que en el caso de ser "0" indica "ejecutado con  éxito sin problemas".

Imagina que tienes un pequeño programa que realiza un trabajo (el que sea), y que es posible que en función de los datos que le das, pueda producirse un error de división por cero, o un error de exceso de datos, o de argumentos insuficientes. Lo que se te ocurra.

Pues puedes hacer que tu programa devuelva en caso de que ocurra uno de esos casos (lo cual compruebas dentro del programa) un código de error.
Los códigos son arbitrarios, puedes usar los que se te antojen

Imagina que uno de tus programa borra ficheros, y que forma parte de un sistema operativo. Tu programa se llama "delete" y puede admitir una serie de argumentos tras su nombre. Antes de borrar un fichero, harás una serie de comprobaciones, como saber si el fichero existe, si está protegido contra escritura, si dispones de los permisos necesarios, o cualquier otra cosa. En esos casos, tu programa devuelve al sistema un código de error, y este lo interpreta y muestra al usuario el error.

Supongo que esto lo tienes claro

Lo de
Código
  1. if (vocal (c))

Es simple. El problema es que la gente se acostumbra mal, a ver entre parentesis en el "if" una operación de comparación, y eso es un error.

Lo que hay entre paréntesis en un "if" no es una operación de comparación, es una operación booleana. Eso vale para los if, los while, y lo que sea.

Entre paréntesis puede haber cualquier cosa que al "calcularla" te de true o false, no necesariamente una operación de "mayor que", "menor que", etc.

En este caso, entre paréntesis hay una llamada a una función ,que nos va a dar un booleano. No tiene mas misterio. Por otro lado recuerda que tras el if se ejecuta un código, si el if no se cumple, ese bloque no se ejecuta, y se ejecutará lo que hay a continuación "si o si" haya o no un "else"

Lo cierto es que a veces hay pequeños conceptos que creo se explican mal en algunos cursos, y hacen que la gente se encasquille en conceptos que no son completos, espero que esto te ayude aunque sea un poco


Título: Re: Funciones
Publicado por: FKT en 24 Agosto 2015, 10:31 am
Vale... entonces es más fácil de lo que creía, esque me comía la cabeza...


Lo cierto es que a veces hay pequeños conceptos que creo se explican mal en algunos cursos, y hacen que la gente se encasquille en conceptos que no son completos, espero que esto te ayude aunque sea un poco



Si te digo la verdad en el tiempo que llevo estudiando programación no he leído ni un curso :xD

Gracias por ayudarme Orubatosu