Tema 6: Funciones
Funciones. Librerías básicas de C
Funciones
#include <stdio.h>
#include <stdlib.h>
int potencia (int , int );
main() { int i;
for (i = 0; i < 10; i++ )
printf (“%d %d %d \n”, i, potencia(2,i), potencia(-3,i));
system (“pause”);
}
/* funcion potencia, eleva “base” a la potencia “n”, n>=0 */
int potencia (int base, int n) { int i,p;
p = 1;
for (i=1; i<=n; i++) p *= base;
return p;
}
<retorno-tipo> nombre_funcion
(parametros declaraciones (si lo hay)) {
declaraciones locales instrucciones
return (variable) }
ver ejemploC6/ejC6
Profs. Buitrago - Jiménez
Lenguaje ANSI C
Funciones recursivas
Una función recursiva es una función que se llama a sí misma.
/* funcion potencia, eleva “base” a la potencia “n”, n>=0 */
int potencia (int base, int n)
{ if (n == 0) /* potencia a la cero, devuelve 1 */
return 1;
else
return (potencia(base, n-1) * base);
}
Ejemplo: la función potencia como función recursiva
Para calcular 23 e imprimir el resultado, en el main():
printf( “%d elevado a la %d es %d \n”, 2, 3, potencia(2, 3));
2 elevado a la 3 es 8
Obs.: Se puede escribir una versión mucho más compacta de la función recursiva potencia usando el operador ternario ? de la siguiente manera:
int potencia (int base, int n) { return ( n == 0 ? 1 : base*potencia(base,n-1)); }
ver ejemploC6/ejC6
Profs. Buitrago - Jiménez
Ejemplo: escribir una función que verifica si una cadena de caracteres dada constituye un número hexadecimal (los dígitos usados en base 16 son
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F).
Profs. Buitrago - Jiménez
int chequear_hexa(unsigned longNumHex, char numHex[ ]) { unsigned i, esValida;
char charHex;
esValida = 1;
for ( i = 0 ; i < longNumHex ; i++ ) { charHex = numHex[i];
if ( !(charHex >= 48 && charHex <= 57)
&& (!(charHex >= 65 && charHex <= 70)) ) { esValida = 0;
break;
} }
if (!esValida) return 0;
else return 1;
}
if ( (charHex < '0' || charHex > '9') &&
(charHex < 'A' || charHex > 'F') )
ver ejC_Hexadecimal/verficar/chequear_Hexa
Lenguaje ANSI C
Ejemplo (cont.):
Profs. Buitrago - Jiménez
#include <stdio.h>
#include <stdlib.h>
#define MAXHEX 1000
int chequear_hexa(unsigned , char numHex[]);
main() {
unsigned longNumHex, i, esValida;
char numHex[MAXHEX], charHex;
// Pide el número hexadecimal por pantalla
printf("\n\n Ingrese un numero hexadecimal: ");
scanf("%s",numHex);
longNumHex = strlen(numHex);
// Verifica la validez de la cadena como hexadecimal esValida = chequear_hexa(longNumHex, numHex);
if (!esValida) printf("\n La cadena %s NO es valida \n",numHex);
else printf("\n La cadena %s SI es valida \n",numHex);
system("pause");
}
función main donde se pide la cadena de caracteres y se realiza el llamado a la función chequear_hexa para verificar la validez de la cadena como número
hexadecimal
ver ejC_Hexadecimal/verficar/chequear_Hexa
Ejemplo: función que realiza una búsqueda binaria y decide si un valor particular x está o no en un vector/arreglo ordenado de forma ascendente. La función retorna la posición si x está, si no retorna -1.
Profs. Buitrago - Jiménez
En la figura que se incluye a la derecha, vemos qué pasa cuando se busca el valor 18 en la lista {1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23}
Lenguaje ANSI C
Ejemplo: función que realiza una búsqueda binaria y decide si un valor particular x está o no en un vector ordenado de forma ascendente. La función retorna la
posición si x está, si no retorna -1.
int busquea_binaria (int x, int v[ ], int n) { int bajo, alto, medio;
bajo = 0;
alto = n-1;
while (bajo <= alto)
{ medio = (alto + bajo) / 2;
if (x < v[medio])
alto = medio -1;
else if (x > v[medio])
bajo = medio +1;
else /* valor encontrado */
return medio;
}
return -1; /* valor no existe */
}
main ()
{ int v[ ] = {2, 5, 10, 14};
int x = 10, m, n, i;
printf (“lista de números \n”);
n = 4;
for (i = 0; i < n; i++)
printf(“%d%c”, v[i], (i%10 == 9 ||
i == n-1) ? ‘\n’ : ‘ ‘);
m = busqueda_binaria(x, v, n);
if ( m == -1)
printf (“el %d no está en la lista \n”, x);
else
printf (“el %d ocupa la posición %d \n”, x, m);
system(“pause”);
}
ver ejemploC7
Profs. Buitrago - Jiménez
continuación
Ejemplo: función que remueve todas las ocurrencias de un carácter almacenado en la variabe "c" sobre un arreglo de caracteres "s".
Ejercicios:
1. Escribir una función que remueva todos los caracteres de un “string” s2 sobre un “string” s.
2. Escribir un programa principal que lea los arreglos de caracteres s y s2, elimine las ocurrencias de s2 sobre s y escriba por pantalla el arreglos s antes y después de procesado.
Profs. Buitrago - Jiménez ver ejemploC8/caso1cada vez que el caracter
almacenado en c no aparece, se copia el caracter de la
posición i a la posición j.
void limpiar (char s[ ], char c) { int i, j;
for (i = j = 0; s[i] != '\0'; i++) if(s[i] != c){
s[j] = s[i];
j = j+1; } s[j] = ‘\0’;
}
if (s[i] != c) s[j++] = s[i];
ejemplo declaración -> char c , s[] = "ae ees 45de 7er@ ere rt?\'";
Lenguaje ANSI C
Ejemplo: función que convierte un “string” al número equivalente. El “string” puede tener espacios en blanco al principio, pero no intercalados. El proceso debe
terminar al encontrar el primer carácter que no puede ser un número.
int caracter2entero (char s[ ]) { int i, n, signo;
for (i = 0; s[i] == ‘ ’; i++);
signo = (s[i] == ‘-‘) ? -1 : 1;
if (s[i] == ‘+’ || s[i] == ‘-’) i++;
for (n = 0; s[i] >= ‘0’ && s[i] <= ‘9’; i++) n = 10*n + (s[i] – ‘0’);
return signo*n;
}
cuenta espacios en blanco al principio
incrementa i si existe el signo del número
1 5 3 = 1 * 10
2+ 5 * 10 + 3 = (1 * 10 + 5) * 10 + 3 = ((0 * 10 +1) * 10 + 5) * 10 + 3
0 1 2posiciones n n
n
Obs:
ver ejemploC9
Profs. Buitrago - Jiménez
char s[] = " +115678-a1b1";
Ejercicio: Ampliar el ejemplo para el
caso de números reales, por ejemplo
el caso de aparecer -145.567
Funciones especiales.
isspace(c), con c un carácter, retorna
1 si c es un espacio en blanco, 0 en caso contrario isdigit(c), con c un carácter, retorna
1 si ‘0’ ≤ c
≤ ‘9’, 0
en caso contrariofor (n = 0; isdigit(s[i]); i++) for (i = 0; isspace(s[i]); i++);
int caracter2entero (char s[ ]) { int i, n, signo;
for (i = 0; s[i] == ‘ ‘; i++);
signo = (s[i] == ‘-‘) ? -1 : 1;
if (s[i] == ‘+’ || s[i] == ‘-’) i++;
for (n = 0; s[i] >= ‘0’ && s[i] <= ‘9’; i++) n = 10*n + (s[i] – ‘0’);
return(signo*n);
}
Ejemplo:
Obs. Hay que declarar en el encabezado la directiva
# include <ctype.h>
islower(c): 1 si c es minúscula isupper(c): 1 si c es mayúscula
isalpha(c): distinto de cero si c es una letra (1 mayúscula, 2 minúscula) Profs. Buitrago - Jiménez ver ejemploC9
Profs. Buitrago - Jiménez
Lenguaje ANSI C
Características fundamentales de las funciones
• Estar definida en el mismo archivo de texto donde está escrito el programa principal (función main), o ser incluida en éste mediante
#include.
• Ser llamada desde el programa principal, desde otra función o desde ella misma (recursividad).
• Admitir o no argumentos.
• Retornar o no un valor.
• Poseer sus propias variables, algunas de las cuales podrían conservar su valor de una llamada a otra de la función (static).
• Tener varios puntos de salida ( return).
Una función PUEDE:
Una función DEBE:
• Tener uno y sólo un punto de entrada.
• Tener un prototipo y un cuerpo de definición.
ver ejemploC9A/
ejemplos de función main y otras funciones en archivos separados
ver ejemploC10A/
Ejemplo: función que ordena un vector de n elementos enteros en forma ascendente.
int ordenar (int v[ ], int n) { int gap, i, j, temp;
for (gap = n/2; gap > 0; gap /= 2) for(i = gap; i < n; i++)
for (j = i-gap; j >= 0 &&
v[j] > v[j+gap]; j -= gap) { temp = v[j];
v[j] = v[j+gap];
v[j+gap] = temp; } return (1);}
# include <stdio.h>
# include <stdlib.h>
main ()
{ int n, m, i;
int v[ ] = {5, 4, 3, 2, 1, 0};
n = 6;
m = ordenar(v, n);
for (i = 0; i < n; i++)
printf(“%d%c”, v[i], (i%10 == 9 ||
i == n-1) ? ‘\n’ : ‘ ‘);
system(“pause”);
n=6 gap i j }
3 3 0
4 1
5 2
1 1 0
2 1
0
3 2
cambio v[0] y v[3]
cambio v[1] y v[4]
cambio v[2] y v[5]
cambio v[0] y v[1]
cambio v[1] y v[2]
cambio v[0] y v[1]
no cambio v[2] y v[3]
5 4 3 2 1 0
0 1 2 3 4 5
(1) (2)
. . .
inicial
final
. . .
ver ejemploC10
Profs. Buitrago - Jiménez
2 1 0 5 4 3
. . .
Profs. Buitrago - Jiménez
Lenguaje ANSI C
Protección de argumentos pasados por referencia
Se usa el calificador const para evitar que los argumentos pasados por referencia a una función sean modificados en ésta.
#include <stdio.h>
#include <stdlib.h>
void esp_a_guion(const char *);
int main(void)
{ esp_a_guion("esto es una prueba");
printf("\n\n");
system("pause");
return 0;
}
/* CORRECTO */
void esp_a_guion(const char *cad) { while (*cad) {
if (*cad == ' ') printf("%c",'-');
else printf("%c",*cad);
cad++;
} }
#include <stdio.h>
#include <stdlib.h>
void esp_a_guion(const char *);
int main(void)
{ esp_a_guion("esto es una prueba");
printf("\n\n");
system("pause");
return 0;
}
/* INCORRECTO */
void esp_a_guion(const char *cad) { while (*cad) {
if (*cad == ' ') *cad = '-'; /* no se puede */
printf("%c",*cad);
cad++;
} }
ver ejemploC11 printf("%c",*cad==' '?'-':*cad);
La función sustituye espacio por guion
Ejemplo de MAKEFILE para compilación de un programa en LINUX Supongamos que el siguiente
programa está conformado por las tres funciones escritas en los archivos principal.c,
imprime.c y duplica.c
Profs. Buitrago - Jiménez
duplica.c
imprime.c
principal.c
Ejemplo de MAKEFILE para compilación de un programa en LINUX Supongamos que nuestro
programa está repartido en 3 archivos que contienen el programa principal (main) y 2 funciones, de nombres principal.c,
imprime.c y duplica.c,
respectivamente.
Obs. El espacio que antecede a
$(COMPILADOR) es el que crea la tecla “tab”
Archivo de nombre Makefile (sin extensión)
El “backslash” \ indica
continuación de línea in LINUX.
Profs. Buitrago - Jiménez
Obs. En la consola se escribe make para ejecutarlo
Lenguaje ANSI C
math.h :
acos, asin, atan, atan2, ceil, cos, cosh, exp, fabs, floor, fmod, frexp, ldexp, log, log10, modf, pow, sin, sinh, sqrt, tan, tanh
string.h :
memchr, memcmp, memcpy, memmove, memset, strcat, strchr, strcmp, strcoll, strcpy, strcspn, strerror, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, strtok, strxfrm
stdio.h :
clearerr, fclose, feof, ferror, fflush, fgetc, fgetpos, fgets, fopen, fprintf, fputc, fputs, fread, freopen, fscanf, fseek, fsetpos, ftell, fwrite, getc, getcha, gets, perror, printf, putc, putchar, puts, remove, rename, rewind, scanf, setbuf, setvbuf, sprintf, sscanf, tmpfile, tmpnam, ungetc, vfprintf, vprintf, vsprintf
time.h :
asctime, clock, ctime, difftime, gmtime, localtime, mktime, strftime, time
stdlib.h :
abort, abs, atexit, atof, atoi, atol, bsearch, calloc, div, exit, free, getenv, labs, ldiv, malloc, mble, mbstowcs, mbtowc, qsort, rand, realloc
ctype.h :
tolower, toupper, isspace, isdigit, islower, isupper, isalpha
Profs. Buitrago - Jiménez http://www.di-mgt.com.au/src/CStdLib.html
Librerías básicas de C
Una biblioteca de C es una colección de funciones utilizadas en el lenguaje de programación C. Las bibliotecas más comunes son la biblioteca estándar de C y la biblioteca del estándar ANSI C, la cual provee las especificaciones de los estándares que son ampliamente compartidas entre bibliotecas.
#include <nombre.h>
Función clock() de la librería time.h
Profs. Buitrago - Jiménez ver ejC1.c
librería
variables tipo clock_t
llamado función clock()
cálculo tiempo de CPU
constante en time.h
Lenguaje ANSI C
Profs. Buitrago - Jiménez
Generación de números enteros aleatorios
ver ejC_uso_rand
nn = rand()%(N-M+1)+M
Genera un número aleatorio entre los enteros positivos M y N, con N
> M.
srand((unsigned int) sem) Inicializa la secuencia de aleatorios srand((unsigned int)
time((time_t *)NULL))
Establece la semilla para generar números aleatorios basado en el tiempo del computador (función time)
rand() genera un número entre 0 y 32767 (RAND_MAX)
Profs. Buitrago - Jiménez
Lenguaje ANSI C
atoi(): Convierte una cadena a su valor numérico (entero). La conversión se detiene en cuanto se encuentra un carácter no aceptable. Si no se puede convertir la cadena, devuelve 0.
Sintaxis: int atoi (const char *cadena);
isalpha(): El valor de retorno será no nulo si c es una letra y cero en caso contrario (retorna 1 si es una letra mayúscula y 2 si es
minúscula)
Sintaxis: int isalpha(int c) Funciones
ctype.h stdlib.h
ver ejemploC9
Funciones especiales para cadenas de caracteres.
En el encabezado hay que declarar la directiva
#include <string.h>
strlen(“Hola, como estas”); retorna 16
char v[32] = “Hola, como estas”;
strlen(v); retorna 16 sizeof(v); retorna 32
longitud hasta el carácter nulo, '\0' espacio reservado para el arreglo de caracteres v
strlen(), cuenta el número de caracteres de una cadena, sin incluir el '\0' (caracter nulo) final.
El paso del argumento se realiza por referencia, pues como argumento se emplea un apuntador a la cadena, y devuelve un entero sin signo que es el número de caracteres de la cadena.
Sintaxis: unsigned strlen (const char * s);
Profs. Buitrago - Jiménez
Lenguaje ANSI C
Funciones especiales para cadenas de caracteres.
strcat(), se emplea para unir dos cadenas de caracteres poniendo s2 a
continuación de s1. El valor de retorno es un apuntador a s1. Los argumentos son los apuntadores a las dos cadenas que se desea unir. La función almacena la cadena completa en la primera de las cadenas (por lo cual ésta debe disponer de suficiente espacio).
Sintaxis: char *strcat(char *s1, const char *s2);
strcpy(), se utiliza para copiar cadenas. Utiliza como argumentos dos apuntadores a caracter: el primero es un apuntador a la cadena copia, y el segundo es un
apuntador a la cadena original. El valor de retorno es un apuntador a la cadena s1.
Sintaxis: char *strcpy (char *s1, const char *s2); ver ejC_proy\fecha2texto
ver ejemploC9
strcmp(), sirve para comparar dos cadenas de caracteres. Como argumento utiliza a las cadenas que se van a comparar. La función devuelve cero si las cadenas son iguales, un valor menor que cero si s1 es menor (en orden alfabético) que s2, y un valor mayor que cero si s1 es mayor que s2.
Sintaxis: int strcmp (const char *s1, const char *s2)
Profs. Buitrago - Jiménez
retornar
ver ejemploC22B
Profs. Buitrago - Jiménez
datos_ejC22B.txt
salida.txt
…
Ejemplo.
strchr(s1, ch);
Retorna apuntador a la primera ocurrencia del caracter ch en la cadena de caracteres s1.
Sintaxis:
char *strchr(const char *s1, int c);
strstr(s1, s2);
Retorna apuntador a la primera ocurrencia de la cadena de caracteres s2 en la cadena de caracteres s1.
Sintaxis:
char *strstr(const char *s1, const char *s2);
Lenguaje ANSI C
Funciones especiales para cadenas de caracteres.
Profs. Buitrago - Jiménez ver ejemploC22C