Home
Username:
Password:
C Programming (Español) Tutorials

Funciones / Soluciones del Capítulo 10




Visitors to VTC.com will be able to view all introductory videos for each training course.
Free Trial Members will gain access to first three chapters for each training course.
Full Access Members have full access to VTC.com’s entire library of video tutorials.


Learn More

Subtitles of the Movie

ÀComo le fue? Seguramente fue dificil. Estoy seguro de que tuvo problemas con algunas funciones, pero no importa, pues es la primera vez que escribimos funciones propiasÉ y todos cometemos errores la primera vez. Ahora tiene la idea general. y comienza a comprender la creacion y el funcionamiento de las funciones. Seguramente tuvo algunos problemas, asi que aqui tenemos las soluciones a los ejercicios, las cuales pueden diferir completamente de las suyas. Sin embargo, estas le daran una idea si tiene problemas. Aqui tenemos de nuevo el archivo "database.c". Vamos a recorrerlo desde el principio para revisar las nuevas funciones que he creadoÉ y si estas realizan las acciones esperadas. Luego veremos la funcion "main" para ver como utilizarlas. Comenzamos con la funcion mas sencilla llamada "trim_newline", a la cual le pasamos una cadena llamada "string". Esta funcion va a modificar este parametro; los elementos de este arreglo seran modificados, es decir, los caracteres individuales seran cambiados. En particular, vamos a cambiar el caracter de nueva linea si este existe, asi que debemos verificar este aspecto. Si existe dicho caracter, este estara en la ultima posicion de la cadena, es decir, sera 1 menos que la longitud de la cadena. Al hallar la longitud de la cadena, debemos restarle 1. Si este es un caracter de nueva linea, debemos reemplazarlo por un caracter "null"É para realmente reducir la cadena. Tendremos una cadena terminada con dos caracteres "null", pero esto esta bien, aunque uno es suficiente. Nos desplazamos hacia abajo y observe que la funcion "trim_newline" no tiene ninguna sentencia de restitucion. Esta no restituye ningun valor una vez la cadena es completada y procesada, por lo tanto esta sencilla funcion no contiene ninguna sentencia de sustitucion. Simplemente desplegamos una cadena ante el usuario y leemos un caracter desde el teclado. Esta es la cadena visualizada por el usuario, pero esta no es modificada mediante la funcion "enter". Aunque dicha funcion podria modificar la cadena, no lo haceÉ sino que simplemente ejecuta las funciones "puts", "fflush" para liberar la entrada del teclado y por ultimo "getchar". Es muy sencilla. y la utilizaremos varias veces dentro del programa. Luego tenemos una funcion un poco mas compleja, pero con la misma idea: esta vez vamos a restituir un entero, asi que especificamos que el tipo de restitucion sera "int", aunque este es implicito y sera de tipo "int" aunque no lo especifiquemos. Es conveniente incluir la palabra "int" para que todos reconozcan que esta funcion restituira un valor entero. Podemos modificar el comentario para aclarar que si se ingresa la letra "y" mayuscula o minusculaÉ la funcion restituira el valor 1, y que si se ingresa la letra "n" mayuscula o minuscula, se restituira el valor 0. Tambien es conveniente incluir comentarios en las funcionesÉ para que las personas que quieran utilizarlas en el futuro conozcan exactamente su funcionamiento. Al igual que en la funcion "enter", aqui solicitamos el ingreso de un caracterÉ y esta es la primera accion que realizamos. Necesitaremos una respuesta, asi que aqui tenemos un cicloÉ porque el usuario podria ingresar una respuesta incorrecta, como la letra "p", el numero 3, etc. Desplegamos la preguntaÉ y el usuario no tendra que ingresar un signo de interrogacion al finalÉ sino que lo haremos nosotros. Tomamos la pregunta, agregamos un espacio, "Y/N" entre parentesis, un signo de pregunta y otro espacio. Lo incluimos al final de la pregunta para que el usuario no tenga que hacerlo. Esta es una especie de ayuda especial. Luego leemos un caracter desde el teclado y lo procesamos. Primero lo convertimos a mayusculas, y si es la letra "y", restituimos el valor 1. Si es la letra "n" restituimos el valor 0. Aqui tenemos algunos aspectos que no hemos visto. Llamamos a la sentencia "return" en medio de la funcionÉ en vez de hacerlo al final. No tenemos que ubicarla al final, pues podriamos incluir una sentencia "break" en tales puntosÉ aqui, aqui y aqui abajo tambien. Podriamos incluir una sentencia "return" y luego un valor con base en la respuesta "y" o "n", pero no es necesario porque podemos restituirlo desde aqui. Aunque no habiamos visto este aspecto, podemos hacerlo. Observe que tampoco tenemosÉ ninguna clausula "else". Podriamos incluirla, pero esta no es necesaria. Intente averiguar por que no necesitamos una clausula "else" en este caso. Si no restituimos ninguno de estos valores, aqui tambien podriamos incluir una clausula "else", pero esta tampoco es necesaria. No es necesaria en absolutoÉ y podemos omitirla. El programa funcionara exactamente igual. Una vez mas, compruebe este aspecto por su cuenta. Puede suponer que alli tenemos una clausula "else" si desea. Si no se ha ingresado la letra "y" o "n", desplegamos este mensaje. Voy a eliminar esta clausula "else, pues no me agrada tenerla alli. Luego simplemente ejecutamos de nuevo el ciclo. Despegamos la pregunta, leemos otra respuesta, la procesamos y asi sucesivamente. Observe que si el usuario ingresa la letra "y" o "n", la funcion restituira el valor respectivo y el ciclo se detendra, asi que este no es un ciclo infinito sino un ciclo "forever", pues existe una manera de salir de el. De hecho, existen dos maneras de hacerlo. La prueba final consiste en comprobar si esta funcion es correcta al ejecutar el programa. Esta es una funcion mucho mas sencilla: leemos un enteroÉ y de nuevo solicitamos un caracter. Desplegaremos la frase "Please enter the number of tracks" o una similar, ejecutamos una sentencia "fflush" estandar para despejar la entrada del teclado y leemos la respuesta. Luego, por supuesto, restituimos esa respuesta. Esta es una clasica y sencilla funcion. La funcion "read_float" es igual, excepto que restituye un valor de tipo "float" y la respuesta ingresada es de tipo "float", asi que tenemos "%f" en vez de "%d". Por lo demas, es exactamente igual. La funcion "read_string" es ligeramente diferente, pues recuerde que las funciones no pueden restituir cadenas. Sin embargo, estas pueden modificar sus parametros si estos son arreglos o cadenas, asi que de nuevo solicitamos un caracter, pero en vez de por ejemplo restituir un valor "char", lo cual no podemos hacer, simplemente creamos otro parametro llamado "answer" para la respuesta. Explicare ese tercer parametro en un momento. De nuevo solicitamos un caracter, tenemos las funcion "fflush"É y ejecutamos una funcion "fgets" sobre la variable "answer". Es alli donde "fgets" lee los datos de la respuesta. Recuerde que con la funcion "fgets" debemos especificar el tamano de la cadena leidaÉ para que esta sepa donde detenerse sin bloquear el programa. Esto es importante. Si vamos a especificar esos datos, debemos obtenerlo de algun lugar. La funcion "read_string" no conoce el tamano de la cadenaÉ porque no puede utilizar un operador "sizeof" en la variable "answer". Podriamos hacerlo, compilar y ejecutar el programa, pero no funcionariaÉ porque la variable "answer" no tiene un tamano o un numero entre estos corchetes. No podemos hacerlo porque la funcion "read_string" no conoce el tamano del arreglo, asi que debemos especificarlo. La unica manera de hacerlo es pasarle otro parametro de esta manera. Tal vez usted realizo este proceso con una funcion "scanf"É en vez de una funcion "fgets", lo cual tambien es correcto. Ademas del hecho de que la cadena tendra un tamano maximo, la respuesta sera pasada desde la cadena declarada. Si por ejemplo esta tiene 30 caracteres, estaremos pasando un arreglo de 30 caracteresÉ dentro del cual ingresaremos la respuesta. Al utilizar las funciones "scanf" o "gets" estaremos leyendo un arreglo de 30 caracteres, pero si el usuario ingresa 50 caracteresÉ probablemente bloqueara el programa. Si no me cree, intentelo. Creo que esta es la manera mas apropiada de hacerlo porque el programa no se bloqueara, pero es una cuestion de preferencias. Finalmente, eliminamos la nueva linea de la respuestaÉ mediante la funcion que vimos anteriormente. Por ultimo tenemos la funcion "output" a la cual le pasamos las cadenas "title", "artist", "tracks", el entero booleano "album"É para indicar si es un album o un sencillo y finalmente "price". Esto es muy sencillo, pues simplemente desplegamos los detalles. Este es el mismo codigo anterior que he copiado y pegado aqui. Ahora veamos la funcion "main", la cual es mas pequena de lo normal. Declaramos todas las variables a excepcion de "type" que ya no es necesaria, pues el unico lugar en el cual la utilizamos es la funcion "yesno", y esta vez le asignamos el nombre "answer". Regresamos a la funcion "main" y tenemos una sentencia "printf" y un cicloÉ en el cual formulamos una pregunta con respuesta de si o no. Podemos verificarÉ si esta es igual a 0 porque la funcion "yesno" siempre restituira un valor 1 o 0. Obviamente, si el usuario no va a ingresar mas detalles de otro CD, la respuesta sera no, asi que la funcion restituira el valor 0. Recuerde que esto es igual a tener aqui un operador "NOT". Si pensamos en la funcion "yesno" como una funcion booleana, podemos incluir un signo de exclamacion al inicio para invertir el resultado, es decir, si la funcion "yesno" restituye un 1, este se convertira en 0 y viceversa; si "yesno" restituye un 0, este se convertira en 1. Aunque comprenda o no este aspecto, estara de acuerdo con que al incluir. un signo de exclamacion aqui obtendremos el mismo resultado que al igualar la funcion al valor 0. Tambien es mas facil leerlo asi, pero cuando usted se convierta en un programador experimentado del C vera que esta opcion tambien es facil de leer. Simplemente verificamos si este no es el valor. Si el usuario responde "n", en ese punto salimos de ciclo. Luego desplegamos "Please enter the details of the CD" y leemos los detalles ingresados. Observe que basicamente tenemos 5 lineas de codigoÉ y ya no tenemos las funciones "printf", "scanf" y "fflush", asi que ahora es mas sencillo. Ejecutamos dos veces la funcion "read_string" y le pasamos estos argumentos. Recuerde que estamos trabajando con arreglos bidimensionalesÉ como el arreglo "title" de la parte superior. Este es un arreglo de cadenas, y por supuesto, cada cadena es un arreglo en si. Aqui tenemos una cadena. Este es un arreglo bidimensional y esta es por supuesto una cadena con este tamano. Recuerde que tambien debemos pasar el tamano a la funcion "read_string"É y hacemos lo mismo para el artista. Esto es mas sencillo: ejecutamos la funcion "read_int" seguida por la pregunta en cuestion. Le pasamos el valor que ubicamos en la variable "tracks" para este numero de pista en particularÉ y hacemos lo mismo para el album y el precio. En la funcion "yesno" no tenemos que incluir un espacio, "Y/N" entre parentesis, un signo de interrogacion y otro espacioÉ porque la funcion lo hara por nosotros, asi que no es necesario hacerlo. Aunque esto es un poco inconsistente, es posible hacerlo asi. Luego verificamos si el arreglo se ha completado y aqui utilizamos la funcion "enter" que escribimos, la cual simplemente despliega esta cadena. Observe que aqui tenemos una cadena y aqui tenemos otra cadenaÉ y ambas son literales. ÀQue tenemos entre ellas? Voy a ubicarlas en la misma linea y observe que tenemos un espacio entre ellas. Recuerde que en el C podemos tener muchos espacios entre los elementos, asi como tabulaciones o nuevas lineas. Esto es lo mismo que tener una nueva linea o un espacio como este. Ya vimos este aspecto, pero en el C, si tenemos dos cadenas literales contiguasÉ como esta cadena y esta cadena, una a continuacion de la otraÉ y sin ninguna separacionÉ a excepcion es este espacio, el C las tratara como una sola cadena literal, es decir, las unira entre si. El C las concatenara automaticamente por nosotros. Me refiero a las cadenas literales y no por ejemploÉ a las cadenas "name" y "address". No podemos ubicarlas de esta maneraÉ y esperar que sean concatenadas como al utilizar la funcion "strcat". Estas no seran concatenadas porque no son cadenas literales. Si hacemos esto podriamos concatenarlas y obtener la cadena "nameaddress"É pero esto seria exactamente igualÉ que asignar el mismo texto a cada una de las dos cadenas. Obtendriamos una sola cadena literal de 11 caracteres. Recuerde que el compilador del CÉ concatenara las cadenas literales contiguas, asi que aunque las ubiquemos en dos lineas y visiblemente separadas, estaremos dividiendo una cadena en dos partes. Como dije, el compilador no las diferencia porque no hemos utilizado una coma o un caracter similar entre ellas. No hemos hecho esto, asi que estas no son dos cadenas literales contiguas sino una una cadena literal seguida por una coma y otra cadena literal. Sin embargo, estas son dos cadenas literales pero el compilador las trata como una sola, asi que tenemos una linea con un caracter de nueva linea en el centro. La funcion "enter" desplegara la cadena completa y esperara que el usuario pulse la tecla "Enter"É para continuar. Finalmente, desplegamos los detalles del CDÉ y llamamos de nuevo a la funcion "enter". Desplegamos "Press enter to see the next set of details" y finalmente indicamos como salir del programa. Hacemos exactamente lo mismo y llamamos de nuevo a la funcion "enter". Hemos realizado varias modificaciones. Ahora vamos a verificar el archivo de encabezado. Aqui lo tenemos con todos los prototipos. Simplemente he copiado y pegado estas lineas desde el otro archivo ".c". Cada una comienza con un tipo de datosÉ porque este es necesario para que el prototipo este completo. Es decir, aunque al hacer esto indicamos implicitamente que la funcion "yesno" es de tipo "int", con los prototipos. debemos ser especificos en cuanto al tipo de la funcion. Este es el archivo de encabezado. Regresamos al archivo ".c", compilamosÉ sin obtener errores y ejecutamos. Aparece la pregunta "Do you have anymore CD's to enter?" generada por la funcion "yesno". Veamos si funcionaÉ al ingresar datos equivocados. Observe que se nos prohibe continuar si ingresamos respuestas incorrectas, asi que escribimos "y" para avanzar. Todo parece funcionar bien. Se nos pregunta el tituloÉ mediante la ejecucion de la funcion "read_string". Ingresamos por ejemplo "Love Over Gold"É y la funcion "read_string" nos pregunta el artista. Ingresamos "Dire Straits"É y la funcion "read_int" nos pregunta el numero de pistas. Ingresamos 5É y debemos ingresar "y" o "n" para definir si el CD es un album en vez de las letras "a" y "s". Ingresamos "y"É y en cuanto al precio ingresamos 9.50. Aparece "Have you any more CD's to enter?", ingresamos "n" y veamos si la funcion "input" es correcta. Observe que esta funciona correctamente. Luego aparece "Press enter to exit the program". Al ejecutarse la funcion "enter", el programa espera que pulsemos la tecla "Enter", asi que funciona correctamente. Realizamos varias modificacionesÉ y convertimos un programa relativamente sencillo en un programa mas complejo. Le hemos agregado complejidad al introducir todas estas nuevas funcionesÉ y usted estara de acuerdo con esto, pero tal vez piense que este es un retroceso. En un sentido lo es, pues si no somos programadores experimentados del CÉ considerariamos que es un retroceso tener tantas funciones que son mas dificiles de entender que una sola funcion. Sin embargo, soy un programador experimentado como sera usted en algun punto, y como a todos los programadores experimentados del C, me agradan las funcionesÉ y siempre deseo trabajar con ellas. Me sorprenderia encontrar una sola y extensa funcion "main". Hemos incrementado la complejidad, pero tambien la legibilidad y la sustentabilidad del programa al dividirlo en partes modulares, pues cada parte realiza una tarea especifica. En la parte inferior tenemos la funcion "main" en la cual hemos organizado dichas acciones. Utilizamos algunas de ellas dos veces, como "yesno", y tres veces como la funcion "enter". Utilizamos la funcion "read_string" dos veces y tenemos un codigo reutilizable que no teniamos antes, asi que este programa ahora es un poco mas pequeno, pues hemos reducido el numero de lineas de codigo. Ciertamente tenemos mas comentarios y aqui se nos indica que tenemos 204 lineas en este archivo, lo cual es mucho mas de lo que teniamos antes, pero el numero de lineas de codigo que realizan acciones reales es menor. Puedo asegurarlo. Esto es todo en cuanto a las funciones. En el siguiente capitulo veremos las estructuras.

Tutorial Information

Course: C Programming (Español)
Author: Mark Virtue
SKU: 33759
ISBN: 1-933736-81-X
Release Date: 2007-04-16
Duration: 21.5 hrs / 139 lessons
Captions: Available on CD and Online University
Compatibility: Vista/XP/2000, OS X, Linux
QuickTime 7, Flash 8

VTC Sign up & Benefits

  • Unlimited Access
  • 98,729 Video Tutorials (23,265 free)
  • Video Available as Flash or QuickTime
  • Over 1026 Courses
  • $30 for One Month Access
  • Multi-User Discounts Available