Académique Documents
Professionnel Documents
Culture Documents
Tabla de contenidos
1. Definición de funciones
2. Paso de parámetros a una función
Tablas como parámetros a una función
3. Prototipos de funciones
4. Funciones estáticas
5. Ejercicios
1. Definición de funciones
Las funciones en C tienen el siguiente formato:
3. Prototipos de funciones
Como el compilador trabaja sólo con la información contenida en un
único fichero, a menudo es preciso “informar” al compilador de que
en otro fichero existe una función. Esto se consigue insertando, en
lugar de la definición de la función (que ya está presente en otro
fichero), su prototipo. El prototipo de una función es una línea similar
a la primera de su declaración: tipo del resultado, seguido del nombre
de la función y de la lista de tipos de datos de los parámetros
separados por comas y rodeados por paréntesis. Toda función que se
invoca debe ir precedida o de su definición o de su prototipo. La
definición y el prototipo de la función pueden estar presentes en el
mismo fichero. El siguiente ejemplo ilustra esta situación:
1 /* Prototipo */
2 int addition(int, int);
3 /* Función principal */
4 int main()
5 {
6 int i, j;
7
8 i = 10;
9 j = 20;
10 /* Invocación de la función */
11 i += addition(i, j);
12 }
13 /* Definición de la función */
14 int addition(int a, int b)
15 {
16 return (a + b);
17 }
Sugerencia
4. Funciones estáticas
La definición de una función puede tener el prefijo “static”. Cuando
una función se declara como estática, tan sólo puede ser invocada
desde el fichero en el que está definida. Este mecanismo, por tanto,
puede interpretarse como una forma primitiva de restringir el acceso
a una función, pero dista mucho del mecanismo de tres niveles
(público, privado y protegido) presente en Java.
1 /* Funciones globales */
2 int function1(int p1, float p2, int table[], int
3 size);
4 void function2();
5 struct data *function3(char *name, char* lastname,
int status);
6
/* Funciones locales */
7
8 static void check(int table[], int size);
9 static struct data *duplicate(struct data *d1);
10
/* Definiciones */
....
5. Ejercicios
1. Un programador con poca experiencia nos manda la siguiente
función que dice que intercambia el valor de sus dos
parámetros. Si se llama como swap(x, y), al terminar la
ejecución, las variables x e y han intercambiado sus valores.
¿Es eso cierto? Comprueba tu respuesta creando un programa
en tu entorno de desarrollo y ejecutándolo. Puedes imprimir la
variable entera x con la líneaprintf("%d\n", x);.
1 struct gps_information
2 {
3 int is_3D;
4 float latitude;
5 float longitude;
6 float height;
7 };
8 typedef struct gps_information gps_info;
Funciones[editar]
Como vimos anteriormente C tiene como bloque básico la función main() , también
hemos visto la sentencia printf() que es otra función, y de igual forma hay muchas más
funciones predefinidas, pero nosotros mismos también podemos definir nuestras propias
funciones. De hecho, es fundamental hacerlo.
Podemos definir una función cualquiera de la misma manera en que definimos la
función main() . Basta con poner su tipo, su nombre, sus argumentos entre paréntesis y
luego, entre llaves, su código:
/* Inclusión de archivos */
#include <stdio.h>
Este código es en todo equivalente al "Hola Mundo" original, sólo que nos muestra cómo
escribir y cómo utilizar una función. Y además nos muestra un principio de buena
programación: meter las sentencias que "hacen el trabajo" en otras funciones específicas
para sacarlas de main() , dejando en ésta tan sólo un guión general de lo que hace el
programa, no las órdenes específicas. De esta manera se facilita la comprensión del
programa, y por tanto el futuro trabajo de modificarlo.
La sentencia return puede utilizarse dentro de una función para terminar su ejecución.
En el ejemplo anterior, la función holamundo fue declarada con valor de retorno de
tipo void (es decir, valor de retorno nulo). En ese caso, la sentencia return no lleva
ningún parámetro adicional, ya que la función no debe devolver ningún valor a la función
que la llama.
En cambio, la función main tiene un valor de retorno de tipo int , por lo
que return debe ir seguido de un valor entero (0 en el ejemplo). El valor 0 se utiliza para
indicar que el programa ha llegado a un punto en el que todo se ha desarrollado
correctamente y se utiliza cualquier otro valor para indicar que ha habido algún tipo de
error.
La instrucción return no es una función, se trata de una sentencia que lo que hace es
retornar como valor de la función el valor que se le proporciona como argumento.
Argumentos[editar]
Las funciones también pueden recibir argumentos o parámetros, para modificar su
comportamiento. Por ejemplo, la definición de una función para sumar dos números sería
de la siguiente manera:
Declaración y definición[editar]
En el ejemplo anterior podemos notar que la función sumar figura en el código antes
que main . ¿Qué pasaría si las escribiéramos en distinto orden?
#include <stdio.h>
int main(void)
{
int suma = sumar(5, 3); /* ERROR, sumar no ha sido declarada
aún */
printf("La suma es: %d ", suma);
return 0;
}
#include <stdio.h>
/* Declaración */
int sumar(int numero1, int numero2);
int main(void)
{
int suma = sumar(5, 3);
printf("La suma es: %d ", suma);
return 0;
}
/* Definición */
int sumar(int numero1, int numero2)
{
return numero1 + numero2;
}
Paso de Parámetros[editar]
Las funciones pueden recibir datos como lo hemos observado, pero existen dos formas de
enviar los datos hacia una función por valor y por referencia, las cuales modifican en
diferente forma el comportamiento del programa.
Por Valor[editar]
El paso por valor envía una copia de los parámetros a la función por lo tanto los cambios
que se hagan en ella no son tomados en cuenta dentro de la función main() . Ejemplo:
/*
* por_valor.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
int main(void)
{
int numero = 57; /* definimos numero con valor de 57*/
return 0;
}
return;
}
Por Referencia[editar]
El paso por referencia se hace utilizando apuntadores. Se envía la dirección de memoria
de la variable, por lo tanto los cambios que haga la función si afectan el valor de la
variable. Ejemplo:
/*
* por_referencia.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
int main(void)
{
int numero = 57; /* definimos numero con valor de 57*/
return 0;
}
return;
}
/*
* locales.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
void funcion1()
{
int dato = 53; /* definimos dato en 53*/
char num1 = 'a'; /* num1 vale a */
/* imprimimos */
printf("Funcion1, dato=%d, num1=%c\n", dato, num1);
return;
}
void funcion2()
{
int dato = 25; /* definimos dato en 25*/
char num2 = 'z'; /* num2 vale z*/
/* imprimimos */
printf("Funcion2, dato=%d, num2=%c\n", dato, num2);
return;
}
int main(void)
{
funcion1(); /* llamamos a funcion1() */
return 0;
}
En este caso la variable dato, esta definida dentro de cada una de las funciones y son
totalmente distinta una de otra y no se puede utilizar fuera de esta, así pues num2 no
puede ser utilizada por la funcion1() y num1 tampoco puede ser utilizada por funcion2().
Existen pues variables que se definen fuera de la función principal main() y fuera de
cualquier otra función creada por nosotros, estas variables se les conoce con el nombre de
Variables Globales ya que se pueden utilizar dentro de main() y dentro de cualquier
función creada por nosotros. Ejemplo:
/*
* global.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
void funcion();
int main(void)
{
/* imprimimos el valor*/
printf("main(), acceso a variable_global %d\n",
variable_global);
/* llamamos a la función */
funcion();
return 0;
}
void funcion()
{
/* imprimimos el valor*/
printf("funcion(), acceso a variable_global %d\n",
variable_global);
return;
}
Funciones Recursivas[editar]
La recursividad (recursión) es la propiedad por la cual una función se llama a sí
misma directa o indirectamente. La recursión indirecta implica utilizar más de una
función.
Se puede considerar la recursividad como una alternativa a la iteración. La recursión
permite especificar soluciones naturales, sencillas, que serían, en caso contrario, difíciles
de resolver. Toda función recursiva debe contemplar un caso base o condición de
salida, para terminar, o la recursividad no podrá terminar nunca.
Una función recursiva podría definirse así:
/*
*factorial.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
long factorial(int n)
{
if (n == 0) /* caso base */
return 1; /* como 0! = 1, se retorna 1*/
else
return n * factorial (n - 1); /* llamada a esta misma
función */
}
int main(void)
{
/* en este caso se llama a la función y se imprime
directamente*/
printf("%ld ", factorial(5));
return 0;
}
Solución recursiva:
/*
* producto.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
int main(void)
{
/* en este caso se llama a la función y se imprime
directamente*/
printf("%i ", producto( 7, 3));
return 0;
}
/*
* elalfabeto.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
int main(void)
{
return 0;
}
void funcionA(char c)
{
if (c > 'a') /* caso base mientras c no sea menor que A
*/
funcionB(c); /* llamado a la funcionB */
void funcionB(char c)
{
funcionA(--c); /* llamado a la funcionA decrementando
el valor de 'z' */
}
/*
* iterativo.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
/* calcula el factorial de 0 a 10 */
for ( contador = 0; contador <= 10; contador++ )
printf("%d! = %ld\n", contador, factorial(
contador ));
return 0;
}
return resultado;
}
Ejemplo Recursivo[editar]
/*
* recursivo.c
*
* Julio César Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el wikilibro "Programación en C"
* bajo licencia FDL, adaptado del Dominio Público
*/
#include <stdio.h>
/* calcula el factorial de 0 a 10 */
for ( contador = 0; contador <= 10; contador++ )
printf("%d! = %ld\n", contador, factorial(
contador ));
return 0;
}
Programación en C/Vectores
< Programación en C
tipo_elemento nombre[largo];
double valores[128];
En este ejemplo declaramos un vector de 128 elementos del tipo double, los índices de los
elementos irían entre 0 (para el primer elemento y 127 para el último).
De la misma forma que con las otras declaraciones de variables que hemos visto se le
puede asignar un valor iniciar a los elementos.
O también se pueden declarar:
En caso estamos asignadole valores a los primeros 3 elementos del vector nombre. Notar
que largo debe ser mayor o igual a la cantidad de valores que le estamos asignando al
vector, en el caso de ser la misma cantidad no aporta información, por lo que el lenguaje
nos permite escribir:
tipo_elemento elemento;
...
elemento = nombre[2];
/*
* Ejemplo : El producto escalar de dos vectores
*/
#include <stdio.h>
int main()
{
const int largo = 3;
double vector_1[] = {5,1,0};
double vector_2[] = {-1,5,3};
// imprime el resultado
printf("(%f, %f, %f) . (%f, %f, %f) = %f\n",
vector_1[0], vector_1[1], vector_1[2],
vector_2[0], vector_2[1], vector_2[2],
resultado);
return 0;
}
Cuando una función recibe un vector por parámetro y cambia su contenido y el cambio es
permanente (se ve aún fuera de la función). Esto puede parecer extraño después del
énfasis que pusimos en resaltar que todos los parámetros de una función se reciben por
valor, pero se aclarará en el siguiente capitulo.
Mientras tanto usemos esto para definir una función que le aplique otra función que recibe
por parámetro a cada elemento del vector, guardando el resultado en el mismo vector y
una llamada de ejemplo a esta.
De la misma forma que venimos usando vectores de tipos básicos, podemos tener
vectores de vectores, estos se declaran de la siguiente forma:
int matriz[3][7];
int tabla[3][4]={ { 1, 2, 3, 4},
{ 5, 6, 7, 8}, /* los espacios y saltos de líneas no
son tomados en cuenta */
{ 9,10,11,12} };
double v[2][2][2];
...
printf("tabla[0][1]: %i\n", tabla[0][3]); // Imprime 4
printf("tabla[2][0]: %i\n", tabla[2][0]); // Imprime 9
...
Las cadenas de caracteres (también llamadas cadenas o strings) son un tipo particular de
vectores, que como su nombre lo dice son vectores de char, con la particularidad que
tienen una marca en el fin del (el caracter '\0'), además el lenguaje nos permite escribirlas
como texto dentro de comillas dobles si son simples no. Veamos unos ejemplos de su
declaración:
char cadena_hola[]="Hola";
char otro_hola[]={'H','o','l','a','\0'}; // Igual al anterior
char vector[]={'H','o','l','a'}; /* Un vector de 4 elementos,
con los elementos 'H','o','l' y 'a' */
char espacio_cadena[1024]="Una cadena en C";
char cadena_vacia[]="";
Se debe tener en cuenta que el largo de una cadena y el largo del vector con la que se
representa son distintos, tanto por como largo_cadena() cuenta el largo de la cadena,
como por espacio_cadena del ejemplo anterior.
Algo bastante usual es necesitar unir dos cadenas, veamos un ejemplo:
Estos dos ejemplos son versiones simplificadas de funciones provistas por la biblioteca
estándar de C a través del encabezado string.h. Nuestro largo_cadena() es similar
al strlen()de la biblioteca estándar, y unir_cadenas() se asemeja al strncat(). Si bien ver
estas versiones nos sirven para entender las cadenas en C, en general será preferible usar
las funciones provistas por la biblioteca estándar, ya que podemos estar seguros que van
a estar programadas de la mejor manera posible.
Entre las funcione que provee la biblioteca estándar de C, las más importantes son:
#include <stdio.h>
#include <string.h>
...
char color[] = "rojo";
char grosor[] = "grueso";
...
char descripcion[1024];
Definición de la Función
La función ha sido declarada, ha sido llamada y por lo tanto deber haber sido
definida. Lo cual consta de dos partes, las cuales son:
1. La Primera Línea
2. Cuerpo de la función
Se inicia con una llave “{“, y en ella, se pueden realizar asignaciones, cálculos,
impresiones, así como la declaración de las variables locales. Puede estar
constituidas por estructuras secuenciales, selectivas, iterativas, anidamientos, se
pueden llamar otras funciones, etc; finaliza con “}”. Puede devolver uno o ningún
valor.
Ejemplo 5.2
Diseñe un Programa en C, que Dado un número entero y mayor que cero,
Determine si es o no un número Primo. Ojo, los números primos sólo son
divisibles por el mismo y por la unidad (1).
#include <stdio.h>
#include <conio.h>
void primo (int numero);
main()
{
int numero, ban=1;
clrscr();
while(ban==1)
{
printf("Introduzca el n£mero por favor:\n");
scanf("%d", &numero);
while(numero<0)
{
printf("ERROR, el valor del n£mero debe ser mayor que cero\n");
scanf("%d", &numero);
}
primo(numero);
Explicación:
Quizá, lo único nuevo, e importante de explicar, radica en la llamada y la
definición de la función. Cuando una función nos devolverá un valor entero, al
identificador de dicha función debe precederle el tipo de dato. En el lugar, donde
llamamos la función, es que aparecerá el valor que nos devuelva, como valor de
retorno. En nuestro ejemplo, en una impresión. Y al momento de definirla, no se
nos debe olvidar, colocarle la sentencia return(); ya que, mediante esta
declaratoria, está retornando el valor calculado.
Pero, que sucede cuando se está trabajando, con valores bastante grandes, al
utilizar solamente el int, se producirá un error lógico; ya que como valor de
retorno podría ser un cero o una cifra negativa. Por tanto debemos usar el tipo
de dato “long int”.
Ejemplo 5.4
Diseñe un programa, que dada una cifra entera y mayor que cero, sea elevada a
una potencia introducida por el usuario, la cual. (Ejemplo: 5^2=25).
#include <stdio.h>
#include <conio.h>
long int potencia (int base, int exponente);
main()
{
int base, exponente;
clrscr();
printf("La Base es:\n");
scanf("%d", &base);
while (base<0)
{
printf("ERROR, el dato debe ser mayor que cero:\n");
scanf("%d", &base);
}
printf("El Exponente es:\n");
scanf("%d", &exponente);
printf("%d ^ %d es %ld\n\n", base, exponente, potencia(base,exponente));
getch();
return 0;
}
long int potencia (int base, int exponente)
{
long int sum=0, i,x;
for(i=1; i<exponente; i++)
{
x=base*base;
sum=sum+x;
}
return (sum);
}