viernes, 8 de abril de 2011

Capitulo 9. Procedimientos y Funciones

Fuente:
Programación en C++ / Principios y Aplicaciones (resumen)
Carlos Romero Shollande

1.        Introducción

Una estrategia para la solución de problemas complejos reales con computadoras consiste en dividirlos en problemas más pequeños, llamados subproblemas.
Un subproblema puede ser, a su vez, dividido repetidamente en problemas más pequeños, hasta que los problemas más pequeños sean consistentes.
Cada subproblema debe ser independiente de los restantes y se le denomina módulo.
La técnica de dividir un problema en subproblemas se denomina refinamiento sucesivo, diseño descendente o diseño modular, debido a que se comienza en la parte superior de un problema principal y luego se diseñan soluciones especificas para sus subproblemas.

1.1.  Programa Principal

El problema principal se soluciona con un programa denominado programa principal (main), también llamado conductor del programa.
Este programa describe la solución completa del problema y consta de llamadas a subprogramas.
Las llamadas son indicaciones al procesador de que debe continuar la ejecución en el subprograma llamado, regresando al punto de partida una vez haya concluido.
El programa principal puede contener, además, sentencias básicas, selectivas y repetitivas, que son ejecutadas de modo inmediato por el procesador.
El programa principal contendrá pocas líneas, y en el se verán claramente los diferentes pasos del proceso que se han de seguir para la obtención del resultado deseado.

1.2.  Subprogramas

Los subproblemas (módulos) se solucionan mediante declaraciones de subprogramas, ubicados en lugares distintos al del programa principal.
Su estructura coincide básicamente con la de un programa; en consecuencia, un subprograma puede tener sus propios subprogramas.
El objetivo de un subprograma consiste en resolver de modo independiente una parte del problema.
A veces los subprogramas se repiten varias veces en diferentes lugares del programa; en este caso el conjunto de sentencias a repetir aparecerán una sola vez.
Un subprograma es ejecutado sólo cuando es llamado por el programa principal o por otro subprograma.

-       Los subprogramas permiten romper un programa en unidades lógicas discretas, de forma que cada una de ellas puede ser escrita y corregida de un modo más fácil que un programa completo (sin subprogramas), e incluso por programadores diferentes.
-       Los subprogramas utilizados por un programa pueden ser utilizados por otros programas y se pueden crear librerías de funciones y procedimientos.
-       Los subprogramas acortan los programas (si es que el subprograma se utiliza más de una vez), ya que sólo será preciso escribir una sola vez las correspondientes instrucciones, y cada vez que se desea realizar una tarea, el subprograma se encargará de esa operación

Gráfica 1. Diseño descendente del problema principal y programación del programa principal


2.        Variables de los Subprogramas

Al usar subprogramas nos encontramos con cuatro tipos de variables:

2.1.  Variables Locales

En el concepto más amplio, las variables locales son las que se declaran dentro de un bloque de código, y como un subprograma es un bloque discreto de código, se puede concluir que las variables que son locales a un subprograma son simplemente un caso especial del concepto general.
Las variables locales existen sólo durante la ejecución del bloque de código en el que se declaran; es decir, una variable local se crea al entrar en su bloque y se destruye después de salir.
Así las variables locales no son conocidas fuera de su propio bloque de código y no pueden retener sus valores entre llamadas. Ejemplo:

void alfa()      {
            int j;         // j es variable local de alfa()
            j = 77;  }
void beta()      {
            int j;        // j es variable local de beta()
            j = -66; }

La j se declara dos veces, una en alfa() y otra en beta().
La j en alfa() no tiene relación con la j de beta(), ya que cada j es conocida sólo por el código que esta en el bloque que la declaró.
La ventaja de declarar un variable local en un bloque es que se asignará memoria a la variable sólo si es necesario

2.2.  Variables Globales

Las variables globales son las variables que se conocen a través de todo el programa y se pueden usar en cualquier bloque de código.
Se pueden crear variables globales declarándolas fuera de cualquier subprograma.
Un subprograma puede acceder a ellas sin tener en cuenta en que lugar este dicha expresión.
Ejemplo:
#include <iostream.h>
int i;                            // Variable global a todo el programa
void beta()    {
            int i;                 // Variable local a beta()
            for(i=1; i<10; i++) cout<<“ . “;
            }
void alfa()    {
            beta();              // Llamada a beta()
            cout<<“El contador es: “<<i;
            }
main()   {
            i = 230;            alfa();
            }

Aunque ni main(), ni alfa() tienen declarada la variable i, ambas se usan.
Sin embargo, beta() ha declarado una variable local llamada i.
Cuando se referencia i, beta() referencia sólo a su variable local, no a la global.
En conclusión, si una variable local y una global tienen el mismo nombre, todas las referencias a ese nombre de variable, dentro del subprograma en el que se declara como local, se referirá a la local y no afectara a la variable global.
Debe evitarse el uso de variables globales, por tres razones:

-       Ocupan memoria durante toda la ejecución del programa y no sólo cuando se necesitan.
-       El uso de una variable global en lugar de una local, restringirá la generalidad de un subprograma ya que depende de una variable que debe definirse fuera de sí misma.
-       El uso de una serie grande de variables globales puede conducir a errores con efectos laterales desconocido e indeseables.

2.3.  Parámetros Actuales o Reales

Los parámetros actuales son las variables de enlace definidas en el programa principal y que se usan como argumentos dentro de los paréntesis que posee una llamada a un subprograma.

Ejemplo:
main()   {
            char v[20], w[20];
            cout<<”Nombre:”; cin>>v
            cout<<”Apellido:”; cin>>w;
            centro(v, w);    //v y w son parámetros actuales
            }

2.4.  Parámetros Formales o Ficticios

Los parámetros formales son las variables de enlace definidas en la entrada de un subprograma, que aceptan los valores de los parámetros actuales que se usan en la llamada al subprograma y se comportan como otras variables locales.

Ejemplo:
void centro(char *p, char *q)  {         // p y q son P. Formales
            int r, t, x, y;
            r = strlen(p);  x = (79 - r) / 2;
            t = strlen(q);  y = (79 - t) / 2;
            gotoxy(x, 11); cout<<p:
            gotoxy(y, 13); cout<<q;
            }

El subprograma centro tiene dos parámetros formales tipo cadena de caracteres (p y q), en la llamada se puede ver que también existen dos parámetros actuales tipo cadena de caracteres (v y w).
Finalmente se observa que v corresponde a p y w corresponde a q.
En conclusión, los parámetros formales, deben ser semejantes en número, orden y tipo con los parámetros actuales.

3.        Métodos para Diseñar Programas

Existen dos métodos para diseñar subprogramas: procedimientos y funciones. La diferencia esencial entre un procedimiento y una función es que la función obtiene un valor que puede ser utilizado en una expresión, mientras que un procedimiento no tiene ningún valor asociado a su nombre.
Una función puede emplearse en lugar de una variable y el usuario la puede utilizar para crear operaciones nuevas que no están incluidas en las librerías estándar del C++.
Un procedimiento normalmente se utiliza para estructurar un programa y para mejorar la claridad y generalidad.

3.1.  Procedimientos

Un procedimiento es un subprograma que realiza una tarea específica. Esta compuesto por un grupo de sentencias a las que se les asigna un nombre (identificador), y que van a ser ejecutadas como un programa cada vez que se invoca dicho nombre.

3.1.1.      Llamada a un Procedimiento

Sintaxis       :   nombre_procedimiento (parámet_actuales);
Propósito    :   Llamar desde el programa principal o desde otro procedimiento a un procedimiento requerido por su nombre.
Ejemplo      :   leer(m, precios);

En las llamadas a procedimientos se aplica el método denominado: llamada por referencia, que consiste en copiar la dirección de cada parámetro actual en un parámetro formal.

3.1.2.      Declaración de un Procedimiento

Sintaxis      : void nombre_procedim (parám_formals)  {
                        Variables locales
                        Líneas de código de cuerpo de procedimiento
                        }
Propósito    : Declarar un procedimiento indicando nombre y especificando que es un subprograma sin valores de retorno (void). Así mismo, declarar la lista de parámetros formales involucrados en el procedimiento. Es decir, especificar los nombres de tipos y nombres de variables, separados por comas. Estos parámetros son los que reciben valores de los parámetros actuales en la llamada.
Ejemplo     : void reportar (int n, float lista[20])  {
                        int i;              // Definición de variables locales
                        for(i=1;i<=n;i++) cout<<lista[i];
                        // Cuerpo del procedimiento
                        }

Los procedimientos terminan y vuelven automáticamente a la siguiente línea de la sentencia que los llamó en el programa principal, cuando se encuentre con la última llave.
Si un procedimiento carece de parámetros formales, entonces la lista de parámetros estará vacía; pero incluso en este caso se precisan de los paréntesis.
A diferencia de las declaraciones de variables en el programa principal, en las que se pueden declarar, con un solo nombre de tipo, muchas variables separadas por comas.
En la lista de declaraciones de parámetros formales, cada parámetro debe incluir tanto el tipo variable como el nombre, adquiriendo la siguiente sintaxis:

void nomb_proced (tipo1 var1, tipo2 var2,…,tipoN varN)

El siguiente ejemplo tiene una definición incorrecta:

void humos(int s, i, n, float k, r)

La definición correcta es la siguiente:

void humos(int s, int i, int n, float k, float r)

3.1.3.      Retorno de un Procedimiento

El retorno desde un procedimiento al programa principal se produce después que la computadora ejecuta la última sentencia del procedimiento y encuentra al finalizador del procedimiento (}).
En el ejemplo anterior, después de que el procedimiento reporta los valores del vector lista[i], no le queda más que hacer, de manera que vuelve al programa principal, a la siguiente línea de la que la llamó.
Dado que el procedimiento no devuelve ningún valor, se declara como si fuese void.

Gráfica 2. Llamando y retornando de un procedimiento


3.2.  Funciones

Una función es un subprograma que recibe los valores de uno o varios argumentos y devuelve un único resultado al programa o subprograma que lo llamó.
Está formado por una o más sentencias que realizan una tarea determinada.
Cuando se ejecuta la función el resultado es asignado al nombre de la función.
Siempre se utiliza una llamada a una función en una expresión.

3.2.1.      Llamada a una Función

Sintaxis     : variable = nomb_función (parámt_actuales);
Propósito   : Llamar desde el programa principal o desde algún procedimiento a una función requerida por su nombre.
Ejemplo     : y = acumulativa (m, x);

En el caso de llamadas a funciones se aplica el método denominado: llamada por valor, que consiste en copiar el valor de cada parámetro actual en un parámetro formal de la función.
Por lo tanto, los cambios que se hacen a los parámetros formales no tienen efecto en los parámetros actuales. Ejemplo:

main()    {
                        int k = 15;
                        cout<<sum(k)<<k;
                        }
            int sum(int z)     {
                        z = z + z;
                        return(z);         }

Esta función copia el valor del parámetro actual k a sum(), en el parámetro formal z.
Cuando tiene lugar la asignación z = z + z, lo único que se modifica es la variable local z. La variable k, usada para llamar a sum(), todavía tendrá el valor 15.
La salida de la función será 30.

3.2.2.      Declaración de una Función

Sintaxis     : tipo nomb_función (parámetros_formales)  {
                        Variables locales
                        Líneas de código del cuerpo de la función    }
Propósito   : Declarar una función indicando su nombre y especificando el tipo de valor que la función devolverá. Así mismo, declarar la lista de parámetros formales involucrados en la función. Es decir, especificar los nombres de tipos y nombres de variables separados por comas. Estos parámetros son los que recibirán los valores de los parámetros actuales cuando se llame a la función.
Ejemplo    : float acumulativa (int n, float k[30]) 
                        int i, flota s=0;    // Variables locales
                        for(i=1; i<=n; i++) s=s+k[i];  // Cuerpo función
                        return(s);    }

El valor de la función puede ser de cualquier tipo válido; si no se especifica, se asume que por defecto la función devolverá un valor entero.
Si una función carece de parámetros, entonces la lista de parámetros estará vacía; pero incluso en este caso se precisan de los paréntesis.
En las funciones, la declaración de parámetros formales es semejante a la que se hace en los procedimientos:

tipo nomb_función (tipo1 var1, tipo2 var2,..., tipoN varN)

3.2.3.      Retorno desde una Función

Sintaxis     : return expresión;
Propósito   : Devolver un valor desde una función y provocar que el programa en su ejecución salga de la función en la que está y retome de inmediato al código que llamó a dicha función.
Ejemplo     : return(s);

Las funciones que devuelven valores son de tres tipos:

-       Funciones que realizan específicamente operaciones sobre sus parámetros actuales y devuelven un valor basado en ese cálculo. Ejemplo: las funciones de biblioteca como tan() que devuelve la tangente de un ángulo en radianes.
-       Funciones que manipulan información y devuelven un valor que indica si esta manipulación salió bien o falló. Ejemplo: la función fwrite() que se usa para escribir datos sobre un archivo de disco. Si tiene éxito la escritura, entonces fwrite() devolverá el número de bytes que se pidió que escribiera, cualquier otro valor indicará que ha ocurrido un error.
-       Funciones que no tienen un valor de retorno explícito. En esencia, la función es estrictamente procesal y no produce un valor. Si no se especifica una asignación, entonces la computadora simplemente descarta el valor devuelto.
Ejemplo:

main()  {
int h, j, k;
h = 9;   j = 5;
k = resto(h, j);             // Línea 1
cout<<resto(h, j);         // Línea 2
resto(h, j);                   // Línea 3
}

int resto(int p, int q)     {
return p % q;
}

La línea 1 asigna el valor devuelto por resto() a k. En la línea 2, el valor devuelto no está realmente asignado, sino que cout lo usa. Y en la línea 3, el valor devuelto se pierde porque no lo asigna a otra variable, ni la usa como parte de una expresión.
Una función no puede ser objeto de una asignación. Por ejemplo la siguiente sentencia es incorrecta:

Suma(x, y) = 350;

4.        Llamada a Subprogramas con Arreglos

Cuando se usa a un arreglo como un parámetro actual, se pasa sólo la dirección del arreglo al subprograma y no se copia el arreglo completo.
Es decir, que cuando se llama a un subprograma con un nombre de arreglo, la declaración de parámetros debe ser de un tipo puntero, dirigido al primer elemento del arreglo del subprograma.
Hay tres formas de declarar este tipo de parámetro:

-       Declarándolo como un arreglo.
-       Especificando el parámetro como un arreglo sin tamaño
-       Declarándolo como un puntero

a)        Declarándolo como un arreglo.

Ejemplo:
main()     {
int q[20], j;
for(j=0; j<20; j++) q[j] = j;
reporte(q);     }

reporte(int x[20])        {
int j;
for(j=0; j<20; j++) cout<<x[j]);    }

Aunque este programa declare al parámetro x como un arreglo de veinte elementos enteros, el C++ convertirá automáticamente x a un puntero entero.

b)        Especificando parámetro como un arreglo sin tamaño.

Ejemplo:
reporte(int x[])    {
int j;
for(j=0; j<20; j++) cout<<x[j]);
}

Este código declara a x como un arreglo de enteros de tamaño desconocido.
Este método de declaración también define a x como un puntero entero.

c)        Declarándolo como un puntero.

Ejemplo:
reporte(int *x)   {
int j;
for(j=0; j<20; j++) cout<<x[j]);
}

Los tres métodos de declaración de un parámetro de arreglo dan el mismo resultado: un puntero.
Pero la forma más común en los programas escritos profesionalmente, es el tercero.

5.        Prototipos de Subprogramas

Sintaxis     : tipo nombre_subprog(tipo1 par1, tipo2 par2,..., tipoN parN);
Propósito   : Definir el nombre de un subprograma antes de usarlo y el tipo de dato que este devuelve. Declarar número, tipos y orden de parámetros formales que el subprograma espera recibir. Definición de prototipos es obligatoria cuando subprograma se declara después del programa principal o del subprograma que lo llamó. En caso contrario, esta definición es obviada. El compilador usa prototipos de subprogramas para validar las llamadas de subprogramas.
Ejemplo     : int equipo(int, int, float);

Los tipos de datos que están entre paréntesis le informa al compilador que el subprograma equipo espera que el invocador le devuelva dos valores enteros y uno flotante.
El tipo de dato (int) a la izquierda del nombre del subprograma le informe al compilador que equipo le devuelve un resultado entero al invocador.
En el caso de que uno de los parámetros formales del subprograma sea arreglo, este se puede definir de 2 formas:
En forma subíndicada, por ejemplo:

int estrategia(int x[20], int);

En forma de puntero, por ejemplo:

int estrategia(int *, int);

6.        Tipos de Subprogramas

Existen dos tipos de subprogramas:

-       Subprogramas internos, son los subprogramas que figuran junto con el programa principal (en el mismo listado).
-       Subprogramas externos, son los subprogramas que figuran físicamente separados del programa principal, es decir, en distintos archivos fuente.

Pueden ser compilados separadamente y generalmente se enlazan con el programa principal en la fase de montaje, cuando ya son módulos objeto, es decir, traducidos a lenguaje de máquina.
Los archivos de estos subprogramas pueden ser incluidos en el encabezamiento del programa principal usando la siguiente sintaxis:

#include <unidad: \ ruta \ nombre_archivo . extensión>

Por ejemplo:
#include <c: \ borlandc \ bin \ estadistica . h>

Esta directiva incluye a todos los subprogramas que han sido salvados previamente en el archivo denominado estadistica.h que se encuentra en la ruta borlandc\bin de la unidad C:

7.        Atributos de Identificadores de Subprogramas

En los capítulos anteriores hemos utilizado identificadores para los nombres de las variables, los atributos de estos identificadores incluyen: nombre, tipo, tamaño y valor.
En este capítulo también utilizamos identificadores como nombres de subprogramas definidos por el usuario. De hecho, los identificadores de los subprogramas tienen otros atributos, tales como: clase de almacenamiento, alcance y enlace.

7.1.  Clase de Almacenamiento

La clase de almacenamiento del identificador determina el periodo durante el cual existe en memoria dicho identificador.
Algunos identificadores existen durante un periodo breve, otros se crean y destruyen repetidamente y otros existen durante toda la ejecución del programa.
Los especificadores de clase de almacenamiento pueden dividirse en:

-       Clase de almacenamiento automático.
-       Clase de almacenamiento estático

7.1.1.   Clase de Almacenamiento Automático

Sintaxis     : auto tipo nombre_variable;
Propósito   : Declarar variables de clase de almacenamiento automático.
Ejemplo     : auto float r, t;

Las variables locales y los parámetros de una función normalmente son de esta clase.
De manera predeterminada, las variables locales son de la clase de almacenamiento automático por lo que pocas veces se utiliza la palabra clave auto.
Esta clase es un medio eficiente para conservar memoria sólo cuando se necesita, ya que existen mientras el bloque está activo y se destruyen al salir de él.

Sintaxis     : register tipo nombre_variable;
Propósito   : Sugiere al compilador que mantenga a una variable automática en uno de los registros de hardware, que son de alta velocidad, en lugar de en memoria.
Ejemplo     : register int k=1;

Las variables de uso intensivo (contadores), pueden mantenerse en registros de hardware, con lo cual es posible eliminar la sobrecarga
La palabra clave register sólo puede utilizarse con variables y parámetros de funciones locales.
Frecuentemente estas declaraciones son innecesarias.

7.1.2.   Clase de Almacenamiento Estático

Sintaxis     : extern tipo nombre_variable;
Propósito   : Declarar variables y nombres de funciones globales. Las variables globales se crean poniendo declaraciones de variables fuera de todas las definiciones de funciones.
Ejemplo     : extern float x;

Las variables y funciones de esta clase existen desde el momento en que se inicia la ejecución del programa.
Sin embargo, aunque las variables y los nombres de función existan desde el inicio de la ejecución, esto no significa que puedan utilizarse en todo el programa.
Generalmente se usan para declarar variables globales.

Sintaxis     : static tipo nombre_variable;
Propósito   : Declarar variables locales que son conocidas solo en la función en la que se define; pero, a diferencia de las variables automáticas, estas variables locales conservan sus valores al salir de la función. La siguiente vez que se llama a la función, las variables locales static contendrán valores que tenían al salir de ella la última vez.
Ejemplo    : static int w=3;

Todas las variables numéricas de la clase de almacenamiento estático se inicializan a cero si el programador no las inicializa a un valor explícito.

7.2.  Alcance

El alcance de un identificador es la parte del programa en la que un identificador tiene significado.
Ejemplo, cuando se declara una variable local en un bloque, se puede referenciar sólo en dicho bloque o en bloques anidados dentro de él.

-       Alcance de archivo. En este tipo de alcance los identificadores son “conocidos” por todas las funciones desde el momento en que se declara el identificador hasta el final del archivo. Para ello, los identificadores deberán ser declarados fuera de cualquier función. Las variables globales, las definiciones de funciones y los prototipos de función colocados fuera de una función tienen este alcance.
-       Alcance de función. En este tipo de alcance los identificadores pueden usarse en cualquier parte de la función en la que aparezcan, pero no pueden referenciarse desde fuera del cuerpo de la función. Los únicos identificadores de este tipo son las etiquetas. Las etiquetas sirven en las estructuras switch y en las instrucciones goto.
-       Alcance de bloque. Este tipo de alcance comienza con la declaración del identificador dentro de un bloque y termina con la llave de terminación del bloque ( } ). Tienen este tipo de alcance las variables locales declaradas al inicio de una función y los parámetros formales de función. Si un bloque es anidado y un identificador de un bloque externo tiene el mismo nombre que un identificador de un bloque interno, se “oculta” el identificador del bloque externo hasta que termina el bloque interno. 
Alcance de prototipo de función. Este tipo de alcance tiene como únicos identificadores a aquellos que se usan en la lista de parámetros de un prototipo de función. Los prototipos de función no requieren nombres en la lista de parámetros, sólo se necesitan los tipos. Si se indica un nombre en la lista de parámetros de un prototipo de función, el compilador lo ignora. Los identificadores usados en los prototipos

Ejemplo:
Ingresar el número de elementos de dos vectores (M y N), así como cada uno de los elementos de los vectores que definen a la variable independiente X(i) y a la variable dependiente Y(j); usar en este caso el procedimiento Ingreso(). Si el número de elementos de ambos vectores son iguales, calcular la intersección de la recta con la ordenada (A) y la pendiente (B) usando el método de los mínimos cuadrados (análisis de regresión). Luego ingresar el valor de un dato correspondiente a la variable independiente y determinar el pronóstico respectivo. En caso contrario, calcular la suma de los elementos de cada vector. Usar procedimientos y funciones.

Análisis:
La pendiente de la recta (B) se calcula utilizando la siguiente expresión estadística:

 



La intersección con la ordenada (A) se calcula usando la siguiente expresión estadística:

 



La ecuación del pronóstico es la siguiente:

Y = A + B X

Codificación:
#include <iostream.h>      // Regresión lineal
#include <conio.h>
#define LIM 10
int x[LIM];                        // Elementos del vector de la variable independiente
int y[LIM];                        // Elementos del vector de la variable dependiente
void main()     {
void ingreso(int, int *, char *);
int suma(int, int *);
long int sumaxy(int, int *, int *);
long int sumax2(int, int *)
int m;                                 // Tamaño del vector de la variable independiente
int n;                                   // Tamaño del vector de la variable dependiente
int p;                                   // Suma de elementos de la variable independiente
int q;                                   // Suma de elementos de la variable dependiente
long int r;                            // Suma de productos de los elementos de ambos vectores
long int t;                            // Suma de cuadrados de la variable independiente
float a;                                 // Intersección con la ordenada
float b;                                 // Pendiente de la recta
float v;                                 // Valor de variable independiente a pronosticar
float w;                                // Valor de pronóstico de variable dependiente
clrscr();
gotoxy(10,2); cout<<"Número de elementos del primer vector : ";
gotoxy(51,2); cin>>m;
gotoxy(10,4); cout<<"Número de elementos del segundo vector: ";
gotoxy(51,4); cin>>n;
ingreso(m, x, "Elementos del primer vector: ");
ingreso(n, y, "Elementos del segundo vector: ");
if(m==n)     {
p=suma(m, x);  q=suma(m, y);  r=sumaxy(m, x, y);  t=sumax2(m, x);
b=(float) (m*r-p*q)/(m*t-p*p);  a=(q/m)-b*(p/m);
clrscr();
gotoxy(10,2);  cout<<"Línea recta";
gotoxy(10,5); cout<<"Intersección con la ordenada    : "<<a;
gotoxy(10,7); cout<<"Pendiente                       : "<<b;
gotoxy(10,10); cout<<"Valor de variable independiente : ";  cin>>v;
w=a+b*v;
gotoxy(10,12); cout<<"Pronóstico                      : "<<w;    }
else  {
p=suma(m, x);   q=suma(n, y);
clrscr();
gotoxy(10,2);  cout<<"Suma de elementos";
gotoxy(10,5); cout<<"Primer vector  : "<<p;
gotoxy(10,7); cout<<"Segundo vector : "<<q;    }
getch();
}
void ingreso(int n, int x[LIM], char mensaje[15])    {
register int i;                            // Subíndice de la variable independiente o dependiente
clrscr();  gotoxy(10,2);  cout<<mensaje;
for(i=1;i<=n;i++)     {
gotoxy(10,3+i); cout<<"Ingrese elemento "<<i<<": ";
gotoxy(38,3+i); cin>>*(x+i);    }
}
int suma(int k, int x[LIM])     {
register int i;                            // Subíndice de la variable independiente o dependiente
int s=0;                                    // Suma de los elementos del vector
for(i=1;i<=k;i++) s=s+*(x+i);
return(s);
}
long int sumaxy(int k, int x[LIM], int y[LIM])    {
register int i;                            // Subíndice de las variables independiente y dependiente
int s=0;                                    // Suma de los productos de los elementos de ambos vectores
for(i=1;i<=k;i++) s=s+*(x+i)**(y+i);
return(s);
}
long int sumax2(int k, int x[LIM])    {
register int i;                            // Subíndice de las variables independiente y dependiente
int s=0;                                    // Suma de los cuadrados de los elementos del vector independiente
for(i=1;i<=k;i++) s=s+*(x+i)**(x+i);
return(s);
}

No hay comentarios:

Publicar un comentario