Hola, Mundo
empleando una función. #include<stdio.h> /* prototipo de la función decir_hola() */ void decir_hola(int numero_de_veces); int main(int argc, char * argv) { decir_hola(7); return 0; } /* Declaración de la función decir_hola() */ void decir_hola(int numero_de_veces) { int i; printf("******************************\n"); printf("******************************\n"); printf("******************************\n"); for(i=0;i<numero_de_veces;i++) printf("Hola por vez número %d\n", i); printf("******************************\n"); printf("******************************\n"); printf("******************************\n"); return; } /* ****************************** ****************************** ****************************** Hola por vez número 0 Hola por vez número 1 Hola por vez número 2 Hola por vez número 3 Hola por vez número 4 Hola por vez número 5 Hola por vez número 6 ****************************** ****************************** ****************************** Y ahora otra vez ****************************** ****************************** ****************************** Hola por vez número 0 Hola por vez número 1 Hola por vez número 2 Hola por vez número 3 Hola por vez número 4 Hola por vez número 5 Hola por vez número 6 Hola por vez número 7 Hola por vez número 8 Hola por vez número 9 Hola por vez número 10 Hola por vez número 11 Hola por vez número 12 Hola por vez número 13 ****************************** ****************************** ****************************** */
decir_hola()
. Este bloque escribe varias líneas de asteriscos, y después va escribiendo la frase "
Hola por vez número N
", haciendo variar el valor de
N
. En la función
main()
aparecen dos llamadas (dos saltos, decíamos antes) a
decir_hola()
, una con el parámetro real 7 y otra con el parámetro real 14, lo cual da lugar a dos ejecuciones del bloque de
decir_hola()
: una con
numero_de_veces
igual a 7, y otra con
numero_de_veces
igual a 14. Estas llamadas a
decir_hola()
son sólo dos, pero podríamos poner cualquier número de llamadas dentro del bloque de
main()
. El ahorro de espacio es evidente, aunque, como se verá, esa no es la ventaja más importante que aportan las funciones. Tipo_proporcionado nombre_de_función(lista_de_parámetros);
int numero_de_vocales(char * cadena);
Tipo_proporcionado
(
int
en el ejemplo) es cualquier tipo válido en C, y denota el tipo de variable en que debe almacenarse el resultado que se obtiene al ejecutar la función. Esto es, la ejecución de una función puede producir un resultado, que podríamos recoger mediante una expresión como la siguiente:
resultado = numero_de_vocales(lista);en donde el tipo de
resultado
y el tipo proporcionado por la función
suma
deben ser iguales o al menos compatibles. Si la función no va a proporcionar resultado alguno, entonces el
Tipo_proporcionado
debe ser
void
. El tipo
void
significa nada o nulo y tiene otras aplicaciones, especialmente en el mundo de los punteros.
nombre_subprograma
(
numero_de_vocales
en el ejemplo) es el nombre que deseamos dar a al función. Por convención (no porque lo imponga el lenguaje), los nombres de funciones empiezan por una letra minúscula. Para llamar a una función, esto es, para que en el código máquina haya un salto de ida al código de la función y de vuelta a la función desde la cual se hace la llamada, se escribe el nombre de la función y después unos paréntesis. Si la función admite parámetros, se ponen dentro de esos paréntesis. En el ejemplo anterior,
resultado = suma(lista);
,
lista
es un
parámetro
. Los parámetros son una vía de comunicación entre la función que hace la llamada y la función la recibe, esto es, la que se ejecuta. En un ejemplo anterior, la función que hacía la llamada era
main()
y la función que recibía la llamada era
decir_hola()
.
lista_de_parámetros
es es una colección de declaraciones de variables, de la forma
Tipo variableSi la función posee varios parámetros, esto es, si en la llamada a la función hay que aportar varios valores, será preciso separar las declaraciones mediante comas . Por ejemplo, la función cuyo prototipo se muestra a continuación admite varios parámetros:
float calcular(int x, int y, float z, struct Registro * p);Como se observará, cada parámetro (
x
,
y
,
z
y
p
)
debe
ir precedido por su tipo. Las distintas declaraciones van separadas mediante
comas
. Los parámetros que se declaran en el prototipo y en el encabezado de la función reciben el nombre de parámetros
formales
. El número, tipo y nombre de los parámetros especificados en el prototipo y en el encabezado de la función tiene que ser exactamente el mismo. Si no hay ni un sólo parámetro, debe indicarse esta circunstancia empleando la palabra
void
como lista de parámetros, como se indica en la declaración siguiente:
int calcular(void)que especifica que la función
calcular
no recibe parámetro alguno. Si se especifica una lista de parámetros
void
en el prototipo, tiene que especificarse también una lista de parámetros
void
en el encabezado de la función.
Tipo_proporcionado nombre_subprograma(lista_de_parametros) /* Encabezado */ { /* Cuerpo */ return expresión; }
void funcion(int, float, long); ... void funcion(int x, float y, long z) { /* Sentencias */ return; };Obsérvese que coinciden exactamente los tipos de los parámetros formales especificados en el prototipo y en el encabezado de la función; lo contrario sería un error. Recuérdese también que en el caso de que no haya parámetros formales es preciso emplear la palabra
void
como lista de parámetros tanto en el prototipo como en el encabezado de la función. Por ejemplo, las declaraciones siguientes corresponden a una función que carece de parámetros y no proporciona resultado alguno:
void funcion(void); ... void funcion(void) { /* Sentencias */ return; };El
Tipo_proporcionado
que se indica en el prototipo y el que se indica en el encabezado tiene que coincidir exactamente.
void
; si el
Tipo_proporcionado
no es
void
y la función carece de sentencia
return
(o ésta no se ejecuta), el resultado proporcionado por la función no está definido). La sentencia
return
puede adoptar dos formas, dependiendo del
Tipo_proporcionado
por la función. Si éste es
void
, la sentencia
return
va acompañada por ninguna expresión, como puede verse en el fragmento de código anterior. Si la función tiene un
Tipo_proporcionado
que no es
void
, entonces la sentencia return debe ir acompañada por una expresión; el tipo del valor obtenido al evaluar esa expresión debe ser el mismo que el
Tipo_proporcionado
, o al menos compatible con él.
main()
; todo programa está formado, como mínimo, por la función
main()
. Un archivo de código en C sin función
main()
no es ejecutable, pero puede ser una biblioteca de funciones; de hecho, es frecuente construir y compilar bibliotecas de funciones, que después se utilizarán sin tener que volver a compilarlas y, sobre todo, sin necesidad de conocer el cuerpo de esas funciones. El uso de una biblioteca de funciones exige conocer los prototipos de esas funciones: esa va a ser la misión de los archivos de encabezado, como
stdio.h
. .
main()
posee parámetros que le proporciona el sistema operativo. Concretamente, es frecuente encontrar programas en los que la función main() posee el aspecto siguiente:
int main(int argc, char * argv[]) {...}Los parámetros formales argc y argv sirven para que el sistema operativo pueda pasar a
main()
argumentos recibidos a través de la línea de órdenes. La mecánica de este proceso se describe en la
sección correspondiente
. Este es el método que se emplea en las órdenes de
shell
de los sistemas operativos basados en texto; de hecho, la cola de palabras de los sistemas basados en texto será sustituida por una cola de eventos en sistemas dotados de una interfaz gráfica de usuario (GUI) pero el concepto es bastante paralelo.
main()
carece de sentido, y viola todos los principios de programación estructurada.
main()
:
#include<stdio.h>; #include<stdlib.h>; #include "mi_encabezado.h";
#define MAX 10 #define MIN 5 struct Registro { char nombre[20]; int n; float f }; long int p; struct Registro * q;
int calcular (float, int, char); void imprimir(void); char * cadena(const char *, const char *);
int calcular (float f, int n, char c) { return 3.0*f - n; } void imprimir(void) { printf("Datos finales\n"); } char * cadena(const char * c1, const char * c2) { return strcat(c1, c2); }Estas zonas definen el contenido de un archivo genérico en C,
programa.c
Todas las constantes y variables que se declaran en un archivo, pero fuera de las funciones construidas en el mismo, reciben el nombre de constantes y variables
globales
. Todas las constantes y variables que se declaran dentro de una función reciben el nombre de constantes y variables
locales
.
int
, calcular valores de interés, mostrar valores de interés y salir de programa. Los valores de interés de la lista son el máximo, el mínimo y el valor medio.
float
), calcular la suma de las matrices, calcular la resta de las matrices, mostrar la suma, mostrar la resta y salir de programa.
#define PAGINAS 3 #define LINEAS 4 #define COLUMNAS 10 char libro[PAGINAS][LINEAS][COLUMNAS];El programa ofrecerá opciones para leer el libro (de teclado), mostrar una cierta página y salir del programa. Mejora.- Hacer que el programa lea de disco el contenido del libro, preguntando al usuario el nombre del fichero que lo contiene.
ax^2 + bx + c = 0Se se pide construir tres funciones, adecuadas para calcular el valor de las raíces de esta ecuación, en función del valor del discriminante
d = b^2 - 4.0*a*c
. Probar las funciones mediante un programa principal.
palabra
y la segunda se llama
diccionario
. Se pide construir la función de tal modo que proporcione el valor 1 si
palabra
aparece dentro de
diccionario
, o 0 en caso contrario.