Programaci´ on : C (5)
Dr. J.B. Hayet
CENTRO DE INVESTIGACI ´ON EN MATEM´ATICAS
Agosto 2013
,
J.B. Hayet Programaci´on, Agosto 2013 1 / 40
Outline
1 Funciones
,
J.B. Hayet Programaci´on, Agosto 2013 2 / 40
Funciones
Outline
1 Funciones
,
J.B. Hayet Programaci´on, Agosto 2013 3 / 40
Funciones
Funciones
Son pedazos de c´odigo que se pueden
llamar
unos entre ellos (incluso recursivamente).Regresan un valor o no (si el tipo de regreso es void ).
Un programa tiene que tener una funci´on main.
La funci´on empieza por declaraciones de los variables, luego viene el cuerpo de las instrucciones y la instrucci´on return que regresa el resultado (menos estricto en C99).
T´ıpicamente :
t i p o X f u n c i o n ( t i p o Y a r g 1 , t i p o Z a r g 2 , . . . ) { t i p o X t ;
. . .
r e t u r n t ; }
,
J.B. Hayet Programaci´on, Agosto 2013 4 / 40
Funciones
Funciones : ejemplo
i n t f ( u n s i g n e d i n t n ) { i n t r e s u l t = 1 ; i n t k ;
f o r ( k =1; k<=n ; k++) r e s u l t ∗= k ; r e t u r n r e s u l t ;
}
,
J.B. Hayet Programaci´on, Agosto 2013 5 / 40
Funciones
Funciones
Llamar a la funci´on se hace con el nombre de la funci´on, y con los par´ametros dentro de los () (variables o constantes).
No es est´ andar el orden de evaluaci´ on de los par´ ametros
(cuidado con ++ en expresiones pasadas en argumento. . . ).i n t r e s u l t = f ( 1 5 ) ; i n t a =5;
i n t b=f ( a ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 6 / 40
Funciones
Funciones : void
Una funci´on que no regresa nada tiene el tipo void (tipo nulo). En este caso, el
return
se puede usar (sin argumentos) o no.v o i d g ( u n s i g n e d i n t n ) { p r i n t f ( ”%d \n” , f ( n ) ) ; }
,
J.B. Hayet Programaci´on, Agosto 2013 7 / 40
Funciones
Funciones : memoria
Los recursos en memoria dentro de cada funci´on son
locales
: desaparecen al salir de la funci´on. Por eso la estructura depila
en memoria : cada nueva llamada pide un espacio de memoria que seconsigue abajo del espacio memoria de la funci´ on que llama
; cuando se sale, este espacio est´a disponible otra vez. . .,
J.B. Hayet Programaci´on, Agosto 2013 8 / 40
Funciones
Funciones : memoria
.text
int funcion() { int i;
...
}
PILA HEAP
Direciones crecientes
.data .bss
int *data=(int *) malloc(100*sizeof(int));
static double pi=3.14; int variableGlobal;
int main() { ...
PROGRAMA CARGADO EN MEMORIA
,
J.B. Hayet Programaci´on, Agosto 2013 9 / 40
Funciones
Funciones : memoria
}
int main() {
}
int norm(int x,int y) {
}
int prod(int x,int y) { int a;
int b;
int c = norm(a,b);
return 0;
return n;
int p=x*y;
return p
int n = prod(x,x)+prod(y,y);
Memoria de 512 Mo
main : variables locales, parametros...
,
J.B. Hayet Programaci´on, Agosto 2013 10 / 40
Funciones
Funciones : memoria
norm : variables, parametros, direccion regreso...
}
int main() {
}
int norm(int x,int y) {
}
int prod(int x,int y) { int a;
int b;
int c = norm(a,b);
return 0;
return n;
int p=x*y;
return p
int n = prod(x,x)+prod(y,y);
Memoria de 512 Mo
main : variables locales, parametros...
,
J.B. Hayet Programaci´on, Agosto 2013 11 / 40
Funciones
Funciones : memoria
prod : variables, parametros, direccion regreso...
norm : variables, parametros, direccion regreso...
}
int main() {
}
int norm(int x,int y) {
}
int prod(int x,int y) { int a;
int b;
int c = norm(a,b);
return 0;
return n;
int p=x*y;
return p
int n = prod(x,x)+prod(y,y);
Memoria de 512 Mo
main : variables locales, parametros...
,
J.B. Hayet Programaci´on, Agosto 2013 12 / 40
Funciones
Funciones : memoria
norm : variables, parametros, direccion regreso...
}
int main() {
}
int norm(int x,int y) {
}
int prod(int x,int y) { int a;
int b;
int c = norm(a,b);
return 0;
return n;
int p=x*y;
return p
int n = prod(x,x)+prod(y,y);
Memoria de 512 Mo
main : variables locales, parametros...
,
J.B. Hayet Programaci´on, Agosto 2013 13 / 40
Funciones
Funciones : memoria
prod : variables, parametros, direccion regreso...
norm : variables, parametros, direccion regreso...
}
int main() {
}
int norm(int x,int y) {
}
int prod(int x,int y) { int a;
int b;
int c = norm(a,b);
return 0;
return n;
int p=x*y;
return p
int n = prod(x,x)+prod(y,y);
Memoria de 512 Mo
main : variables locales, parametros...
,
J.B. Hayet Programaci´on, Agosto 2013 14 / 40
Funciones
Funciones : memoria
norm : variables, parametros, direccion regreso...
}
int main() {
}
int norm(int x,int y) {
}
int prod(int x,int y) { int a;
int b;
int c = norm(a,b);
return 0;
return n;
int p=x*y;
return p
int n = prod(x,x)+prod(y,y);
Memoria de 512 Mo
main : variables locales, parametros...
,
J.B. Hayet Programaci´on, Agosto 2013 15 / 40
Funciones
Funciones : memoria
}
int main() {
}
int norm(int x,int y) {
}
int prod(int x,int y) { int a;
int b;
int c = norm(a,b);
return 0;
return n;
int p=x*y;
return p
int n = prod(x,x)+prod(y,y);
Memoria de 512 Mo
main : variables locales, parametros...
,
J.B. Hayet Programaci´on, Agosto 2013 16 / 40
Funciones
Funciones : recursividad
i n t f ( u n s i g n e d i n t n ) { i f ( n==0)
r e t u r n 1 ; e l s e
r e t u r n n ∗ f ( n − 1 ) ; }
Usar funciones recursivas, aunque puede escribirse en un c´odigo muy conciso, puede ser
muy costoso en t´ erminos de memoria !
,
J.B. Hayet Programaci´on, Agosto 2013 17 / 40
Funciones
Funciones : variables locales
Por default : las variables declaradas en las funciones est´an reservadas
en la pila
y s´olo existen el tiempo de estar en la funci´on. Son puramentelocales
. El espacio pila est´alimitado
, generalmente a unos Mo.Bidarray[CLASE4][18:48]>ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) 6144 file size (blocks, -f) unlimited max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited
open files (-n) 256
pipe size (512 bytes, -p) 1 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited
max user processes (-u) 266
virtual memory (kbytes, -v) unlimited
,
J.B. Hayet Programaci´on, Agosto 2013 18 / 40
Funciones
Funciones : variables est´ aticas
Unas variables pueden estar guardadas diferentemente del
mecanismo de pila : quedan de visibilidad local pero su espacio memoria est´a guardado (el valor no se pierde entre dos llamadas a la funci´on). Se introducen por la palabra llave
static
.i n t m( u n s i g n e d i n t n ) {
s t a t i c i n t k =1000; // . d a t a s t a t i c i n t l ; // . b s s
i n t c =10; // p i l a
. . . }
,
J.B. Hayet Programaci´on, Agosto 2013 19 / 40
Funciones
Funciones : variables globales
Hay tambi´en variables que son definidas fuera de toda funci´on (en el archivo de c´odigo), se llaman
variables globales
. Estar´an visibles en todo c´odigo que sigue su declaraci´on.i n t n G l o b a l ; v o i d f ( ) {
p r i n t ( ” V a l o r de n G l o b a l %d \ n ” , n G l o b a l ++);
r e t u r n ; }
i n t main ( ) { i n t k ;
n G l o b a l =19;
f o r ( k =0; k <10; k++) f ( ) ;
r e t u r n 0 ; }
,
J.B. Hayet Programaci´on, Agosto 2013 20 / 40
Funciones
Funciones : variables globales
Cuidado con conflictos de
nombre
: i n t n ;v o i d f ( ) {
i n t n =0;
n =18;
. . . r e t u r n ; }
,
J.B. Hayet Programaci´on, Agosto 2013 21 / 40
Funciones
Funciones
No se puede definir una funci´on
dentro
de otra, pero s´olo antes o despu´es de otra.Una funci´on que llama otra debe de saber antes de la llamada que esa existe : una declaraci´on de la funci´on es indispensablesi es definida despu´es de la que llama (el prototipo solo : tipo, nombre, argumentos)
i n t f ( u n s i g n e d i n t n ) ; // D e c l a r a t i o n de f v o i d g ( u n s i g n e d i n t n ) { // D e f i n i c i o n de g
p r i n t f ( ”%d \ n ” , f ( n ) ) ; }
i n t f ( u n s i g n e d i n t n ) { // D e f i n i c i o n de f i n t p=(n ==0)?1: n ∗ f ( n − 1 ) ;
r e t u r n p ; }
,
J.B. Hayet Programaci´on, Agosto 2013 22 / 40
Funciones
Funciones
Para no tener l´ıos con el orden de las funciones (declaraciones, definiciones), se suele poner todas las declaraciones en un archivo header separado del archivo .c en que vienen las definiciones, con una extensi´on .h.
Contenido de func.h :
i n t f ( u n s i g n e d i n t n ) ; // D e c l a r a c i ´o n de f v o i d g ( u n s i g n e d i n t n ) ; // D e c l a r a c i ´o n de g
,
J.B. Hayet Programaci´on, Agosto 2013 23 / 40
Funciones
Funciones : headers
Contenido de func.c, que incluye el contenido de func.h (comando al preprocesador) :
#i n c l u d e ” f u n c . h ”
v o i d g ( u n s i g n e d i n t n ) { // D e f i n i c i ´o n de g . . .
}
i n t f ( u n s i g n e d i n t n ) { // D e f i n i c i ´o n de f . . .
}
,
J.B. Hayet Programaci´on, Agosto 2013 24 / 40
Funciones
Funciones : cast de par´ ametros
Otra ventaja de las declaraciones es que permite prever si se necesita hacer conversiones de tipos, cuando es necesario.
#i n c l u d e < s t d i o . h>
// v o i d h ( i n t m, i n t n ) ; i n t main ( ) {
f l o a t b =6 , c =9;
h ( b , c ) ; }
v o i d h ( i n t m, i n t n ) { // D e f i n i c i o n de g p r i n t f ( ”%d %d \ n ” ,m, n ) ;
}
,
J.B. Hayet Programaci´on, Agosto 2013 25 / 40
Funciones
Funciones : cast de par´ ametros
Bidarray[CLASE2][18:14]>gcc exo2.c -o exo2 exo2.c:9: warning: conflicting types for ’h’
exo2.c:7: warning: previous implicit declaration of ’h’ was here Bidarray[CLASE2][18:14]>./exo2
0 1075314688
,
J.B. Hayet Programaci´on, Agosto 2013 26 / 40
Funciones
Funciones externas
Se puede usar funciones que nosotros no definemos, pero que tomamos de otras librer´ıas; en este caso se tiene que declararla, y se puede hacer con la palabra llave extern :
e x t e r n i n t p u t c h a r ( i n t ) ;
Significa que se espera en otra unidad de compilaci´on la definici´on de esa funci´on. (en realidad es
opcional
porque cualquiera declaraci´on de funci´on es extern por default),
J.B. Hayet Programaci´on, Agosto 2013 27 / 40
Funciones
Funciones : par´ ametros
Los par´ametros est´an procesados exactamente como variables locales : a la llamada de la funci´on, est´an copiados en el segmento memoria de la pila correspondiendo a la funci´on.
Por eso al salir de la funci´on, esas copias no existen mas ! El comportamiento global es que el valor de los par´ametros no puede estar cambiado dentro de una funci´on.
v o i d h ( double x ) { x = 1 . 0 ; r e t u r n ; } ;
double y = 3 . 0 ; h ( y ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 28 / 40
Funciones
Funciones : par´ ametros
Para cambiar el valor de par´ametros, hay que pasarle a la funci´on el apuntador hacia este valor; es ´util cuando se necesita cambiar varias cosas. . .
v o i d h ( double ∗ x ) {
∗ x = 1 . 0 ; } ;
double y = 3 . 0 ; h(&y ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 29 / 40
Funciones
Funciones : par´ ametros
Lo com´un es usar el return para regresar una error, y hacer todos los otros “regresos” por apuntadores,
i n t h ( double ∗ x ) {
∗ x = 1 . 0 ; . . .
i f ( p r o b l e m )
r e t u r n −1;
r e t u r n 0 ; } ;
double y = 3 . 0 ; i n t e r r = h(&y ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 30 / 40
Funciones
Funciones : main
El entero de regreso de main esta enviado al sistema. 0
(EXIT SUCCESS, macro de stdlib.h) significa que todo pas´o bien, valores no nulas a ejecuciones problem´aticas (como
EXIT FAILURE). Alternativamente se puede usar exit(int status);
,
J.B. Hayet Programaci´on, Agosto 2013 31 / 40
Funciones
Funciones : main
Hasta ahora vimos como prototipo valido para main i n t main ( ) ;
pero hay otro :
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 32 / 40
Funciones
Funciones : main
argc
es el numero de parametros pasados al programa al lanzarlo (contando el nombre del programa);argv
es un apuntador hacia las diferentes cadenas de caracteres que componen la linea de comanda (nombre del programa y par´ametros)p r o g 1 23 t a r a t a t a
En este caso argc=4, argv[0]=“prog”, argv[1]=“1”, argv[2]=“23”, argv[3]=“taratata”
,
J.B. Hayet Programaci´on, Agosto 2013 33 / 40
Funciones
Apuntadores sobre funciones
A veces puede ser ´util poder usar dentro de una funci´on una entre varias funciones para hacer tal o tal tarea sin tener que reescribir el c´odigo correspondiendo a todos los casos.
Por ejemplo, suponemos que queremos, dentro de una funci´on, hacer ordenamiento (sort) de n´umeros dentro de un arreglo; existen varios algoritmos : puede ser ´util pasar como
par´ ametro
“la funci´on” que lo har´a.,
J.B. Hayet Programaci´on, Agosto 2013 34 / 40
Funciones
Apuntadores sobre funciones
Para eso existe un
apuntador sobre funci´ on
que es simplemente un objeto apuntando hacia el c´odigo de la funci´on en la memoria. Si la funcion es de prototipo :t i p o f u n c i o n ( t i p o 1 , . . . , t i p o n ) ;
Entonces un apuntador hacia este tipo de funciones tiene este tipo : t i p o ( ∗ ) ( t i p o 1 , . . . , t i p o n ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 35 / 40
Funciones
Apuntadores sobre funciones
Cuidado a no confundir :
t i p o ∗ f u n c ( t i p o 1 , . . . , t i p o n ) ; t i p o ( ∗ f u n c ) ( t i p o 1 , . . . , t i p o n ) ; Llamar de dos maneras :
f u n c ( v1 , . . . , vn ) ; ( ∗ f u n c ) ( v1 , . . . , vn ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 36 / 40
Funciones
Apuntadores sobre funciones
Ejemplo :
i n t a p p l y S o r t ( i n t ∗ , i n t , i n t ( ∗ ) ( i n t ∗ , i n t ) ) ; Tomar´ıa como entrada apuntador hacia datos enteros, numero de datos y una funci´on de ordenamiento que regresa int y que toma como input, tambi´en, apuntador y numero de datos. Definir´ıamos :
i n t q u i c k S o r t ( i n t ∗ d a t a , i n t n d a t a ) { . . .
} ;
i n t h e a p S o r t ( i n t ∗ d a t a , i n t n d a t a ) { . . .
} ;
,
J.B. Hayet Programaci´on, Agosto 2013 37 / 40
Funciones
Apuntadores sobre funciones
Ejemplo (seguida):
Luego lo podr´ıamos usar as´ı : i n t ∗ d a t a ;
i n t n d a t a ; . . .
i n t e r r=a p p l y S o r t ( d a t a , n d a t a , q u i c k S o r t ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 38 / 40
Funciones
Numero variable de par´ ametros
Es posible definir funciones que toman un numero variable de par´ametros. Ya conocen unas : printf, scanf. . .
En este caso, el prototipo debe de especificar al menos un par´ametro formal, y los potenciales est´an resumidos por ... :
i n t v a r f ( i n t a , c h a r c , . . . ) ; o tambi´en :
i n t p r i n t f ( c h a r ∗ f o r m a t , . . . ) ;
,
J.B. Hayet Programaci´on, Agosto 2013 39 / 40
Funciones
Numero variable de par´ ametros
Para acceder a los par´ametros, se usa macros definidas en stdarg.h i n t sum ( i n t , . . . ) ;
i n t sum ( i n t num , . . . ) { i n t r e s = 0 ;
i n t i ;
v a l i s t l i s t a P a r a m s ;
v a s t a r t ( l i s t a P a r a m s , num ) ; f o r ( i = 0 ; i < num ; i ++)
r e s += v a a r g ( l i s t a P a r a m s , i n t ) ; v a e n d ( l i s t a P a r a m s ) ;
r e t u r n ( r e s ) ; }
,
J.B. Hayet Programaci´on, Agosto 2013 40 / 40