23
DESCOMPOSICIÓN FUNCIONAL (I Parte) ASIGNATURA: PROGRAMACIÓN ESTRUCTURADA 2013 DESCOMPOSICIÓN FUNCIONAL (I Parte) Funciones en C D EPARTAMENTO DE C OMPUTACIÓN UNAN-L EÓN

DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

  • Upload
    others

  • View
    4

  • Download
    0

Embed Size (px)

Citation preview

Page 1: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

ASIGNATURA:

PROGRAMACIÓN ESTRUCTURADA

2013

DESCOMPOSICIÓN FUNCIONAL (I Parte)

Funciones en C

D E P A R T A M E N T O D E C O M P U T A C I Ó N – U N A N - L E Ó N

Page 2: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

2

UNIDAD V: DESCOMPOSICIÓN FUNCIONAL

♦ INTRODUCCIÓN: Un programa fuente C está formado por una o más funciones, una función es un conjunto de instrucciones que realizan una tarea específica. Muchas de las funciones que utilizaremos pertenecen a la biblioteca de C, por lo tanto ya están escritas y compiladas. Otras tendremos que escribirlas nosotros mismos cuando necesitemos ejecutar una tarea que no esté en la biblioteca de C. Todo programa debe contener una función nombrada main, como se muestra a continuación: int main() { //Código C } Esta función main es el punto de entrada de ejecución de un programa, por tal motivo siempre un programa en C lleva esta función. El diseño top down de programas, consiste precisamente en encontrar la solución de un problema mediante la aplicación sistemática de descomposición del problema en subproblemas cada vez más simples, aplicando la máxima de dividir para vencer. El empleo de esta técnica de desarrollo de programas, así como la utilización únicamente de estructuras secuenciales, alternativas y repetitivas, nos conduce a la denominada programación estructurada. En ocasiones se piensa que todo el proceso se podría haber hecho utilizando solamente la función main, lo cual es cierto. Pero, lo que se pretende es que pueda ver de una forma clara que, en general, un programa C es un conjunto de funciones que se llaman entre sí con el fin de obtener el resultado perseguido, y que la forma sencilla de resolver un problema es descomponerlo en subproblemas más pequeños y por lo tanto más fáciles de solucionar; cada subproblema será resuelto por una función C.

♦ DEFINICIÓN DE FUNCIÓN: Una función es considerada como un micro programa dentro de un programa, una función contiene un grupo de sentencias bajo un mismo nombre con la finalidad de hacer más fácil la solución a un problema dado. Es decir, una función es una colección independiente de declaraciones y sentencias enfocadas a realizar una tarea específica. Otro detalle importante es que las funciones que escriba deben ser autónomas, para posteriormente poderlas utilizar sin dificultades en otros programas. Una función es autónoma cuando depende única y exclusivamente de sus propios argumentos.

Page 3: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

3

Una función es un fragmento de programa parametrizado que efectúa unos cálculos y, o devuelve un valor como resultado, o tiene efectos laterales (modificación de variables globales o argumentos, volcado de información en pantalla, etc.), o ambas cosas. Por ejemplo: scanf(“%d %d”,&a,&b); Cuando se accede a una función desde un determinado punto del programa, se le puede pasar información mediante unos identificadores especiales conocidos como argumentos (también denominados parámetros). Una vez que la función procesa esta información, devuelve un valor mediante la instrucción return. La estructura general de una función en C es la siguiente: tipo_de_retorno nombre_de_la_función (lista_de_parámetros) {

cuerpo_de_la_función return expresión

} Una función consta de:

• Definiciones y/o declaraciones • Sentencias a ejecutar

Algo que si debemos cumplir al escribir un programa en C, es que las definiciones y/o declaraciones en las funciones deben de realizarse antes de escribir la primer sentencia. Ejemplo #1: Programa en C que suma dos números enteros implementando una función. #include<stdio.h> //Prototipo Función Suma int suma(int a, int b); void main() { int n1,n2,res; printf("Sumando 1:"); scanf("%d",&n1); printf("Sumando 2:"); scanf("%d",&n2); res=suma(n1,n2); printf("%d + %d = %d\n",n1,n2,res); }

Page 4: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

4

int suma(int a, int b) { int res; res=a+b; return(res); }

♦ DIRECTRICES DEL PREPROCESADOR:

La finalidad de las directrices es facilitar el desarrollo, la compilación y el mantenimiento de un programa. Una directriz se identifica porque inicia con el carácter #. Las más usuales son la directriz de inclusión, #include, y la directriz de sustitución #define. Las directrices son procesadas por el preprocesador de C, que es invocado por el compilador antes de proceder a la traducción del programa fuente.

♦ DIRECTRIZ DE INCLUSIÓN #include: En general, cuando se invoca a una función antes de su definición, es necesario incluir previamente a la llamada el prototipo de la función. Como ejemplo observe la función suma del programa anterior. La definición de está escita a continuación de la función main y la función main llama a dicha función. Esto es así para todas las funciones, incluidas las funciones de la biblioteca de C, como printf. Las declaraciones de las funciones de la biblioteca de C se localizan en los ficheros de cabecera (ficheros con extensión .h). Estos ficheros generalmente se encuentran en el directorio predefinido include o en el directorio de trabajo. Para incluir la declaración de una función de la biblioteca de C, basta con incluir el fichero de cabecera que la contiene antes de que ella sea invocada. Esto se hace utilizando la directriz #include. Si el fichero de cabecera se encuentra en el directorio predefinido include, utilizaremos #include <fichero.h>. Por ejemplo: #include <stdio.h> /* declaraciones de las funciones C estándar de E/S*/ Si el fichero se encuentra, en el directorio de trabajo o en el directorio include, utilice #include "fichero.h". Por ejemplo: #include "misfunciones.h" La directriz anterior busca el fichero especificado primero en el directorio de trabajo y si no lo localiza, sigue la búsqueda en el directorio include.

Page 5: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

5

♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica al compilador, que toda aparición en el programa de identificador, debe ser sustituida por valor. Por ejemplo: #include <stdio.h> #define MAX 10 int main() {

int i; for(i=0; i<MAX; i++ )

printf("%d",i+1); return 0;

} Cuando el preprocesador de C procese las directriz del ejemplo anterior, todas las apariciones de MAX en el programa fuente son sustituidas por el valor 10.

♦ DECLARACIÓN Y DEFINICIÓN DE UNA FUNCIÓN: Al momento de definir una función en lenguaje C se deben de tomar en cuenta los siguientes aspectos:

• El lenguaje C se basa en el uso de funciones. • No se puede definir una función dentro de otra función, es decir, todas las funciones

deben de estar en el mismo nivel. • Siempre ha de existir la función main ya que esta es la función que se ejecutará al

iniciarse el programa.

♦ DEFINICIÓN DE UNA FUNCIÓN: La definición de una función consta de la cabecera y del cuerpo de la función, la sintaxis es la siguiente: TipoRetorno NombreFunción (ParámetrosFormales) {

[declaraciones] Sentencias;

}

Page 6: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

6

Donde:

• TipoRetorno: Indica el valor devuelto por la función, puede ser un tipo de dato fundamental o definido por el usuario. Una función no puede retornar un arreglo o una función, sino un puntero al arreglo o a la función.

• NombreFunción: Es el identificador que indica el nombre de la función. • ParámetrosFormales: Componen la lista de argumentos de la función, esta lista es

un conjunto de variables con sus tipos. Estos parámetros reciben los valores de las variables pasadas en la llamada a la función.

La definición de una función consiste en escribir la funcionalidad de la misma. Se construye el cuerpo de la función, el cual está formado por el conjunto de sentencias que definen lo que hace la función. También puede contener declaraciones de variables, las cuales serán locales a la función. Una función puede devolver un valor cuyo tipo se indica en la cabecera, el valor se devuelve por medio de la sentencia return, cuya sintaxis es: return[[(] expresión [)]]; Si no se especifica la expresión, la función no devolverá valor alguno (void). Ejemplo #2: Programa que define una función que calcula el logaritmo en base b (para b entero) de un número x. #include <stdio.h> #include <math.h> float logaritmo (float x, int b) { float logbase, resultado; logbase = log10(b); resultado = log10(x)/logbase; return resultado; } //Otra definición de la función logaritmo (más compacta) /*float logaritmo (float x, int b) { return log10(x)/log10(b); }*/ int main (void) { float y; y = logaritmo(128.0, 2); printf ("%f\n", y); return 0; }

Page 7: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

7

♦ DECLARACIÓN DE UNA FUNCIÓN: A la declaración de una función se le conoce como función prototipo. La intención del prototipo es darle a conocer al compilador el nombre de la función, el tipo de valor devuelto y los parámetros formales de la misma. El prototipo de una función, no define el cuerpo de la misma. Una función no puede ser llamada sin antes ser definida o declarada, esta regla tiene una excepción la cual se muestra a continuación: Ejemplo #3: Programa en C que suma dos números enteros implementando una función. //suma2.c #include<stdio.h> //Definición Función Suma int suma(int a, int b) { int res; res=a+b; return(res); } void main() { int n1,n2,res; printf("Sumando 1:"); scanf("%d",&n1); printf("Sumando 2:"); scanf("%d",&n2); res=suma(n1,n2); printf("%d + %d = %d\n",n1,n2,res); } Observe que la definición de la función se realiza antes de la llamada, si esto no es así, entonces es necesario declarar el prototipo de la función antes de que sea llamada. ♦ LLAMADA A UNA FUNCIÓN: Una función es sencillamente un conjunto de sentencias que se pueden llamar desde cualquier punto del programa. Cuando desde una parte del código se llama a una función, el control es pasado a la misma para su ejecución; al finalizar la ejecución de la función el control es devuelto al punto donde se realizo la llamada.

Page 8: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

8

En la siguiente figura se muestra como se llama una función: Cuando una función es llamada, esta recibe unos valores como argumentos conocidos como parámetros actuales. ♦ PASO DE PARÁMETROS A UNA FUNCIÓN: Cuando se hace una llamada a una función se pueden pasar valores a la misma a través de los parámetros actuales (argumentos). Existen dos formas de pasar los parámetros actuales a sus respectivos parámetros formales y estas son:

• Por valor • Por referencia

Para entender mejor que significa por valor o por referencia, vamos a recordar el concepto de variable, una variable en un programa es algo con un nombre, que contiene un valor que puede variar. El modo en que el compilador y el enlazador (linker) manejan esto es que asignan un bloque específico de la memoria dentro de la computadora para guardar el valor de una variable. Cuando una variable es declarada le informamos al compilador dos cosas, el nombre de la variable y el tipo de la variable. Por ejemplo, declaramos una variable de tipo entero llamada k al escribir: int k=2; Cuando el compilador encuentra la declaración de la variable “k” la agrega en una tabla de símbolos, en esa tabla a la variable se le asocian el valor de la variable y la correspondiente dirección de la memoria en donde se encuentra la variable. Entonces tiene sentido decir que hay dos valores asociados a la variable k, uno es el valor del entero alojado ahí y el otro es la dirección de la localidad de la memoria donde se ha guardado el valor entero. ♦ ÁMBITO DE UNA VARIABLE: Una variable posee un ámbito (accesibilidad) dentro de un programa, se entiende por ámbito de la variable a la parte del programa donde la variable puede ser referenciada por su nombre. Cuando una variable se declara fuera de todo el bloque (fuera de main) se dice que esa variable es global, una variable global existe y tiene valor desde el principio hasta el final de la ejecución del programa. Si la declaración de la variable se hace dentro de un bloque, el acceso queda limitado al bloque y a los bloques contenidos dentro de este. En este caso la variable recibe el nombre de local o automática, este tipo de variable existe y tiene valor desde donde se declara hasta donde termina el bloque.

Page 9: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

9

Ejemplo #4: En el siguiente ejemplo se muestra el modo de acceso (global o local) de una variable. /*Modo de uso de una variable*/ #include <stdio.h> int x = 15; //variable global void Funcion( void ); //Prototipo de la función int main() {

int x = 25; //variable local printf("\nEl valor de la variable local x es: %d", x); //Acceso a la variable local Funcion(); //Llamada a la función return 0;

} void Funcion(void) { printf("\nEl de la variable global x es: %d", x); //Acceso a la variable global } Salida:

La variable x definida dentro del bloque main es local al mismo, mientras que la variable x definida fuera de main es global a todo el programa y por ende se puede acceder a ella desde cualquier punto. Pasar un parámetro por valor, significa que los parámetros actuales se copiaran a sus respectivos parámetros formales; es decir, que al pasar un parámetro por valor su contenido se copia en la zona de memoria donde está ubicado el parámetro formal. Esta operación se realiza por defecto cuando se hace la llamada a la función, se debe de tener en cuenta que al pasar los parámetros por valor el contenido del parámetro actual no será modificado dentro de la función. Esto quiere decir que si el contenido del parámetro formal cambia el cambio no se refleja en el correspondiente parámetro actual. Ejemplo #5: Programa que muestra el paso de parámetros a una función. #include <stdio.h> void Intercambiar(int a, int b); //Prototipo de la función

Page 10: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

int main() {

int a=5, b=10; printf("\nValores antes de la llamada a=%d, b=%d", a, b); Intercambiar(a, b); printf("\nValores despues de la llamada a=%d, b=%d", a, b);return 0;

} void Intercambiar( int a, int b ) {

int aux = a; a = b; b = aux; printf("\nFuncion intercambiar a=%d, b=%d", a, b);

} En el ejemplo anterior se tiene una función Intercambiar que recibe (por valor) dos valores enteros, cuando se manda a llamar a la función de la forma Intercambiar(a, b), los contenidos de las variables a y b (parámetros actuales) son copiados en sus respeformales a y b respectivamente. variables a y b (parámetros formales de la función) son copias exactas de sus respectivos parámetros actuales y cualquier cambio a los valores dreflejados en sus parámetros actuales. Podemos apreciar mejor lo antes mencionado por medio de las siguientes figuras Memoria antes de llamar a la función

Todo cambio que se realice sobre los valores de las variables a y b de la función Intercambiar no se ven reflejados en los valores de las variables en la función main. Ejemplo #5.1: Programa que muestra el paso #include <stdio.h> //Prototipos de Funcionvoid unaFuncion(void); void otraFuncion(void);

DESCOMPOSICIÓN FUNCIONAL

10

nValores antes de la llamada a=%d, b=%d", a, b); Intercambiar(a, b); //Llamada a la función Intercambiar

nValores despues de la llamada a=%d, b=%d", a, b);

void Intercambiar( int a, int b )

n intercambiar a=%d, b=%d", a, b);

En el ejemplo anterior se tiene una función Intercambiar que recibe (por valor) dos valores enteros, cuando se manda a llamar a la función de la forma Intercambiar(a, b), los contenidos de las variables a y b (parámetros actuales) son copiados en sus respeformales a y b respectivamente. Esto quiere decir que dentro de la función Intercambiar las variables a y b (parámetros formales de la función) son copias exactas de sus respectivos parámetros actuales y cualquier cambio a los valores de los parámetros formales no se ven reflejados en sus parámetros actuales.

Podemos apreciar mejor lo antes mencionado por medio de las siguientes figuras

Memoria antes de llamar a la función a y b en la función Intercambiar son copias exactas de las variables a y b de la función main

Todo cambio que se realice sobre los valores de las variables a y b de la función Intercambiar no se ven reflejados en los valores de las variables en la función main.

Ejemplo #5.1: Programa que muestra el paso de parámetros a una función.

nes

DESCOMPOSICIÓN FUNCIONAL (I Parte)

//Llamada a la función Intercambiar

En el ejemplo anterior se tiene una función Intercambiar que recibe (por valor) dos valores enteros, cuando se manda a llamar a la función de la forma Intercambiar(a, b), los contenidos de las variables a y b (parámetros actuales) son copiados en sus respectivos parámetros

Esto quiere decir que dentro de la función Intercambiar las variables a y b (parámetros formales de la función) son copias exactas de sus respectivos

e los parámetros formales no se ven

Podemos apreciar mejor lo antes mencionado por medio de las siguientes figuras:

a y b en la función Intercambiar son de las variables a y b de

Todo cambio que se realice sobre los valores de las variables a y b de la función Intercambiar

de parámetros a una función.

Page 11: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

11

int variable; void main() { variable = 9; printf("El valor de variable es: %d\n", variable); unaFuncion(); otraFuncion(); printf("Ahora el valor de variable es: %d\n", variable); } void unaFuncion() {

printf("En la funcion unaFuncion, variable es: %d\n", variable); } void otraFuncion() {

variable++; printf("En la funcion otraFuncion, variable es: %d\n",variable);

} Salida:

♦ PASO DE PARÁMETROS POR REFERENCIA: Pasar un parámetro por referencia, significa que lo transmitido a la función no son los valores sino la dirección en memoria de las variable que contiene dichos valores. Al pasar los valores por referencia si se modifican los valores en los parámetros formales de la función, estos cambios se reflejan en los parámetros actuales. Cuando se pasa un valor por referencia, se pasa la dirección del parámetro actual a su correspondiente parámetro formal. Para ello se utiliza en operador de dirección (&) antes del nombre de la variable. Al momento de recibir un parámetro actual su correspondiente parámetro actual debe de ser un puntero, es decir que este debe de estar precedido del operador de indirección (*). Ejemplo #6: Programa que muestra el paso de parámetros por referencia a una función.

Page 12: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

#include <stdio.h> void Intercambiar( int *a, int *b ); int main() {

int a = 5, b = 10; printf("\nValores antes de la llamada a=%d, b=%d", a, b); Intercambiar(&a, &b); //printf("\nValores despues de la llamada a=%d, b=%d", a, b);return 0;

} void Intercambiar( int *a, int *b ) {

int aux = *a; *a = *b; *b = aux; printf("\nFunción intercambiar a=%d, b=%d", *a, *b);

} En el ejemplo se tiene una función Intercambiar que recibe las direcciones de memoria (referencias) de dos valores enteros, cuando se manda a llamar a la función de la forma Intercambiar (&a, &b), las direcciones de memoria de las variables a y b (parámetroactuales) son tomadas por sus respectivos parámetros formales a y b. dentro de la función Intercambiar las variables a y b (parámetros formales de la función) contienen las direcciones de memoria de sus respectivos parámetros actuales y cualquier cambio a los valores de los parámetros formales se ven ractuales. Podemos apreciar mejor lo antes mencionado por medio de las siguientes figuras Memoria antes de llamar a la fun

DESCOMPOSICIÓN FUNCIONAL

12

void Intercambiar( int *a, int *b );

nValores antes de la llamada a=%d, b=%d", a, b); Intercambiar(&a, &b); //Paso de parámetros por referencia

nValores despues de la llamada a=%d, b=%d", a, b);

void Intercambiar( int *a, int *b )

nFunción intercambiar a=%d, b=%d", *a, *b);

En el ejemplo se tiene una función Intercambiar que recibe las direcciones de memoria (referencias) de dos valores enteros, cuando se manda a llamar a la función de la forma

(&a, &b), las direcciones de memoria de las variables a y b (parámetroactuales) son tomadas por sus respectivos parámetros formales a y b. dentro de la función Intercambiar las variables a y b (parámetros formales de la función) contienen las direcciones de memoria de sus respectivos parámetros actuales y cualquier cambio a los valores de los parámetros formales se ven reflejados en sus parámetros

Podemos apreciar mejor lo antes mencionado por medio de las siguientes figuras

ar a la función a y b en la función poseen las direccionelas variables a y b de

DESCOMPOSICIÓN FUNCIONAL (I Parte)

arámetros por referencia

En el ejemplo se tiene una función Intercambiar que recibe las direcciones de memoria (referencias) de dos valores enteros, cuando se manda a llamar a la función de la forma

(&a, &b), las direcciones de memoria de las variables a y b (parámetros actuales) son tomadas por sus respectivos parámetros formales a y b. Esto quiere decir que dentro de la función Intercambiar las variables a y b (parámetros formales de la función) contienen las direcciones de memoria de sus respectivos parámetros actuales y cualquier

eflejados en sus parámetros

Podemos apreciar mejor lo antes mencionado por medio de las siguientes figuras:

a y b en la función Intercambiar direcciones de memoria de

y b de la función main

Page 13: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

13

♦ DIFERENCIAS ENTRE PASO DE VARIABLES POR VALOR Y POR REFERENCIA: Las reglas que se han de seguir cuando se transmiten variables por valor y por referencia son las siguientes: • Los parámetros valor reciben copias de los valores de los argumentos que se les pasan; la asignación a parámetros valor de una función nunca cambian el valor del argumento original pasado a los parámetros; • Los parámetros para el paso por referencia (declarados como punteros *p) reciben la dirección de los argumentos pasados; a estos les debe de preceder del operador &, excepto los arrays. En una función, las asignaciones a parámetros referencia (punteros) cambian los valores de los argumentos originales. Ejemplo #6.1: Programa que muestra el paso de parámetros a una función. #include <stdio.h> void FuncionSumaPorValor( int a, int b, int c ); void FuncionSumaPorReferencia( int a, int b, int *c ); int main() {

int a = 15, b = 20, c = 0; FuncionSumaPorValor( a, b, c ); //Pasando parámetros por valor printf("\nLa suma es: %d", c); FuncionSumaPorReferencia( a, b, &c ); //Pasando parámetro por referencia return 0;

} void FuncionSumaPorValor( int a, int b, int c ) {

c = a + b; } void FuncionSumaPorReferencia( int a, int b, int *c ) {

*c = a + b; }

Page 14: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

14

Ejemplo #6.2: Paso de parámetros a una función. #include <stdio.h> void DemostracionLocal(int valor); int main ( ) {

int n = 10; printf("Antes de llamar a DemoLocal, n = %d\n",n); DemostracionLocal (n); printf("Despues de llamada a DemoLocal, n = %d\n",n); return 0;

} void DemostracionLocal (int valor) {

printf ("Dentro de DemostracionLocal, valor = %d\n", valor); valor = 999; printf ("Dentro de DemostracionLocal, valor = %d\n", valor);

} Ejemplo #6.3: Paso de parámetros a una función. #include <stdio.h> void Incrementar(int *valor); int main ( ) {

int n = 10; printf("Antes de llamar a Incrementar, n = %d\n",n); Incrementar( &n ); printf("Despues de llamada a Incrementar, n = %d\n",n);

} void Incrementar(int *valor) {

(*valor)++; //Incrementa el valor en uno }

Page 15: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

15

♦ FUNCIONES DE USO COMÚN EN C:

o FUNCIONES PARA CONVERSIÓN DE DATOS: Estas funciones se encuentran en la librería stdlib.h. double atof( const char *cadena ); Convierte una cadena a valor double. int atoi( const char *cadena ); Convierte una cadena a valor entero. long atol( const char *cadena ); Convierte una cadena a valor long. char *fcvt(double valor, int decs, int *pdec, int *signo) Convierte un numero real a una cadena de caracteres, la función devuelve un puntero a la cadena de caracteres. char *ltoa( long valor, char *cadena, int base ); Sólo para MS-DOS. Convierte un valor a entero largo, devuelve un puntero a la cadena de caracteres. char *itoa(int valor, char *cadena, int base); Convierte un valor a entero a cadena de caracteres. Devuelve un puntero a la cadena de caracteres.

o FUNCIONES PARA CLASIFICACIÓN Y CONVERSIÓN DE CARACTERES: Estas funciones se encuentran en la librería ctype.h int isalnum(int c); Comprueba si c es una letra (A ± Z, a - z ) o dígito (0 ± 9). int isalpha(int c); Comprueba si c es una letra (A ± Z, a - z ). int isascii(int c); Comprueba si c es un carácter ascii (0 - 127). int isnctrl(int c); Comprueba si c es un carácter de control (0-31 y 127). int isdigit(int c); Comprueba si c es un dígito (0 - 9). int isgraph(int c); Comprueba si c es un carácter escribible exceptuando el espacio (33 - 126). int islower(int c); Comprueba si c es una letra minúscula.

Page 16: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

16

int isprint(int c); Comprueba si c es un carácter escribible (32 - 126). int ispunct(int c); Comprueba si c es un carácter de puntuación. int isspace(int c); Comprueba si c es un espacio en blanco (9 ± 13 o 32) . int isupper(int c); Comprueba si c es un carácter es mayúscula. int isxdigit(int c); Comprueba si c es un carácter hexadecimal. int toascii(int c); Convierte a c en un carácter ascii. int tolower(int c); Si es posible convierte a c en una letra minúscula. int toupper( int c); Si es posible convierte a c en una letra mayúscula. Todas las funciones descritas anteriormente devuelven un valor distinto de cero si se satisface la condición, en caso contrario devuelven cero.

o FUNCIONES MATEMÁTICAS EN C: Se muestra a continuación una lista de funciones matemáticas. Son fáciles de usar y algunas de ellas han sido ya usadas previamente. double acos(double x); Calcula el arco coseno de x. double asin(double x); Calcula el arco seno de x. double atan(double x); Devuelve el arco tangente en radianes. double atan2(double y, double x); Calcula el arco tangente de las dos variables x e y. Es similar a calcular el arco tangente de y/x, excepto en que los signos de ambos argumentos son usados para determinar el cuadrante del resultado.

Page 17: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

17

double ceil(double x); Redondea x hacia arriba al entero más cercano. double cos(double x); Devuelve el coseno de x, donde x está dado en radianes. double cosh(double x); Devuelve el coseno hiperbólico de x. double exp(double x); Devuelve el valor de e (la base de los logaritmos naturales) elevado a la potencia x. double fabs(double x); Devuelve el valor absoluto del número en punto flotante x. double floor(double x); Redondea x hacia abajo al entero más cercano. double fmod(double x, double y); Calcula el resto de la división de x entre y. El valor devuelto es x - n * y, donde n es el cociente de x / y. long int labs(long int j); Calcula el valor absoluto de un entero largo. double ldexp(double x, int exp); Devuelve el resultado de multiplicar el número x por 2 elevado a exp (inversa de frexp). double log(double x); Devuelve el logaritmo natural o neperiano de x. double log10(double x); Devuelve el logaritmo decimal de x. double modf(double x, double *iptr); Divide el argumento x en una parte entera y una parte fraccional. La parte entera se guarda en iptr. double pow(double x, double y); Devuelve el valor de x elevado a y. double sin(double x); Devuelve el seno de x. double sinh(double x); Regresa el seno hiperbólico de x.

Page 18: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

18

double sqrt(double x); Devuelve la raíz cuadrada no negativa de x. double tan(double x); Devuelve la tangente de x. double tanh(double x); Devuelve la tangente hiperbólica de x.

EJERCICIOS RESUELTOS:

Ejemplo #7: Programa que calcula el cubo de los números desde 1 hasta N utilizando una función definida por el usuario. #include <stdio.h> int cubo(int base); void main() {

int numero,limite; printf("Cubo de los numeros de 1..."); scanf("%d",&limite); for(numero=1; numero<=limite; numero++)

printf("El cubo del numero %d es %d\n", numero, cubo(numero)); }

//Definición de la función cubo int cubo(int base) {

int cubo; cubo = base*base*base; return(cubo);

}

Ejemplo #8: Realizar una función llamada par, que toma un número entero como parámetro, y devuelve 1 si es par o devuelve 0 si es impar. #include<stdio.h> int par(int); void main() { int numero, resultado; printf("Introduzca un número:\n"); scanf("%d",&numero); //Llamada a la función par resultado = par(numero); if( resultado==1 ) printf("Es par.\n"); else printf("Es impar.\n");

Page 19: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

19

return(0); }

/* Función par: Devuelve un valor indicando si un número entero es par o no. */ int par(int numero) { if( (numero%2)==0 ) return(1); else return(0); } Ejemplo #9: Realizar una función llamada bits, que toma un número entero como parámetro, y devuelve el número de bits que tiene dicha cantidad. #include <stdio.h> int bits(unsigned int num) { int b = 0; do { b++; num /= 2; } while (num > 0); return b; } int main(void) { unsigned int numero ; int bitsnumero; printf ("Introduce un entero positivo: "); scanf ("%d", &numero ); bitsnumero = bits(numero); printf ("Hay %d bits en %d.\n", bitsnumero,numero); return 0; } Ejemplo #10: Realizar una función llamada media, que toma dos números reales como parámetros, y devuelve un número real que es la media de los dos números pasados como parámetros. #include<stdio.h> float media(float n1, float n2);

Page 20: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

20

int main() {

float n1, n2, resultado; printf(“Introduzca un número real:\n”); scanf(“%f”,&n1); printf(“Introduzca otro número real:\n”); scanf(“%f”,&n2); resultado=media(n1,n2); printf(“La media es: %f.\n”,resultado); return(0);

} // Función media: Devuelve la media de 2 números. float media(float n1, float n2) {

float resultado; resultado=(n1+n2)/2; return(resultado);

} Ejemplo #11: Programa en C que define una función llamada factorial y recibe como parámetro un número entero positivo e imprime su factorial. #include <stdio.h> #include <stdlib.h> long int factorial(int numero); void main() {

long int num, resultado; printf("Introduzca un numero:\n"); scanf("%d",&num); resultado=factorial(num); printf("!%d = %ld\n",num,resultado);

} long int factorial(int num) { long int fact = 1,f; for(f=1;f<=num;f++) fact*=f; return(fact); }

Page 21: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

21

Ejemplo #12: Programa en C que define una función para encontrar cuál es el mayor de dos números. #include <stdio.h> int maximo (int x, int y) { if (x>y ) return x ; else return y ; } void main () { int a,b; int max; printf ("Introduzca dos numeros: \n"); scanf ("%d %d",&a,&b); max = maximo(a,b); printf ("Entre %d y %d el MAYOR es: %d\n",a,b,max); }

Page 22: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

22

EJERCICIOS PROPUESTOS:

1. Diseñe un Programa en C que contenga una función llamada primo que reciba como parámetro un numero entero positivo. Retorne 1 si en número es primo de lo contrario retorne 0. Nota: Los números primos sólo son divisibles por el mismo y por la unidad.

2. Diseñe un programa con una función llamada potencia, que dada una cifra

entera positiva, sea elevada a una potencia introducida por el usuario, la función recibirá 2 parámetros enteros y retornara el resultado de la operación. (Ejemplo: 5^2=25).

3. Escribir una función en C que cuente el número de ocurrencias de cada vocal (tanto si es mayúscula como minúscula) en una cadena de caracteres y los muestre por pantalla.

4. Crear un programa que calcule las 2 soluciones de una ecuación cuadrática del tipo ax2+bx+c.

5. Escribir una función que imprima por pantalla una pirámide como la de la figura:

El prototipo de la función es: void Piramide(int altura);

6. Escribir un programa en C que defina una función que tome un valor entero y

devuelva el número de dígitos que tiene dicha cantidad.

7. Realice un programa que imprima la suma de la siguiente serie implementando funciones.

1 2 3 4

1 ...1! 2! 3! 4! !

nx x x x x

n+ + + +

8. Realice un programa en C que implemente una función la cual determine si un carácter que será pasado como parámetro es una letra(A…Z, a…z), un dígito o cualquier otro carácter (que no sea ni letra ni número). El prototipo de la función es: void VerificarCaracter(char c);

Page 23: DESCOMPOSICIÓN FUNCIONAL (I Parte)€¦ · DESCOMPOSICIÓN FUNCIONAL (I Parte) 5 ♦ DIRECTRIZ DE SUSTITUCIÓN #define Mediante la directriz #define identificador valor se indica

DESCOMPOSICIÓN FUNCIONAL (I Parte)

23

BIBLIOGRAFÍA BÁSICA:

♦ Ceballos, Francisco Javier: C/C++ Curso de Programación, 2da Edición. Editorial RA-MA, 2002.

♦ Joyanes Aguilar, Luis; Zahonero Martínez Ignacio: Programación en C. McGraw Hill, 2001.

♦ Gottfried, Byron S: Programación en C. McGraw Hill, 1991.