• No se han encontrado resultados

Tema 6: Funciones

N/A
N/A
Protected

Academic year: 2022

Share "Tema 6: Funciones"

Copied!
23
0
0

Texto completo

(1)

Tema 6: Funciones

Funciones. Librerías básicas de C

(2)

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

(3)

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

(4)

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

(5)

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

(6)

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}

(7)

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

(8)

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/caso1

cada 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?\'";

(9)

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 2

posiciones 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

(10)

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 contrario

for (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

(11)

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/

(12)

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

. . .

(13)

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

(14)

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

(15)

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

(16)

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>

(17)

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

(18)

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)

(19)

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

(20)

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

(21)

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

(22)

ver ejemploC22B

Profs. Buitrago - Jiménez

datos_ejC22B.txt

salida.txt

Ejemplo.

(23)

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

Referencias

Documento similar

Volviendo a la jurisprudencia del Tribunal de Justicia, conviene recor- dar que, con el tiempo, este órgano se vio en la necesidad de determinar si los actos de los Estados

A partir de los resultados de este análisis en los que la entrevistadora es la protagonista frente a los entrevistados, la información política veraz, que se supone que

La invalidez en el MMPI por no respuestas no se considera criterio positivo (sólo se puede considerar tal posibilidad en caso de daño neurológico que justifique tal estilo

De este modo se constituye un espacio ontológico y epistemológico a la vez, en el que cada elemento (cada principio) ocupa un lugar determinado en la totalidad, y desde ahí está

Gastos derivados de la recaudación de los derechos económicos de la entidad local o de sus organis- mos autónomos cuando aquélla se efectúe por otras enti- dades locales o

1. LAS GARANTÍAS CONSTITUCIONALES.—2. C) La reforma constitucional de 1994. D) Las tres etapas del amparo argentino. F) Las vías previas al amparo. H) La acción es judicial en

A nivel nacional la legislación básica en materia fitosanitaria se constituye en torno a la Ley 43/2002 , de 20 de noviembre, de Sanidad Vegetal , al Real Decreto 739/2021, de 24

Tras establecer un programa de trabajo (en el que se fijaban pre- visiones para las reuniones que se pretendían celebrar los posteriores 10 de julio —actual papel de los