Está en la página 1de 30
Funciones en C ) CRESS En esta unidad aprenderds a: @ Comprender el desarrollo deun programa utilizando funciones Establecer la diferencia entre la definicién y declaracién de una funcién @ Conocer y utilizar el paso de valores entre funciones yladevolucién de valores deuna funcién @ Establecer la diferencia entre el paso de argumentos por valory porreferencia @ Conocer la clasificacion de las variables de acuerdo asu ambito y clase dealmacenamiento WO 3.1 Introduccién En la unidad 2 hemos visto que una funcién es un fragmento de cédigo que realiza una ‘area bien definida. Por ejemplo, la funcién pringfimprime por la salida estandar los argumentos que le pasamos. Al igual que esta funcién, existen otras funciones que rea- lizan diversas tareas ya definidas en el estandar ANSI Cy que pueden ser utilizadas por el programadar. Este tipo de funciones predefinidas son denominadas funciones de biblioteca. Sin embargo, cada programador puede definir sus propias funciones de acuerdo a sus necesidades. Las funciones que define el programador son conocidas como funciones de usuario. La utilizacion de funciones nos permite dividir un programa extenso en pequetios seg- rmentos que realizan tareas concretas. Prabablemente, dentro de un mismo programa se realicen las mismas tareas varias veces, lo que se faclita mediante la utilzacion de fun- ciones. Sin embargo, es probable que ciertas funciones no sean reutilizables, pero al usarlas se mejora la legibilidad del programa, La filosofiaen la que se base el disefia de Ces el empleo de funciones. Par esta razén, tun programa en C contiene al menos una funcién, la funcién main. Esta funcin es pat- ticular dado que la ejecucin del programa se inicia con las instrucciones contenidas en su interior. Una vez iniciada la ejecucién del programa, desde la funcién main se puede llamar a otras funciones y, posiblemente, desde estas funciones a otras. Ota particula- ridad de la funcin main es que se llama directamente desde el sistema operativo y no desde ninguna otra funcién. De esta manera, un programa en C s6lo puede contener una funcion main, Con el propésito de permitir un manejo eficiente de los datos, las funciones en C no se pueden anidar, En otras palabras, una funcién no se puede declarar dentro de otra fun- cién, por lo que todas las funciones son globales o externas, lo que hace que puedan llamarse desde cualquier parte de un programa, Se puede acceder (llamar) a una determinada funcién desde cualquier parte de un pro- rama. Cuando se lama a una funcin, se ejecutan las instrucciones que constituyen dicha funcién. Una vez que se ejecutan las instrucciones de la funcién, se devuelve el contral del programa ala siguiente instruccién (si existe) inmediatamente después de la que provocs la llamada ala funcién, Cuando se accede a una funcin desde un determinado punto del programa, se le puede pasar informacién mediante unos identficadores especiales conacidos como argumen- ‘tos (también denominados parémetros), Una vez que la funcién procesa esta informa- ci6n, devuelve un valor mediante la instrucci6n retum. La estructura general de una funcin en C es la siguiente: tipe_de_retorne nonbre dela funcién (Lista de_parénetros) ( cuerpe_de_la_funcién return expresién 3. Funciones en C 3.1 Introduecién Donée: ‘© tipo_de_retorno: es el tipo del valor devuelto por la funcién, o, en caso de que la funcién no devuelva valor alguno, la palabra reservada vod. rnombre_de_la_funcién: es el nombre o identificador asignado a la funcién. lista_de_pardmetros: es la lista de declaracin de los parametros que son pasados a la funcién, Estos se separan por comas. Debemos tener en cuenta que pueden existr funciones que no utilcen parimetros. ‘© cuerpo_de_la_funcién: ests compuesto por un conjunto de sentencias que llevan a cabo [a tarea especifica para la cual ha sido creada la Funcién, ‘© return expresién: mediante la palabra reservada return, se cevuelve el valor dela funcién, en este caso representado por expres YYamos a suponer que queremos crear un programa para calcular el precio de un producto basindose en el precio base del mismo y el impuesto aplicable. A continuacin mostra mos el cédigo fuente de dicho programa: Finctude Float precio(float base Empuesto); /* declazactén + precio a pagar ee: #21 (mporte, tasa)); Float precio(float base Ampuesto) /* definicién +/ Aoa: caleulo; calculo = base + (base * inpuesto) return caleulo; ELejemplo anterior se compone de dos funciones, la funcién requeriéa main y a fun- ci6n creada por el usuario precio, que calcula el precio de un producto tomando como pardmetros su precio base y el impuesto aplicable. La funcién precio calcula el precio de un producto suméndole el impuesto correspondiente al precio base y devuelve el valor calculado mediante la sentencia return Por otra parte, en la funcién main declaramas dos variables de tipo float que contie- nen el precio base del producto y el impuesto aplicable. La siguiente sentencia dent de la funcign man es la lamada ala funcion de biblioteca pringf que recibe como pars- metro una llamada a la funcién precio, que devuelve un valor ce tipo float. De esta manera, la funcién prin¢fimprime por la salida estandar el valor devuelto por la fun- cin precio. Es importante tener en cuenta que las variables mporte y Casa (argumen- tos) dentro de la funcién maa tienen una correspondencia con las variables dase © ‘mpuesto (parametros) dentro dela funcién precio respectivament Enel ejemplo anterior, justo antes de la funcién marin, hemos declarado la funcin pre- ci. La intencin es que la funcién main sea capaz de reconocerta. Sin embargo, la defi- nicign de dicha funcion aparece después de la funcién main. Las definiciones de fun cién pueden aparecer en cualquier orden dentro de uno o mas ficheros fuentes. Mas adelante, en esta unidad, veremos en detalle a declaracién y definicién de funciones. Por otra parte, hemos afiadido la sentencia returm Oa final de la funci6n main, puesto que se trata de una funcin como otra cualquiera y puede devalver un valor a quien le ha llamado, en este caso el entorno en el que se ejecuta el programa. Generalmente, el valor implica un fin de ejecucién normal, mientras que otro valor diferente implica un final de ejecucion inusual o errSneo. MON 3.2 Declaracion de funciones ‘Antes de empezar a utilizar una funcién debemas declararla. La declaracin de una fun- cién se conoce también como prototipo ce la funcién. En el prototipo de una funcion se tienen que especificar los pardmetros de la funcidn, asi como el tipo de dato que devuelve. Los prototipos de las funciones que se utilizan en un programa se incluyen generalmente en la cabecera del programa y presentan la siguiente sintaxis: tipe_de_retorne nonbre dela funcién(Lists_de_pardnetros) ; En el prototipo de una funcidn no se especifican las sentencias que forman parte de la misma, sino sus caractersticas. Por ejemplo: int cubo int munezo} En este caso se declara la funcién cubo que recibe como pardmetro una variable de tipo entero (numero) y devuelve un valor del mismo tipo. En ningin momento estamos espe- Cificando que se va a hacer con la variable numero, s6lo declaramos las caracteristicas de la funcin cubo. Cabe sefalar que el nombre de los pardmetros es opcional y se utiliza para mejorar la comprensiGn del cédigo fuente. De esta manera, el prototipo de la funcién cubo podria expresarse dela siguiente manera nt cubo (int) Los prototipos de las funciones son utilizados por el compilador para verificar que se accede ala funcidn de la manera adecuada con respecto al nimero y tipo de parémetros, y al tipo de valor de retorno de la misma. Vearnos algunos ejemplos de prototipos de funciones: int potercia(int base, int exponente! double arez_rectangulo (float base, float altura); Ant mayor (int, int) ; steuct aireceion ent avoid + Las funciones de biblioteca se declaran en lo que se conocen como ficheros de cabe- ‘cera o Ficheros .h (del inglés headers, cabeceras). Cuando deseamos utilizar alguna de las funciones de biblioteca, debemos especificar el fichero.h en que se encuentra decla- rada la funcién, al inicio de nuestro programa. Por ejemplo, si deseamos utilizar La fun- cin pringfen nuestro programa, debemos inclur el fichero stdio.h que contiene el pro- totipo de esta funcign. 3.3 Definiciéndefunciones Tras declarar una funcién, el siguiente paso es implementarla, Generalmente, este paso se conoce como definicién. Es precisamente en la definician de una funcion donde se ‘especifican las instrucciones que forman parte de la misma y que se utlizan para llevar ‘a cabo la tarea especifica dela funcion. La definicin de una funcion consta de dos par- tes, el encabezado y el cuerpo de la funcién. En el encabezado de Ia funcién, al igual ‘que en el protatipo de la misma, se tienen que especificar los pardmetras de la funcign, si ls utiliza y el tipo de datas que devuelve, mientras que el cuerpo se compone de las ‘nstrucciones necesarias para realizar la tarea para la cual se crea la funcién. La sinta- xis de la definicign de una funcion es la siguiente: tipo de_retorne nonbre_de_la_funcién{1ista_de_parénetros) { ) El tjpo_de_retomo representa el tipo de dato del valor que devuelve La funcin. Este tipo debe ser uno de los tipos simples de C, un puntero a un tipo de C o bien un tipo struct De forma predeterminada, se considera que toda funcién devuelve un tipo entero (int). En otras palabras, sien la declaracién o en la definicién de una funcién no se ‘especifica el to_de_retorno, el compilador asume que devuelve un valor de tipo int EL nombre_de_ta_funcién representa el nombre que se le asigna ala funcién. Se recomienda que el nombre de la funcién estérelacionado con la tarea que lleva 2 cabo, En caso de que la funci6nutilice pardmetios éstos deben estar lstados entre paréntesis a continuacign del nombre de la func, especificando el tipo de dato y el nombre de cada pardmetro. En caso de que una funcién no utili pardmetros, se pue- den dejar los paéntesis vacfos o incur Ia palabra vid, que indica que la funcién no utiliza pardmetios, Después del encabezado de la funcin, debe aparece, delimitado por laves (fy J), el cuerpo de la funcién compuesto por las sentencias que llevan a cabo la tareaespecifca de la funcién, Veamos la definicin de la funcin cube decla- rada en el apartado anterior: int cubo(int base! ( int potencia: potencia = base + base * basa; return potenciay 3. Funciones en C 3.3 Definicign de funciones Came ya hemos visto, a los argumentos que rece la funcién también se les suele lla mar pardmetros. Sin embargo, algunos autores consideran como pardmetros ala lista de variables entre paréntesis utilizada en la declaracino en la definicion de la funcién, ¥y coma argumentas los valores utilizadas cuando se llama ala funcién. También se uti- lizan los terminos argumentos formales y argumentos reales, respectivamente, para hacer esta distincin, Cuando un programa utiliza un nimero elevado de funciones, se suelen separar las decla- raciones de funcin de las definiciones de las mismas, AL gual que con las funciones de biblioteca, las declaraciones pasan a formar parte de un fichero cabecera (extensién f), mientras que las definiciones se almacenan en un fichero con el misma nombre que el fichero .h, pero con la extension .c. En algunas ocasiones, un programador no desea divulgar el cSdigo fuente de sus funciones, En estas casos, se suele proporcionar al usua- Fio el fichero de cabecera, el fichero compilada de las definiciones (con extension .o, de objeto) y una decumentacion de las mismas. De esta manera, cuando el usuario desea hacer uso de cualquiera de las funciones, sabe qué argumentos pasarle y qué tipo de datos devuelve, pero no tiene acceso a la definicion de las funciones. preeeted @ Fert programa cael el cub de os nimers del 1a 5 utlizando una funcin defnida pore sua. include nt cubotint base) 7 mumerste) ( bo del ninero #4 es d\n", numero, cubo numero) } int base) potencia, La salida es: ccubo del nimezo 1 ee ccubo del ninezo 2 2 ccubo del ee ccubo del ee ccubo del ninezo § e@ 3.4 Devoluciénde valores SN Una funcion en C slo puede devolver un valor. Para devolver dicho valor, se utiliza la palabra reservada seturn cuya sintaxis es la siguiente: veturn cexpresine; Donde puede ser cualquier tipo de dato salvo un array o una funcién. Ade- mas, el valor de la expresién debe coincidir con el tipo de dato declarado en el proto- tipo de la funcién. Por otro lado, existe la posibilidad de devolver maltiples valores mediante la utilizacién de punteros o estructuras, Dentro de una funcién pueden exis- tir varios retum dado que el programa devolveré el contal a la sentencia que ha llamado ala funcién en cuanto encuentre la primera sentencia return, Sina existen return, la ‘ejecucién de la funcion continia hasta la llave del final del cuerpo de la funcién (2). Hay que tener en cuenta que existen funciones que no devuelven ningin valor. El tipo de dato devuelto por estas funciones puede ser vod, considerada como un tipo especial de dato. En estos casos, la sentencia return se puede escribir como return o se puede omitir directamente. Por ejemplo: void inprine_cabecera{}; ( printf (*esta funcién s6lo inprine esta Linea") } equivale a: void imprine_cabecera|) ( printf (*esta funcién s6lo inprine esta Linea") y 3.5 Accesoaunafuncion Para que una funcin realice la tarea para la cual fue creada, debemos acceder o llamar a la misma, Cuando se llama a una funci6n dentro de una expresién, el contol del pro- rama se pasa 2 éstay s6lo regresa 2 la siguiente expresin de la que ha realizado lala mada cuando encuentra una instruccién return, en su defecto, la llave de ciere al final de la funcién, ‘Generalmente, se suele llamar a las funciones desde la unci6n mat, lo que no implica {que dentro de una funcién se pueda acceder a otra funci ‘Cuando queremos acceder @ una funcién, debemos hacerlo mediante su nombre seguido de la lista de argumentos que utiliza dicha funcién encerrados entre paréntesis. En caso 3. Funciones en C 3.5 Acceso a una funci6n de que la funcion ala que se quiere acceder no utilice argumentos, se deben colacar los paréntesisvactos. Cualquier expresin puede contener una llamada a una funci6n. Esta llamada puede ser parte de una expresién simple, como una asignacién, o puede ser uno de los operandos de una expresion mas compleja. Por ejemplo: a = cabo! cule exbot3) Debemos recordar que los argumentos que utilizamos en la llamada a una funcin se denominan argumentos reales. Estos argumentos deben coincidir en el nimero y tipo con los argumentos formales o pardmetros de la funcién. No alvidemos que los argu- ‘mentos formales son los que se utilizan en la definicion y/o declaracién de una funcién, Los argumentos reales pueden ser variables, constantes o incluso expresiones mas com- plejas. El valor de cada argumento real en la llamada a una funcion se transfiere a dicha funcion y se le asigna al argumento formal correspondiente. Generalmente, cuando una funcién devuelve un valor, la llamada ala funcién suele estar dentro de una expresign de asignacién, como operanda de una expresin compleja 0 como argumento real de otra funcién. Sin embargo, cuando la funcin no devuelve nin- gin valor, (a lamada a la funcién suele aparecer sola. Veamas un ejemplo: Ejemplo practic vance ccna as uncon rie sepinde dese afc main include vold inprinevalor() vain) inpeinevaior inpeinevalor inpeinevalor inpeinevaior return 0; void inprivevalor() ie int conta nt ("B1 valor de contador es: $d\n", contador) La primera vez que se llama a la funcién snprimeValor se incialza su valor a cero, y tras ‘imprimir su valor se incrementa éste. En las sucesivas llamadas, el valor de la variable contador se mantiene y el resultado es el siguiente: Coma hemos visto, el valor de la variable contador se mantiene de una lamada a otra de la funcin mprimeValor. Esto quiere decir que las variables locales estaticas proporcio- nan un medio privado de almacenamiento permanente en una funcién. Por aro lado, la aplicacion del calficador stata variables glabales hace que a éstas slo se pueda acceder desde el fichero fuente en el que se definieron y no desde ningin otro fichero fuente. Por ejemplo, si definimas las variables globales tiempo y relaj en el siguiente fichero fuente: void funciont () cualquier otra funcién que forme parte de la aplicacién y que no forme parte de este fichero fuente no podrs disponer de acceso a tiemporni a rej. Es mas, se pueden uti zat los mismos nombres para defini variables en funciones en otros Ficheros sin ningGn ‘ipo de problema, ‘AL igual que las variables globales, las funciones son abjetos externos cuyos nombres, generalmente, se desea que se conozcan de manera global. Sin embargo, en algunas situaciones resulta deseable limita dicho acceso al fichero en el que se declara la fun- cin. En estos casos, se utiliza la palabra reservada staticy su mecanismo de aplicacién €s similar al caso de las variables, como podemos apreciar en el siguiente ejemplo: static int cuadvade (int numero! { int ealeulo-9; cealoulo = nunave * mumezo; return caleule; ) Limitar el acceso tanto a variables globales coma 2 funciones, mediante su declaracion como estiticas, resulta itil en algunas situaciones en las que se quiere evitar que entren ‘en conflicto con otras variables 0 funciones, incluso inadvertidamente. 3.10 Variablesde registro (I ‘Cuando declaramos una variable como variable de registra, le estamos diciendo al com- pilador que queremos que la variable se almacene en un lugar de répido acceso, gene- ralmente en los registros de la unidad central de procesamiento del ordenador. Para declarar una variable como variable de registro, debemos colocar la palabra reservada register antes de la declaracin de la variable. Veamos algunas ejemplos: register int contador: register char a; Solo se pueden declarar variables como regitersi son variables automaticas (locales) 0 argumentos formales de una funcién. Veamos un ejemplo de la utilizacion de registeren los argumentos farmales de una funcién: Euncion_A (register int entrada, register int aunero) ( ) ‘Cuando se utiliza una variable de tipo register, no esté garantizado que su valor se alma- cene en un registro, Para que el valor de dicha variable se almacene en un registro, debe haber alguno disponible, de lo contrario C ignora el caificacor registry crea la varia~ ble localmente como ya hemos visto. Debido a restrcciones de hardware, existen certaslimitaciones al utilizar variables reai- {er Por esta razén, slo un nimera determinado de variables pueden declararse como register dentco de una funci6n. También existen limitaciones en cuanto al tipo de las variables. Es el compilador el que se encarga de ignorar el calificador registers existe tn ndimero excesive de declaraciones o los tipos utilizados no estan permiticos. MEN 3.11 Paso de argumentos y punteros En C todos los argumentos que se pasan a una funcién se pasan por valor, En otras palabras, se pasa una copia del valor del argumento y no el argumento en si (por ello, este pracedimiento se conace en algunas ocasiones como paso por copia). Al pasar tuna copia del argumento original a la funcién, cualquier modificacin que se realice sobre esta copia no tendré efecto sobre el argumento original utilizado en la llamada de la funcién. Se puede considerar un argumento pasado por valor como una variable local de la funcion a la que se ha pasado, de tal modo que los cambios que se realicen sobre ésta tendrin efecto sélo dentro dela funci6n. \Veamos un ejemplo del paso por valor de argumentos a una funcién: #inctude void modificartine variable); sain() ( int i= 1) printé("\nictd antes de Llanar a la funeién modifica", 3); nod ficar(i) 2 print£("\nistd después de Lazar 2 1a funcién modificar", i}; ) void nodificar{int variable) ( print#("\nvariable = td dentro de moditicar", variable) ; variable = §; print£("\nvariable = td dentro de modificar", variable); ) Dado que lo que se pasa a la funci6n modifiares una copia dela variable i el valor de ésta en la funcién mai no se ve alterado cuando dentro de la funcién modiffcar se cam- bia el valor de variable. De ahi, la salida del ejemplo anteriores la siguiente: isl antes de Llamas a 1a funeiéa modificar variable = 1 dentro de nodificar 9 dentro de nodificar fe de Llsmar a la funcién nodisicar Como ya hemos visto, cuando se pasa un argumento por valor, realmente se pase una copia de éste y siesta copia se mocifica el argumento original no se ve alterado. Sin embargo, en muchas ocasiones lo que queremos es que una funcién cambie los valores de los argumentos que le pasamos. Para lograrto se utiliza lo que se conoce como paso de argumentos por referencia. En estos casos, no se pasa una copia del argumento, sino el argumento mismo, Cuando realizamos un paso de argumentos por referencia en C, realmente lo que esta- mos pasando son direcciones de memoria, En otras palabras, lo que le pasamos a la fun-

También podría gustarte