Un principio ampliamente difundido e importante para
resolver problemas es el de “dividir para reinar”, es decir separar el problema
en partes, en problemas más pequeños, para así enfrentarlos y resolverlos en un
tamaño más accesible y fácil de manejar. Este principio tiene una directa
aplicación en la programación de computadoras, para lo cual muchos lenguajes de
programación cuentan con una característica adecuada: la modularidad. Estos
lenguajes permiten escribir programas compuestos de porciones o partes que se
conocen como módulos, muchas veces nombrados también como subprogramas,
subrutinas, procedimientos, funciones, entre otros. En todos los casos, los
principios generales y elementales que los gobiernan son los mismos, aún cuando
algunos tengan características distintas y mayores o menores prestaciones:
todos permiten separar un programa en partes más pequeñas y reusar esos trozos
de programa o módulos ya escritos para resolver problemas similares.
Un módulo de programa tiene dos partes bien diferenciadas:
la definición del módulo y la invocación o llamada al módulo. La definición de
un módulo es donde se dice qué es lo que el mismo hará, es decir, cuáles serán
sus efectos al ser invocado, es decir cuando se ejecute. Una invocación o
llamada ocurre cuando se usa el módulo. En el punto del programa donde se hace
la invocación al módulo es donde, en tiempo de ejecución del programa, se
ejecutarán las acciones comprendidas en la definición del módulo.
En un programa,
por cada módulo, habrá una única definición, ya que bastará con una vez para
decirse qué es lo que el módulo hace. Sin embargo, puede haber más de una
invocación al mismo, ya que una solución puede usarse tantas veces como sea
necesario.
2.1- TIPOS DE
FUNCIONES: INTERNAS Y CREADAS POR EL USUARIO
Funciones internas
El intérprete de
Python cuenta con funciones internas que siempre se hallan disponibles. Se
muestran a continuación, en orden alfabético.
__import__ (name[, globals[, locals[, fromlist]]])
Esta función es llamada por la sentencia import.
Existe con el propósito principal de reemplazarla con otra función compatible
en interfaz, para hacer posible cambiar la semántica de la
sentencia import. Consultar los módulos de biblioteca
estándar ihooks y rexec si se desea ver por qué y cómo
hacer esto. Consultar también el módulo interno imp, que define ciertas operaciones útiles
para construir una función __import__() propia.
Por ejemplo, la sentencia `import spam' causa la siguiente
llamada: __import__('spam', globals(), locals(), []); la
sentencia from spam.jamon import huevos resulta
en __import__('spam.jamon', globals(), locals(), ['huevos']).
Hay que ver que, a pesar de que se
pasan locals() y['huevos'] como argumentos, la
función __import__() no da valor a la variable local huevos;
esto se realiza con el código adicional generado por la sentencia import (de
hecho, la implementación estándar no utiliza el argumento locals en absoluto y usa globals sólo para determinar el
contexto del paquete de la sentencia import).
Cuando la variable name tiene
la forma package.module, normalmente, se devuelve el paquete de nivel más
elevado (el nombre hasta el primer punto, no el módulo denotado por name. Sin embargo,. cuando se proporciona un argumento fromlist no vacío, se devuelve
el módulo denominado name.
Esto se hace de esta manera por compatibilidad con el bytecode generado para
las diferentes clases de sentencias import. Cuando se utiliza "import
spam.jamon.huevos", el paquete de nivel superior spam debe
colocarse en el espacio nominal que ha llamado a import, pero cuando se usa
"from spam.jamon import huevos", se ha de utilizar el
subpaquete spam.jamon para encontrar la variable huevos. Como
remedio a este comportamiento, se puede utilizar getattr() para
extraer los componentes deseados. Por ejemplo, se podría definir la siguiente
función de ayuda:
import string
def my_import(name):
mod =
__import__(name)
components = string.split(name, '.')
for
comp in components[1:]:
mod = getattr(mod, comp)
return mod
abs (x)
Devuelve el valor absoluto de un número. El argumento
puede ser un entero normal o largo o un número de coma flotante. Si el
argumento es un número complejo, se devuelve su módulo.
apply (function,
args[, keywords])
El argumento function debe ser un objeto invocable (una función o método
definido por el usuario o interna) y args una secuencia (si no es una tupla, primero se
convierte la secuencia a tupla). Se llama a la función function con args como lista de argumentos.
El número de argumentos es la longitud de la tupla (se diferencia de llamar sin
más a func(args), pues en este caso siempre hay
exactamente un argumento). Si se proporciona el argumento opcional keywords, debe ser un diccionario
cuyas claves sean cadenas. Especifica argumentos clave a añadir al final de la
lista de argumentosd.
buffer (object[, offset[, size]])
EL argumento object debe ser un objeto con interfaz compatible con
buffer (cadenas, matrices y buffers). Se creará un nuevo objeto buffer
referente a object. El
objeto buffer será un corte desde el principio de object (o desde el desplazamiento inicial offset especificado). El corte
se extenderá hasta el final de object (o
tendrá una longitud especificada por el argumento size).
Funciones definidas por el usuario
Las funciones de usuario pueden ser escritas para
realizar tareas repetitivas y para reducir el tamaño de un programa.
Las funciones
definidas por el usuario son aquellas que crea usted mismo para
usarlas en aplicaciones, a diferencia de las funciones en las clases
incorporadas, que realizan funciones predefinidas. Deberá asignar nombre a las
funciones usted mismo y añadir sentencias en el bloque de función. Las
secciones anteriores tratan la escritura de funciones como, por ejemplo, las
funciones con nombre, anónimas y callback.
Puede
utilizar una ruta de destino para llamar a una función en cualquier línea de
tiempo y desde cualquier línea de tiempo, inclusive desde la línea de tiempo de
un archivo SWF cargado. Para llamar a una función, escriba la ruta de destino
del nombre de la función, si es necesario, y pase los parámetros necesarios
entre paréntesis. Existen diversas formas de sintaxis para las funciones
definidas por el usuario. En el código siguiente se utiliza una ruta para
llamar a la función initialize(), que se ha definido en la línea de tiempo
actual y que no requiere ningún parámetro:
this.initialize();
En
el ejemplo siguiente se utiliza una ruta relativa para llamar a la función list() que
se ha definido en el clip de película functionsClip:
this._parent.functionsClip.list(6);
También
puede definir sus propias funciones con nombre. Por ejemplo, la siguiente función
con nombre helloWorld() ha sido definida por el usuario:
function
helloWorld() {
trace("Hello world!");
};
Las funciones se
declaran asociadas a un tipo de valor. Este valor será el que devolverá la
función, por ejemplo ‘int’ se utilizará cuando la función devuelva un dato
numérico de tipo entero. Si la función no devuelve ningún valor entonces se
colocará delante la palabra “void”, que significa “función vacía”
2.2
COMPONENTES
Los componentes son
unos elementos genéricos con una funcionalidad muy concreta, cuya única
finalidad es la reutilización. Cada uno de ellos está destinado a realizar una
tarea típica en una aplicación.
Un componente de la
VCL es una clase que
caracteriza a un control de
Windows agregando propiedades, métodos y gestores de eventos a cada
control.
La filosofía de los
componentes en C++ Builder es
exactamente la misma que en Visual
Basic. Esto es tanto así que algunos componentes pueden utilizarse en
ambos entornos (los componentes ActiveX).
2.2.1 Declaracion
Una declaración es
una sentencia que introduce un nombre en una unidad de compilación dándole
existencia semántica. Esto de la "existencia semántica" es una forma
elegante de decir que a partir de ahí el compilador sabe que "cosa"
es (representa) ese nombre. La forma de darle existencia semántica a las
entidades es declararlos (algo así como "presentarlos" formalmente en
el código). Por ejemplo, si declaramos una variable x o una
funciónfunc, a partir de ahí el
compilador sabe que x es una
variable de tal tipo, y que func es
una función de características cuales.
Simplemente asocia un
identificador con un tipo (existencia semántica). La declaración de una función
se denomina prototipo.
La gramática C++ exige que la declaración de una entidad se indique primero su
tipo y después el identificador con el que se la conocerá en adelante.
Ejemplos:
extern int x;
class C;
int func(int x, char c); // prototipo
Observe que la gramática C++ permite realizar varias declaraciones en una
sola sentencia separando con comas los identificadores:
int x, y, z;
C c1, c2, c3;
Después de la declaración es poco lo que puede hacer el compilador con una
etiqueta, ya que solo conoce el "tipo" de objeto que representa. Sin
embargo, son posibles aquellos usos para los que basta con esta información.
Ejemplo:
struct E1; // declara que E1 es tipo struct
struct E2* pe2; // declara que pe2 es tipo
E2* (puntero-a-struct-E2)
E1* ep1; // declara
que pe1 es tipo E1* (puntero-a-struct-E1)
Este tipo de declaraciones se denominan adelantadas (en el sentido que no están
los tipos
incompletos no pueden ser
utilizados en la definición de otros tipos, aunque sí en su declaración
-también incompleta-. Ejemplo:
extern C* cptr; // puntero a tipo incompleto
typedef int UNDA[]; // matriz incompleta
UNDA* aptr; // puntero a tipo
incompleto
class D {
UNDA** apptr; // Error: puntero a tipo
incompleto
...
// en definición
};
2.2.2 ARGUMENTOS
En programación,
los argumentos son los valores realmente suministrados a un procedimiento cuando
éste es invocado o llamado. En ocasiones se considera sinónimo de parámetro,
pero técnicamente no significan lo mismo.
Los argumentos pueden (y a menudo es así) variar de llamado en llamado (a
diferencia de los parámetros, que
forman parte de la definición estática de un procedimiento).
Un argumento o parámetro es
una variable utilizada para recibir valores de entrada en una rutina o subrutina. Dichos
valores, que serán enviados desde la rutina invocante, son llamados argumentos.
La subrutina usa los valores asignados a sus parámetros para
alterar su comportamiento en tiempo de ejecución. La mayor parte de los lenguajes de
programación pueden definir
subrutinas que aceptan cero o más argumentos.
Existen cinco formas de pasar un argumento a una función (subrutina) o procedimiento: por valor, por referencia, por resultado, por
valor-resultado y por nombre.
Diferencia entre parámetro y argumento en programación
En general las palabras argumento y parámetro son tomadas como sinónimos; en
realidad hay diferencia: los parámetros aparecen en la definición del
procedimiento, los argumentos aparecen en los llamados a procedimientos.
Un parámetro es una propiedad intrínseca de un procedimiento, dado que está
incluido en su definición. En tanto, los argumentos son más bien los valores
actuales asignados a los parámetros variables cuando la subrutina es llamada.
En la práctica no se suele distinguir tajantemente entre ambos términos.
2.2.3 PARAMETROS
En la informática, más precisamente en programación, un parámetro representa un dato que se
ofrece una función con un fin específico. Por ejemplo, una rutina que tenga
como finalidad devolver el número más alto de una lista, esperará que le
pasemos dicho conjunto de valores como parámetro para realizar su tarea.
En algunos lenguajes, es
posible especificar que ciertos parámetros sean opcionales, y asignarles un valor por defecto en caso de que el programador
escoja no pasarlos. En programación de gráficos, por ejemplo, suele ser común
que las funciones o métodos que gestionan temas relacionados con el color,
tengan un parámetro para la transparencia que no sea obligatorio
especificar, ya que comúnmente las imágenes de una aplicación multimedial son
opacas.
Esto repercute principalmente
en la practicidad a la hora de programar, ya que existen funciones que esperan
10 parámetros, 6 de los cuales son optativos, y verse forzado a completar esos
espacios con valores nulos o falsos cada vez
que se desee prescindir de ellos representa una pérdida de tiempo.
2.3
INVOCACIÓN Y RETORNO DEL VALOR DE LA FUNCIÓN
FUNCIONES QUE RETORNAN VALOR
Analicemos por medio de un ejemplo dichas funciones :
#include <stdio.h>
#include <conio.h>
#define FALSO 0
#define CIERTO 1
int
finalizar(void);
int lea_char(void) ;
main()
{
int i =
0;
int fin
= FALSO;
printf("Ejemplo de
Funciones que retornan valor\n");
while (fin == FALSO) {
i++;
printf("i == %d\n", i);
fin = finalizar();
}
printf("\n\nFIN DEL PROGRAMA........");
return 0;
}
int finalizar(void)
{
int c;
printf("Otro número ? (s/n) ");
do {
c =
lea_char() ;
}
while ((c != 'n') && (c != 's'));
return
(c == 'n');
}
int lea_char(void)
{
int j ;
if( (j = getch()) >>= 'A' && j
<<= 'Z' )
return( j + ( 'a' - 'A') ) ;
else
return
j ;
}
Analizando el programa anterior; las dos
primeras líneas incluirán, en el programa los prototipos de las funciones de
librería usadas, ( en este caso printf() y getch() . En las dos siguientes
damos nombres simbólicos a dos constantes que usaremos en las condiciones
lógicas y posteriormente damos los prototipos de dos funciones que hemos
creado.
Podrían haberse obviado, en este caso particular, estas dos últimas
declaraciones, ya que ambas retornan un int (default), sin embargo el hecho de
incluirlas hará que el programa sea más comprensible en el futuro.
Comienza luego la función main(), inicializando dos variables, i y fin, donde
la primera nos servirá de contador y la segunda de indicador lógico. Luego de
imprimir el rótulo del programa, entramos en un loop en el que permaneceremos
todo el tiempo en que fin sea FALSO.
Dentro de este loop, incrementamos el contador, lo imprimimos, y asignamos a
fin un valor que es el retorno de la función finalizar()
2.4
ÁMBITO O ALCANCE DE LAS VARIABLES
El ámbito es el
contexto que tiene un nombre dentro de un programa. El ámbito determina en qué
partes del programa una entidad puede ser usada.
Esto sirve para que se pueda
volver a definir una variable con un mismo nombre en diferentes partes del programa sin que haya
conflictos entre ellos.
Si una variable es declarada
dentro de un bloque (método/función/procedimiento), ésta será válida solo
dentro de ese bloque y se destruirá al terminar el bloque. Adicionalmente, la
variable no podrá verse ni usarse fuera del bloque (en el exterior del bloque).
La variable dentro del bloque es una variable local y solo
tiene alcance dentro del bloque que se creó y sus bloques hijos, pero no en
bloques hermanos ni padres, una variable definida fuera de cualquier bloque es
una variable global y cualquier bloque puede acceder a ella y modificarla.
En el caso de programación
orientada a objetos (POO), una variable global
dentro de una clase es llamada variable
de instancia, y cada objeto creado con esa clase tiene una.
Adicionalmente existen variables globales que son comunes a un todos los
objetos creados con una clase y son llamadas variables de clase.
Hay dos tipos de alcances, el
estático que también es llamado lexicográfico, donde el alcance se determina en
tiempo de compilación, mientras que las variables de alcance dinámico se
verificara en el hilo de ejecución.
Ejemplo en Java
public class A {
public Integer numeroEntero =
new Integer(); /* Variable Global a todos los Métodos */
public Integer metodo() {
int num = 1; // Variable
Local a método. Puede accederse dentro de este método en cualquier parte, pero
no fuera del mismo.
for (int i =
0;i<numeroEntero.intValue();i++) { // i es local al bucle for, sólo puede
ser accedida dentro del mismo.
num *= i;
}
// i = 2; Esta línea
provocaría error al no haber declarado la variable i. i fue definida localmente
al bucle for.
return
Integer.valueOf(num);
}
public void otroMetodo() {
int num = 1;
// Variable local a otroMetodo. num aquí es una variable distinta a la variable
num de método
System.out.println("Variable
local num: " + num);
}
}
2.5 PASO DE ARGUMENTOS POR VALOR
Es un tipo poco usado en los lenguajes de programación actuales. Se basa en
que dentro de la función se trabaja como si los argumentos hubieran sido
pasados por valor pero al acabar la función los valores que tengan los
argumentos serán copiados a las variables que pertenecían.
Este tipo puede ser simulado en cualquier lenguaje que permita el paso de
valores por referencia de la siguiente forma:
void EjemploValorRes(int a1, int a2, int a3) {
int
aux1 = a1, aux2 = a2, aux3 = a3;
// código trabajando con aux1, aux2 y aux3
a1
= aux1; a2 = aux2; a3 = aux3; // Dependiendo del compilador la copia se realiza en un
sentido o en el otro
}
Tal y como indica el ejemplo de simulación de valor-resultado, el orden de
copia depende del compilador, lo que implica que la misma función pueda dar
resultados diferentes según el compilador usado.
2.6 PASO DE
ARGUMENTOS POR REFERENCIA
El paso de parámetros por
referencia consiste en proporcionar a la subrutina a la que se le quiere pasar
el argumento la dirección de
memoria del dato. En
este caso se tiene un único valor referenciado (o apuntado) desde dos puntos
diferentes, el programa principal y la subrutina a la que se le pasa el
argumento, por lo que cualquier acción sobre el parámetro se realiza sobre la
misma posición de memoria.
El paso por referencia se hace
utilizando apuntadores. Se envía la dirección de memoria de la variable, por lo
tanto los cambios que haga la función si afectan el valor de la variable.
Ejemplo:
/*
*
por_referencia.c
*
* Julio César
Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el
wikilibro "Programación en C"
* bajo licencia
FDL, adaptado del Dominio Público
*/
#include <stdio.h>
void sumar_referencia(int *numero); /* prototipo de la función */
int main(void)
{
int numero = 57; /* definimos numero
con valor de 57*/
sumar_referencia(&numero); /* enviamos
numero a la función */
printf("\nValor de numero dentro de main() es: %d ", numero);
/* podemos notar que el valor de numero se modifica
* y que ahora dentro de main() también se ha
modificado
* aunque la función no haya retornado ningún
valor.
*/
return 0;
}
void sumar_referencia(int *numero)
{
*numero += 1; /* le sumamos 1 al
numero */
/* el valor de numero recibido se aumenta en 1
* y se modifica dentro de la función
*/
printf("\nValor de numero dentro sumar_referencia() es: %d", *numero);
return;
}
Un principio ampliamente difundido e importante para
resolver problemas es el de “dividir para reinar”, es decir separar el problema
en partes, en problemas más pequeños, para así enfrentarlos y resolverlos en un
tamaño más accesible y fácil de manejar. Este principio tiene una directa
aplicación en la programación de computadoras, para lo cual muchos lenguajes de
programación cuentan con una característica adecuada: la modularidad. Estos
lenguajes permiten escribir programas compuestos de porciones o partes que se
conocen como módulos, muchas veces nombrados también como subprogramas,
subrutinas, procedimientos, funciones, entre otros. En todos los casos, los
principios generales y elementales que los gobiernan son los mismos, aún cuando
algunos tengan características distintas y mayores o menores prestaciones:
todos permiten separar un programa en partes más pequeñas y reusar esos trozos
de programa o módulos ya escritos para resolver problemas similares.
Un módulo de programa tiene dos partes bien diferenciadas:
la definición del módulo y la invocación o llamada al módulo. La definición de
un módulo es donde se dice qué es lo que el mismo hará, es decir, cuáles serán
sus efectos al ser invocado, es decir cuando se ejecute. Una invocación o
llamada ocurre cuando se usa el módulo. En el punto del programa donde se hace
la invocación al módulo es donde, en tiempo de ejecución del programa, se
ejecutarán las acciones comprendidas en la definición del módulo.
En un programa,
por cada módulo, habrá una única definición, ya que bastará con una vez para
decirse qué es lo que el módulo hace. Sin embargo, puede haber más de una
invocación al mismo, ya que una solución puede usarse tantas veces como sea
necesario.
2.1- TIPOS DE
FUNCIONES: INTERNAS Y CREADAS POR EL USUARIO
Funciones internas
El intérprete de
Python cuenta con funciones internas que siempre se hallan disponibles. Se
muestran a continuación, en orden alfabético.
__import__ (name[, globals[, locals[, fromlist]]])
Esta función es llamada por la sentencia import.
Existe con el propósito principal de reemplazarla con otra función compatible
en interfaz, para hacer posible cambiar la semántica de la
sentencia import. Consultar los módulos de biblioteca
estándar ihooks y rexec si se desea ver por qué y cómo
hacer esto. Consultar también el módulo interno imp, que define ciertas operaciones útiles
para construir una función __import__() propia.
Por ejemplo, la sentencia `import spam' causa la siguiente
llamada: __import__('spam', globals(), locals(), []); la
sentencia from spam.jamon import huevos resulta
en __import__('spam.jamon', globals(), locals(), ['huevos']).
Hay que ver que, a pesar de que se
pasan locals() y['huevos'] como argumentos, la
función __import__() no da valor a la variable local huevos;
esto se realiza con el código adicional generado por la sentencia import (de
hecho, la implementación estándar no utiliza el argumento locals en absoluto y usa globals sólo para determinar el
contexto del paquete de la sentencia import).
Cuando la variable name tiene
la forma package.module, normalmente, se devuelve el paquete de nivel más
elevado (el nombre hasta el primer punto, no el módulo denotado por name. Sin embargo,. cuando se proporciona un argumento fromlist no vacío, se devuelve
el módulo denominado name.
Esto se hace de esta manera por compatibilidad con el bytecode generado para
las diferentes clases de sentencias import. Cuando se utiliza "import
spam.jamon.huevos", el paquete de nivel superior spam debe
colocarse en el espacio nominal que ha llamado a import, pero cuando se usa
"from spam.jamon import huevos", se ha de utilizar el
subpaquete spam.jamon para encontrar la variable huevos. Como
remedio a este comportamiento, se puede utilizar getattr() para
extraer los componentes deseados. Por ejemplo, se podría definir la siguiente
función de ayuda:
import string
def my_import(name):
mod =
__import__(name)
components = string.split(name, '.')
for
comp in components[1:]:
mod = getattr(mod, comp)
return mod
abs (x)
Devuelve el valor absoluto de un número. El argumento
puede ser un entero normal o largo o un número de coma flotante. Si el
argumento es un número complejo, se devuelve su módulo.
apply (function,
args[, keywords])
El argumento function debe ser un objeto invocable (una función o método
definido por el usuario o interna) y args una secuencia (si no es una tupla, primero se
convierte la secuencia a tupla). Se llama a la función function con args como lista de argumentos.
El número de argumentos es la longitud de la tupla (se diferencia de llamar sin
más a func(args), pues en este caso siempre hay
exactamente un argumento). Si se proporciona el argumento opcional keywords, debe ser un diccionario
cuyas claves sean cadenas. Especifica argumentos clave a añadir al final de la
lista de argumentosd.
buffer (object[, offset[, size]])
EL argumento object debe ser un objeto con interfaz compatible con
buffer (cadenas, matrices y buffers). Se creará un nuevo objeto buffer
referente a object. El
objeto buffer será un corte desde el principio de object (o desde el desplazamiento inicial offset especificado). El corte
se extenderá hasta el final de object (o
tendrá una longitud especificada por el argumento size).
Funciones definidas por el usuario
Las funciones de usuario pueden ser escritas para
realizar tareas repetitivas y para reducir el tamaño de un programa.
Las funciones
definidas por el usuario son aquellas que crea usted mismo para
usarlas en aplicaciones, a diferencia de las funciones en las clases
incorporadas, que realizan funciones predefinidas. Deberá asignar nombre a las
funciones usted mismo y añadir sentencias en el bloque de función. Las
secciones anteriores tratan la escritura de funciones como, por ejemplo, las
funciones con nombre, anónimas y callback.
Puede
utilizar una ruta de destino para llamar a una función en cualquier línea de
tiempo y desde cualquier línea de tiempo, inclusive desde la línea de tiempo de
un archivo SWF cargado. Para llamar a una función, escriba la ruta de destino
del nombre de la función, si es necesario, y pase los parámetros necesarios
entre paréntesis. Existen diversas formas de sintaxis para las funciones
definidas por el usuario. En el código siguiente se utiliza una ruta para
llamar a la función initialize(), que se ha definido en la línea de tiempo
actual y que no requiere ningún parámetro:
this.initialize();
En
el ejemplo siguiente se utiliza una ruta relativa para llamar a la función list() que
se ha definido en el clip de película functionsClip:
this._parent.functionsClip.list(6);
También
puede definir sus propias funciones con nombre. Por ejemplo, la siguiente función
con nombre helloWorld() ha sido definida por el usuario:
function
helloWorld() {
trace("Hello world!");
};
Las funciones se
declaran asociadas a un tipo de valor. Este valor será el que devolverá la
función, por ejemplo ‘int’ se utilizará cuando la función devuelva un dato
numérico de tipo entero. Si la función no devuelve ningún valor entonces se
colocará delante la palabra “void”, que significa “función vacía”
2.2
COMPONENTES
Los componentes son
unos elementos genéricos con una funcionalidad muy concreta, cuya única
finalidad es la reutilización. Cada uno de ellos está destinado a realizar una
tarea típica en una aplicación.
Un componente de la
VCL es una clase que
caracteriza a un control de
Windows agregando propiedades, métodos y gestores de eventos a cada
control.
La filosofía de los
componentes en C++ Builder es
exactamente la misma que en Visual
Basic. Esto es tanto así que algunos componentes pueden utilizarse en
ambos entornos (los componentes ActiveX).
2.2.1 Declaracion
Una declaración es
una sentencia que introduce un nombre en una unidad de compilación dándole
existencia semántica. Esto de la "existencia semántica" es una forma
elegante de decir que a partir de ahí el compilador sabe que "cosa"
es (representa) ese nombre. La forma de darle existencia semántica a las
entidades es declararlos (algo así como "presentarlos" formalmente en
el código). Por ejemplo, si declaramos una variable x o una
funciónfunc, a partir de ahí el
compilador sabe que x es una
variable de tal tipo, y que func es
una función de características cuales.
Simplemente asocia un
identificador con un tipo (existencia semántica). La declaración de una función
se denomina prototipo.
La gramática C++ exige que la declaración de una entidad se indique primero su
tipo y después el identificador con el que se la conocerá en adelante.
Ejemplos:
extern int x;
class C;
int func(int x, char c); // prototipo
Observe que la gramática C++ permite realizar varias declaraciones en una
sola sentencia separando con comas los identificadores:
int x, y, z;
C c1, c2, c3;
Después de la declaración es poco lo que puede hacer el compilador con una
etiqueta, ya que solo conoce el "tipo" de objeto que representa. Sin
embargo, son posibles aquellos usos para los que basta con esta información.
Ejemplo:
struct E1; // declara que E1 es tipo struct
struct E2* pe2; // declara que pe2 es tipo E2* (puntero-a-struct-E2)
E1* ep1; // declara que pe1 es tipo E1* (puntero-a-struct-E1)
struct E2* pe2; // declara que pe2 es tipo E2* (puntero-a-struct-E2)
E1* ep1; // declara que pe1 es tipo E1* (puntero-a-struct-E1)
Este tipo de declaraciones se denominan adelantadas (en el sentido que no están
los tipos
incompletos no pueden ser
utilizados en la definición de otros tipos, aunque sí en su declaración
-también incompleta-. Ejemplo:
extern C* cptr; // puntero a tipo incompleto
typedef int UNDA[]; // matriz incompleta
UNDA* aptr; // puntero a tipo incompleto
typedef int UNDA[]; // matriz incompleta
UNDA* aptr; // puntero a tipo incompleto
class D {
UNDA** apptr; // Error: puntero a tipo
incompleto
...
// en definición
};
2.2.2 ARGUMENTOS
En programación,
los argumentos son los valores realmente suministrados a un procedimiento cuando
éste es invocado o llamado. En ocasiones se considera sinónimo de parámetro,
pero técnicamente no significan lo mismo.
Los argumentos pueden (y a menudo es así) variar de llamado en llamado (a diferencia de los parámetros, que forman parte de la definición estática de un procedimiento).
Los argumentos pueden (y a menudo es así) variar de llamado en llamado (a diferencia de los parámetros, que forman parte de la definición estática de un procedimiento).
Un argumento o parámetro es
una variable utilizada para recibir valores de entrada en una rutina o subrutina. Dichos
valores, que serán enviados desde la rutina invocante, son llamados argumentos.
La subrutina usa los valores asignados a sus parámetros para
alterar su comportamiento en tiempo de ejecución. La mayor parte de los lenguajes de
programación pueden definir
subrutinas que aceptan cero o más argumentos.
Existen cinco formas de pasar un argumento a una función (subrutina) o procedimiento: por valor, por referencia, por resultado, por
valor-resultado y por nombre.
Diferencia entre parámetro y argumento en programación
En general las palabras argumento y parámetro son tomadas como sinónimos; en realidad hay diferencia: los parámetros aparecen en la definición del procedimiento, los argumentos aparecen en los llamados a procedimientos.
Un parámetro es una propiedad intrínseca de un procedimiento, dado que está incluido en su definición. En tanto, los argumentos son más bien los valores actuales asignados a los parámetros variables cuando la subrutina es llamada. En la práctica no se suele distinguir tajantemente entre ambos términos.
Diferencia entre parámetro y argumento en programación
En general las palabras argumento y parámetro son tomadas como sinónimos; en realidad hay diferencia: los parámetros aparecen en la definición del procedimiento, los argumentos aparecen en los llamados a procedimientos.
Un parámetro es una propiedad intrínseca de un procedimiento, dado que está incluido en su definición. En tanto, los argumentos son más bien los valores actuales asignados a los parámetros variables cuando la subrutina es llamada. En la práctica no se suele distinguir tajantemente entre ambos términos.
2.2.3 PARAMETROS
En la informática, más precisamente en programación, un parámetro representa un dato que se
ofrece una función con un fin específico. Por ejemplo, una rutina que tenga
como finalidad devolver el número más alto de una lista, esperará que le
pasemos dicho conjunto de valores como parámetro para realizar su tarea.
En algunos lenguajes, es
posible especificar que ciertos parámetros sean opcionales, y asignarles un valor por defecto en caso de que el programador
escoja no pasarlos. En programación de gráficos, por ejemplo, suele ser común
que las funciones o métodos que gestionan temas relacionados con el color,
tengan un parámetro para la transparencia que no sea obligatorio
especificar, ya que comúnmente las imágenes de una aplicación multimedial son
opacas.
Esto repercute principalmente
en la practicidad a la hora de programar, ya que existen funciones que esperan
10 parámetros, 6 de los cuales son optativos, y verse forzado a completar esos
espacios con valores nulos o falsos cada vez
que se desee prescindir de ellos representa una pérdida de tiempo.
2.3
INVOCACIÓN Y RETORNO DEL VALOR DE LA FUNCIÓN
FUNCIONES QUE RETORNAN VALOR
Analicemos por medio de un ejemplo dichas funciones :
Analicemos por medio de un ejemplo dichas funciones :
#include <stdio.h>
#include <conio.h>
#define FALSO 0
#define CIERTO 1
int
finalizar(void);
int lea_char(void) ;
main()
{
int i =
0;
int fin
= FALSO;
printf("Ejemplo de
Funciones que retornan valor\n");
while (fin == FALSO) {
i++;
printf("i == %d\n", i);
fin = finalizar();
}
printf("\n\nFIN DEL PROGRAMA........");
return 0;
}
int finalizar(void)
{
int c;
printf("Otro número ? (s/n) ");
do {
c =
lea_char() ;
}
while ((c != 'n') && (c != 's'));
return
(c == 'n');
}
int lea_char(void)
{
int j ;
if( (j = getch()) >>= 'A' && j
<<= 'Z' )
return( j + ( 'a' - 'A') ) ;
else
return
j ;
}
Analizando el programa anterior; las dos
primeras líneas incluirán, en el programa los prototipos de las funciones de
librería usadas, ( en este caso printf() y getch() . En las dos siguientes
damos nombres simbólicos a dos constantes que usaremos en las condiciones
lógicas y posteriormente damos los prototipos de dos funciones que hemos
creado.
Podrían haberse obviado, en este caso particular, estas dos últimas declaraciones, ya que ambas retornan un int (default), sin embargo el hecho de incluirlas hará que el programa sea más comprensible en el futuro.
Comienza luego la función main(), inicializando dos variables, i y fin, donde la primera nos servirá de contador y la segunda de indicador lógico. Luego de imprimir el rótulo del programa, entramos en un loop en el que permaneceremos todo el tiempo en que fin sea FALSO.
Dentro de este loop, incrementamos el contador, lo imprimimos, y asignamos a fin un valor que es el retorno de la función finalizar()
Podrían haberse obviado, en este caso particular, estas dos últimas declaraciones, ya que ambas retornan un int (default), sin embargo el hecho de incluirlas hará que el programa sea más comprensible en el futuro.
Comienza luego la función main(), inicializando dos variables, i y fin, donde la primera nos servirá de contador y la segunda de indicador lógico. Luego de imprimir el rótulo del programa, entramos en un loop en el que permaneceremos todo el tiempo en que fin sea FALSO.
Dentro de este loop, incrementamos el contador, lo imprimimos, y asignamos a fin un valor que es el retorno de la función finalizar()
2.4
ÁMBITO O ALCANCE DE LAS VARIABLES
El ámbito es el
contexto que tiene un nombre dentro de un programa. El ámbito determina en qué
partes del programa una entidad puede ser usada.
Esto sirve para que se pueda
volver a definir una variable con un mismo nombre en diferentes partes del programa sin que haya
conflictos entre ellos.
Si una variable es declarada
dentro de un bloque (método/función/procedimiento), ésta será válida solo
dentro de ese bloque y se destruirá al terminar el bloque. Adicionalmente, la
variable no podrá verse ni usarse fuera del bloque (en el exterior del bloque).
La variable dentro del bloque es una variable local y solo
tiene alcance dentro del bloque que se creó y sus bloques hijos, pero no en
bloques hermanos ni padres, una variable definida fuera de cualquier bloque es
una variable global y cualquier bloque puede acceder a ella y modificarla.
En el caso de programación
orientada a objetos (POO), una variable global
dentro de una clase es llamada variable
de instancia, y cada objeto creado con esa clase tiene una.
Adicionalmente existen variables globales que son comunes a un todos los
objetos creados con una clase y son llamadas variables de clase.
Hay dos tipos de alcances, el
estático que también es llamado lexicográfico, donde el alcance se determina en
tiempo de compilación, mientras que las variables de alcance dinámico se
verificara en el hilo de ejecución.
Ejemplo en Java
public class A {
public Integer numeroEntero =
new Integer(); /* Variable Global a todos los Métodos */
public Integer metodo() {
int num = 1; // Variable
Local a método. Puede accederse dentro de este método en cualquier parte, pero
no fuera del mismo.
for (int i =
0;i<numeroEntero.intValue();i++) { // i es local al bucle for, sólo puede
ser accedida dentro del mismo.
num *= i;
}
// i = 2; Esta línea
provocaría error al no haber declarado la variable i. i fue definida localmente
al bucle for.
return
Integer.valueOf(num);
}
public void otroMetodo() {
int num = 1;
// Variable local a otroMetodo. num aquí es una variable distinta a la variable
num de método
System.out.println("Variable
local num: " + num);
}
}
2.5 PASO DE ARGUMENTOS POR VALOR
Es un tipo poco usado en los lenguajes de programación actuales. Se basa en
que dentro de la función se trabaja como si los argumentos hubieran sido
pasados por valor pero al acabar la función los valores que tengan los
argumentos serán copiados a las variables que pertenecían.
Este tipo puede ser simulado en cualquier lenguaje que permita el paso de
valores por referencia de la siguiente forma:
void EjemploValorRes(int a1, int a2, int a3) {
int
aux1 = a1, aux2 = a2, aux3 = a3;
// código trabajando con aux1, aux2 y aux3
a1
= aux1; a2 = aux2; a3 = aux3; // Dependiendo del compilador la copia se realiza en un
sentido o en el otro
}
Tal y como indica el ejemplo de simulación de valor-resultado, el orden de
copia depende del compilador, lo que implica que la misma función pueda dar
resultados diferentes según el compilador usado.
2.6 PASO DE
ARGUMENTOS POR REFERENCIA
El paso de parámetros por
referencia consiste en proporcionar a la subrutina a la que se le quiere pasar
el argumento la dirección de
memoria del dato. En
este caso se tiene un único valor referenciado (o apuntado) desde dos puntos
diferentes, el programa principal y la subrutina a la que se le pasa el
argumento, por lo que cualquier acción sobre el parámetro se realiza sobre la
misma posición de memoria.
El paso por referencia se hace
utilizando apuntadores. Se envía la dirección de memoria de la variable, por lo
tanto los cambios que haga la función si afectan el valor de la variable.
Ejemplo:
/*
*
por_referencia.c
*
* Julio César
Brizuela <brizuelaalvarado@gmail.com> 2009
*
* para el
wikilibro "Programación en C"
* bajo licencia
FDL, adaptado del Dominio Público
*/
#include <stdio.h>
void sumar_referencia(int *numero); /* prototipo de la función */
int main(void)
{
int numero = 57; /* definimos numero
con valor de 57*/
sumar_referencia(&numero); /* enviamos
numero a la función */
printf("\nValor de numero dentro de main() es: %d ", numero);
/* podemos notar que el valor de numero se modifica
* y que ahora dentro de main() también se ha
modificado
* aunque la función no haya retornado ningún
valor.
*/
return 0;
}
void sumar_referencia(int *numero)
{
*numero += 1; /* le sumamos 1 al
numero */
/* el valor de numero recibido se aumenta en 1
* y se modifica dentro de la función
*/
printf("\nValor de numero dentro sumar_referencia() es: %d", *numero);
return;
}
a)- Ejemplo donde
se analiza las funciones internas, asociándola con la definición matemática de
función.
Hemos hablado ya sobre las expresiones aritméticas
y cómo podemos traducir fórmulas matemáticas usando diferentes clases de
operadores aritméticos. Sin embargo, ¿qué pasa si en mi algoritmo necesito
calcular una raíz cuadrada? ¿o si necesito calcular alguna función
trigonométrica? ¿y qué tal si hay que redondear un valor numérico? Pues para
esos casos existen las llamadas Funciones Internas, incorporadas o estándar,
que forman parte de prácticamente todos los lenguajes de programación.
La idea de estas funciones es ahorrarnos trabajo
puesto que no tenemos que hacer más que llamarlas por su nombre (o
"invocarlas") y pasarles algunos parámetros para que nos regresen el
resultado que buscamos. Por ejemplo, la función raiz2 nos permite calcular la
raíz cuadrada de un número y lo único que tenemos que hacer es pasarle como
parámetro el número cuya raíz cuadrada queremos calcular. Algo asi:
x ← raiz2(25)
Después de esta instrucción, x tendría el valor de
5.
En esta tabla encontramos las funciones internas
más frecuentes así como su descripción y un ejemplo de uso para comprender
mejor su funcionamiento.
Veamos ahora cómo usar estas funciones para
traducir a expresiones algorítmicas una de las fórmulas matemáticas más
conocidas: la fórmula general para resolver ecuaciones de segundo grado (sí
recuerdan sus matemáticas de secundaria, ¿verdad?):
O lo que es lo mismo:
Estas fórmulas, traducidas a expresiones
algorítmicas quedarían así:
x1 = (-b + raiz2(cuadrado(b) - 4 * a * c)) / (2 * a)
x1 = (-b - raiz2(cuadrado(b) - 4 * a * c)) / (2 * a)
b) ACTIVIDADES
EJERCICIO DE PROGRAMACIÓN
DIFERENCIA ENTRE EL PASO POR VALOR Y
PASO POR REFERENCIA.
PASO DE PARÁMETROS POR VALOR:
Al realizar la definición de la función
colocamos los parámetros que ésta recibe especificando el tipo de dato de los mismos.
Luego, cuando hacemos el llamado y especificamos los argumentos, estos se
evalúan y se le pasa a la función una copia de los mismos. A esto es lo
que llamamos paso por valor ya que la función trabajará con los valores
de esas copias. Si pasáramos variables como argumento, éstas no se modificarían
por este sistema de copias.
Veamos esto con un ejemplo simple en que tenemos la siguiente función void que intercambia los valores de dos
enteros x e y:
Declaramos
dos variables de tipo int en el main, mostramos sus valores, llamamos a la
función y volvemos a mostrarlos de la siguiente manera:
Y
veríamos en pantalla:
Donde
vemos que, en efecto no se modificaron los valores. Pero agreguemos un printf al final de la función para ver
si se habían modificado o no los valores:
Y
obtenemos:
Donde
vemos que, en efecto se modificaron los valores de x e y dentro de la función
pero que no se modificaron las variables originales ya que al hacer el pasaje
por valor se trabaja con la copia de las mismas.
PASO DE PARÁMETROS POR REFERENCIA
En
el pasaje por referencia se pasa a la función las direcciones de memoria de las
variables en cuestión en lugar de su valor. A diferencia del paso por valor,
aquí no se realizan copias de las variables sino que se trabaja sobre la
dirección de memoria que pasamos, lo que nos permite modificar el valor de la
variable en cuestión.
Veamos
esto con el mismo ejemplo que usamos antes, pero usando punteros:
Luego
hacemos el llamado a la función de la misma manera, pero pasando las
direcciones de memoria de x e y:
Obteniendo
lo siguiente al compilar el programa y ejecutarlo:
a)- Ejemplo donde
se analiza las funciones internas, asociándola con la definición matemática de
función.
Hemos hablado ya sobre las expresiones aritméticas
y cómo podemos traducir fórmulas matemáticas usando diferentes clases de
operadores aritméticos. Sin embargo, ¿qué pasa si en mi algoritmo necesito
calcular una raíz cuadrada? ¿o si necesito calcular alguna función
trigonométrica? ¿y qué tal si hay que redondear un valor numérico? Pues para
esos casos existen las llamadas Funciones Internas, incorporadas o estándar,
que forman parte de prácticamente todos los lenguajes de programación.
La idea de estas funciones es ahorrarnos trabajo
puesto que no tenemos que hacer más que llamarlas por su nombre (o
"invocarlas") y pasarles algunos parámetros para que nos regresen el
resultado que buscamos. Por ejemplo, la función raiz2 nos permite calcular la
raíz cuadrada de un número y lo único que tenemos que hacer es pasarle como
parámetro el número cuya raíz cuadrada queremos calcular. Algo asi:
x ← raiz2(25)
Después de esta instrucción, x tendría el valor de
5.
En esta tabla encontramos las funciones internas
más frecuentes así como su descripción y un ejemplo de uso para comprender
mejor su funcionamiento.
Veamos ahora cómo usar estas funciones para
traducir a expresiones algorítmicas una de las fórmulas matemáticas más
conocidas: la fórmula general para resolver ecuaciones de segundo grado (sí
recuerdan sus matemáticas de secundaria, ¿verdad?):
O lo que es lo mismo:
Estas fórmulas, traducidas a expresiones
algorítmicas quedarían así:
x1 = (-b + raiz2(cuadrado(b) - 4 * a * c)) / (2 * a)
x1 = (-b - raiz2(cuadrado(b) - 4 * a * c)) / (2 * a)
EJERCICIO DE PROGRAMACIÓN
DIFERENCIA ENTRE EL PASO POR VALOR Y
PASO POR REFERENCIA.
PASO DE PARÁMETROS POR VALOR:
Al realizar la definición de la función colocamos los parámetros que ésta recibe especificando el tipo de dato de los mismos.
Luego, cuando hacemos el llamado y especificamos los argumentos, estos se evalúan y se le pasa a la función una copia de los mismos. A esto es lo que llamamos paso por valor ya que la función trabajará con los valores de esas copias. Si pasáramos variables como argumento, éstas no se modificarían por este sistema de copias.
Veamos esto con un ejemplo simple en que tenemos la siguiente función void que intercambia los valores de dos enteros x e y:
Al realizar la definición de la función colocamos los parámetros que ésta recibe especificando el tipo de dato de los mismos.
Luego, cuando hacemos el llamado y especificamos los argumentos, estos se evalúan y se le pasa a la función una copia de los mismos. A esto es lo que llamamos paso por valor ya que la función trabajará con los valores de esas copias. Si pasáramos variables como argumento, éstas no se modificarían por este sistema de copias.
Veamos esto con un ejemplo simple en que tenemos la siguiente función void que intercambia los valores de dos enteros x e y:
Declaramos
dos variables de tipo int en el main, mostramos sus valores, llamamos a la
función y volvemos a mostrarlos de la siguiente manera:
Y
veríamos en pantalla:
Donde
vemos que, en efecto no se modificaron los valores. Pero agreguemos un printf al final de la función para ver
si se habían modificado o no los valores:
Y
obtenemos:
Donde
vemos que, en efecto se modificaron los valores de x e y dentro de la función
pero que no se modificaron las variables originales ya que al hacer el pasaje
por valor se trabaja con la copia de las mismas.
PASO DE PARÁMETROS POR REFERENCIA
En
el pasaje por referencia se pasa a la función las direcciones de memoria de las
variables en cuestión en lugar de su valor. A diferencia del paso por valor,
aquí no se realizan copias de las variables sino que se trabaja sobre la
dirección de memoria que pasamos, lo que nos permite modificar el valor de la
variable en cuestión.
Veamos
esto con el mismo ejemplo que usamos antes, pero usando punteros:
Luego
hacemos el llamado a la función de la misma manera, pero pasando las
direcciones de memoria de x e y:
Obteniendo
lo siguiente al compilar el programa y ejecutarlo:
Información interesante e ilustradora sobre la independencia modular que nos ayuda y mejora el rendimiento humano, pudiendo realizar programación en equipo y desarrollar módulos paralelamente. Simplificando la complejidad de un problema a través de la división de programas en módulos o subprogramas con la finalidad de hacerlo más legible y manejable.
ResponderEliminarEs productivo leer sobre la modularidad ya que esta se basa en la descomposición de un problema en una serie de sub problemas; dividiéndolo en módulos que resultan de segmentar el problema en funciones lógicas que son perfectamente diferenciadas. Esta división exige la presencia de un módulo denominado módulo de base o principal a objeto de que controle y se relacione con los demás.
ResponderEliminarMGM Casino - DrmCD
ResponderEliminarMGM 군산 출장안마 Resorts Casino at Wynn Las Vegas. 상주 출장안마 Information. MGM Resorts. 전주 출장안마 Casino. Las 서귀포 출장안마 Vegas Nevada. MGM Resorts. Casino. 남양주 출장안마 MGM Resorts. Casino. MGM Resorts.