Monografias.com > Sin categoría
Descargar Imprimir Comentar Ver trabajos relacionados

Tópicos de Lenguajes de programación (página 3)



Partes: 1, 2, 3

A = A – 1

Loop

  1. Un bucle o ciclo en programación es una sentencia que se
    realiza repetidas veces.

    Un bucle se utiliza para hacer una acción repetida sin tener que repetir
    varias veces el mismo código, lo que ahorra tiempo,
    deja el código más claro y facilita su
    modificación en el futuro.

    El bucle y los condicionales
    representan la base de la programación estructurada.
    Es una evolución del código ensamblador, donde la única posibilidad
    de iterar un código era establecer una sentencia jump
    (que en los lenguajes de programación fue sustituida
    por el "ir a" o GOTO).

    Los tres bucles más utilizados en
    programación son el mientras, el
    para y el bucle repetir.

    Ejemplo en código C de sentencias
    repetidas:

    int var=0;

    //código que puede ser sustituido por un
    bucle

    var = var + 2; //var igual a 2 (puede ser
    sustituído por var+=2)

    var = var + 2; //var igual a 4

    var = var + 2; //var igual a 6

    var = var + 2; //var igual a 8

    var = var + 2; //var igual a 10

    // fin de código que puede ser sustituido por
    un bucle

    printf("el resultado es %i", var );

    Ejemplo con un bucle:

    int var=0;

    //Código para el bucle

    int i;

    // este es el Bucle for

    for(i=0;i<10;i+=2)

    {

    var += 2;

    }

    printf("el resultado es %i", var);

    Algunos lenguajes de
    programación tienen sentencias que permiten
    "escapar" de los bucles sin llegar a la condición de
    fin, como el romper o el
    devolver.

    Ejemplo escapando de un bucle en Visual
    Basic 1:

    Dim h&, var&

    var = 0

    'Codigo del
    Bucle

    do

    var = var + 2

    if var = 10 then 'Codigo para salir del
    bucle

    goto escape

    end if

    loop

    escape:

    print "El resultado es " & var

    Ejemplo escapando de un bucle en Visual
    Basic 2:

    Dim h&, var&

    var = 0

    'Codigo del Bucle

    do

    var = var + 2

    if var = 10 then 'Codigo para salir del
    bucle

    exit do

    end if

    loop

    print "El resultado es " & var

  2. Bucle

    El bucle
    for o ciclo for es una
    estructura
    de control en
    la que se puede indicar el número máximo de
    iteraciones. Está disponible en casi todos los
    lenguajes de programación
    imperativos.

    1. Elementos del bucle
    2. Variable de control:
      prácticamente un mandato impuesto por el uso habitual es utilizar
      la letra i como variable de control, o bien sus sucesoras
      en caso de bucles anidados. El uso de esta letra
      críptica quizás a primera vista es sin
      embargo una excelente forma de aportar agilidad de
      lectura al código por su uso
      tan extensivo. Como raras veces los bucles
      anidados superan las tres dimensiones (por una sencilla
      cuestión de explosión exponencial), las
      letras i, j y k suelen ser las únicas relacionadas
      con este uso. En C se define en el primer
      parámetro de la instrucción junto con la
      inicialización (opcional).
  3. Bucle for
  • Inicialización de la variable de
    control
    : en pseudolenguaje se pide explicitarlo (es la
    sección := ValorInicial), sin embargo, otros
    lenguajes más permisivos como C no lo requieren de forma
    obligatoria. De todos modos, la práctica de utilizar
    variables de
    control que no se inicializan en el bucle no es recomendada
    para la legibilidad del código. En C se define en el
    primer parámetro del bucle junto con la variable de
    control.
  • Condición de control: en pseudolenguaje
    se ve representado por el valor final
    que puede tomar la variable de control (la sección A
    ValorFinal
    ). En C es el segundo parámetro y puede
    ser cualquier condición (ni siquiera es
    obligación que esté la variable de control,
    aunque una vez más, esto no se considera una buena
    práctica).
  • Incremento: en pseudolenguaje se toma por
    defecto el valor 1, aunque puede explicitarse por medio de la
    sentencia PASO = ValorPaso cualquier número entero
    (léase bien entero, o sea que técnicamente
    podemos decrementar). En C es el último
    parámetro.
  • Cuerpo: es lo que se hará en cada
    iteración, pueden ser una o más instrucciones. En
    pseudolenguaje pesa la restricción de no poder
    alterar el valor de la variable de control; esto no es
    requerido en C, pero no se considera una buena
    práctica.
  1. Usos
  2. Su uso principal se orienta a los
    arreglos, pudiendo modificar,
    agregar, eliminar o consultar datos que se
    encuentren según el índice. Por esto
    último, una condición mínima del arreglo
    es que debe ser ordenado, por que si se intenta leer un dato
    inexistente, esto genera un error de
    programación
    .
  1. Teorema de Dijkstra

Un famoso teorema, demostrado por
Edsger Dijkstra en los años sesenta, demuestra
que todo programa puede
escribirse utilizando únicamente las tres instrucciones de
control siguientes:

  • El bloque secuencial de instrucciones,
    instrucciones ejecutadas sucesivamente.
  • La instrucción condicional alternativa, de la
    forma "IF condición THEN instrucción-1 ELSE
    instrucción-2".
    • Si la condición se cumple, se
      ejecutará "instrucción-1".
    • En caso contrario, se ejecuta
      "instrucción-2".
    • Abreviadamente, esta instrucción se suele
      llamar IF-THEN-ELSE.
  • El bucle condicional "WHILE condición DO
    instrucción", que ejecuta la instrucción
    repetidamente mientras la condición se
    cumpla.
    • En su lugar, se puede utilizar también la
      forma "UNTIL condición DO instrucción", que
      ejecuta la instrucción hasta que la condición
      se cumpla. Los dos bucles se diferencian entre sí
      porque en la forma WHILE la condición se comprueba
      al principio, por lo que es posible que la
      instrucción no se ejecute ni una sola
      vez.
    • En cambio,
      en la forma UNTIL la condición se comprueba al final
      del bucle, por lo que la instrucción se ejecuta
      siempre al menos una vez.

Los programas que
utilizan sólo estas tres instrucciones de control
básicas o sus variantes (como los bucles FOR o la
instrucción condicional CASE), pero no la
instrucción GOTO, se llaman estructurados.

La "programación estructurada"
(llamada también "programación sin GOTO") se
convirtió durante los años setenta en la forma de
programar más extendida.

A pesar de todo, la mayoría de los lenguajes
conservan la instrucción GOTO y las etiquetas de las
instrucciones, para utilizarla en casos muy especiales, aunque
normalmente se desaconseja su uso.
Entre los lenguajes de alto nivel, Pascal, C y Ada
pueden considerarse especializados en programación
estructurada, y aunque todos ellos permiten utilizar la
instrucción GOTO, se desaconseja su uso. En otros
lenguajes, tal como Léxico, se ha suprimido esa
instrucción por considerársele una fuente de
errores cuando se carece de experiencia en la lógica
de programación.

6.- Subprogramas,
paso de parámetros, implementación y
abstracción de datos

Subprogramas

Definición, declaración y
uso

Un subprograma es un procedimiento
(procedure) o una función
(function). La diferencia entre un procedimiento y una
función es que el primero sólo indica la
ejecución de una secuencia de instrucciones, en
función de unos parámetros, mientras que la segunda
representa un valor que se genera como resultado de su
ejecución. Se pueden usar funciones para
sobrecargar los operadores del lenguaje,
otorgándoles nuevos significados.

Definición de un subprograma.

La definición de un subprograma consta de tres
elementos: (1) cabecera, donde se fija su clase y
nombre, se describen sus parámetros formales y, si es una
función, se especifica el tipo de su resultado, terminando
todo ello con la palabra "is", expresando que a
continuación se desarrolla el subprograma, (2)
declaraciones locales, de cualquier elemento declarable (tipos,
variables, constantes, …), incluyendo la definición
anidada de otros subprogramas y (3) el bloque de sentencias
ejecutables del subprograma delimitado por las palabras
reservadas "begin" y "end" (esta última
suele ir acompañada del nombre del subprograma). Si el
subprograma es una función, entre las sentencias
ejecutables debe incluirse al menos una sentencia de retorno
("return") con una expresión que indique el valor a
devolver a quien la llamó; si la ejecución de una
función alcanza el final sin encontrar una sentencia de
retorno, se produce una excepción
"Program_Error",  dado que la sentencia de retorno se
utiliza en las funciones para especificar el valor a devolver. En
los procedimientos
puede omitirse la sentencia de retorno cuando el único
punto de retorno se encuentra al final, como en el siguiente
ejemplo.

procedure Intercambia(A,B: in out Integer)
is
   C: integer;
begin
   C := A;
   A := B;
   B := C;
end Intercambia;

function
Media(A,B: Float) return Float is
begin
   return (A + B) / 2.0;
end Media;

Las declaraciones locales están sujetas a
las reglas de ámbito generales de
Ada.

Un subprograma puede constituir por sí mismo
una unidad de librería o estar anidado
dentro de una unidad mayor. Si un subprograma está anidado
en una unidad mayor, la definición del subprograma debe
escribirse en una sección de declaraciones de esa
unidad.

procedure Principal is
    …
    procedure Intercambia(A,B: in
out
Integer) is
        …
    begin
        …
    end Intercambia;
    …
begin
    …
end Principal;

En un mismo ámbito se pueden tener varios
subprogramas con el mismo nombre, siempre que se diferencien en
los parámetros o en el tipo del resultado (si son
funciones). Esto se conoce como sobrecarga de
subprogramas
. La sobrecarga de operadores es una clase de
sobrecarga de subprogramas.


procedure Intercambia(A,B: in out Integer)
is
    …
begin
    …
end Intercambia;

procedure Intercambia(A,B: in out Float)
is
    …
begin
    …
end Intercambia;

Declaración de un subprograma.

En determinadas circunstancias (p.e. cuando un
subprograma se proporciona para ser usado desde un
paquete, cuando se define un subprograma
genérico o cuando hay referencias mutuas entre
subprogramas) se precisa escribir una declaración de un
subprograma separada de su definición. La
declaración de un subprograma es como su cabecera, pero
terminada en ";" en vez de con la palabra "is", para
expresar que lo que se está dando es una vista de un
subprograma cuya definición se haya en otro
lugar.

procedure Intercambia(A,B: in out
Integer);
function Media(A,B: Float) return Float;

Definición separada (separate).La
definición de un subprograma que está anidado en
otra unidad puede extraerse de la misma para compilarse por
separado, dejándolo indicado en la unidad matriz
mediante una declaración con cláusula
"separate". A efectos de reglas de ámbito es como
si la definición del subprograma estuviera donde
está dicha declaración. El subprograma separado
debe indicar quién es su unidad matriz.

procedure Ejemplo_Matriz is
    …
    — Indicación de que Intercambia se
desarrollará aparte
    procedure Intercambia(A,B: in
out
Integer) is separate;
    …
begin
    …
end Ejemplo_Matriz;

— Lo siguiente posiblemente irá en un fichero
diferente
separate(Ejemplo_Matriz)
procedure Intercambia(A,B: in out Integer)
is
    …
begin
    …
end Intercambia;

 

Llamada a un subprograma.

La llamada a un procedimiento constituye una sentencia,
mientras que la llamada a una función sólo puede
hacerse como parte de una expresión:

Intercambia(X,Y);
Z := Media(L,M);
if Media(L,M) > 5.0 then
return Media(L,M);

Parámetros.

Listas de parámetros formales.

El número, tipo y clase de los parámetros
formales se declara en una lista de parámetros
formales
que se pone justo después del nombre del
subprograma en la especificación del mismo. La lista de
parámetros formales se delimita por paréntesis y se
compone de una o varias sublistas de parámetros de la
misma clase y tipo separadas por punto y coma (";"). Cada
sublista est

    1. Las palabras parámetro y
      argumento, aunque de significado similar, tiene
      distintas connotaciones semánticas: Se denominan
      parámetros los tipos declarados en el
      prototipo (que deben corresponder con los declarados en
      la definición). Cuando se realiza una llamada a
      la función, los "valores" pasados se denominan
      argumentos. A veces se utilizan también
      las expresiones argumentos formales, para los
      parámetros y argumentos actuales para
      los
      valores pasados.

      Parámetros (en prototipo o
      definición)    argumentos
      formales

      Valores pasados (en tiempo de
      ejecución)    argumentos
      actuales

      La sintaxis utilizada para la
      declaración de la lista de parámetros
      formales es similar a la utilizada en la
      declaración de cualquier identificador.  A
      continuación se exponen varios
      ejemplos:

      int func(void)
      {…}     
           
            // sin
      parámetros
      inf func()
      {…}                     
      // ídem.
      int func(T1 t1, T2 t2, T3 t3=1) {…} // tres
      parámetros simples,
        
                                    
          // uno con argumento por defecto
      int func(T1* ptr1, T2& tref)
      {…}    // los argumentos son un
      puntero y
        
                                        
      // una referencia.
      int func(register int i)
      {…}        //
      Petición de uso de registro para
                                           
      // argumento (entero)
      int func(char* str,…) {…}
              /* Una
      cadena y cierto número de otros
                  
      argumentos, o un número fijo de argumentos de
      tipos variables */

        Los argumentos son siempre objetos. Sus tipos
      pueden ser: escalares; estructuras; uniones, o enumeraciones;
      clases definidas por el usuario; punteros o referencias
      a estructuras y uniones, o punteros a funciones, a
      clases o a matrices. El tipo
      void está
      permitido como único parámetro formal.
      Significa que la función no recibe ningún
      argumento.

      Nota: recuerde que cuando
      coloquialmente se dice que se pasa una matriz como
      argumento de una función, en realidad se
      está pasando un puntero a su primer elemento.
      Recuerde también que las funciones no
      pueden ser utilizadas como argumentos, pero sí
      pueden serlo los punteros-a-función, lo que a la
      postre, viene a ser equivalente.

        Es un error realizar una
      declaración en la lista de
      parámetros

      int func (int x, class C{…} c) { … } 
      // Error!!

        Todos los parámetros de una
      función tienen ámbito del bloque de la
      propia función y la misma duración
      automática que la función.

        El único especificador de
      almacenamiento que se permite es
      register. En la
      declaración de parámetros también
      pueden utilizarse los modificadores
      volatile y
      const. Este
      último se utiliza cuando se pasan argumentos por
      referencia y queremos garantizar que la función
      no modificará el valor recibido.
      Ejemplo:

      int dimension(X x1, const X&
      x2)      // x2 NO se
      puede modificar!!

    2. Sinopsis

      C++ permite tener valores por defecto para los
      parámetros. Esto supone que, si no se pasa el
      parámetro correspondiente, se asume un valor
      predefinido. La forma de indicarlo es declararlo en el
      prototipo de la función, como se muestra en el ejemplo (ambas expresiones
      son equivalentes).

      float mod (float x, float y = 0);
      float mod (float, float = 0);

      Más tarde no es necesario, ni
      posible, indicarlo de nuevo en la definición.
      Por ejemplo:

      float mod (float, float =
      0);    // prototipo

      float mod (float x, float y = 0) { return x + y; } //
      Error!!
      float mod (float x, float y) { return x + y;
      }     // definición
      Ok

      Si declaración y definición
      están en una sola sentencia entonces si
      es necesario indicar los valores por defecto. Ejemplo,
      en la sentencia:

      float mod (float x, float y = 0) { return
      pow(x*x + y*y, 0.5); }

      La ausencia de un segundo argumento en la
      invocación hace que se adopte para él un
      valor 0 (podría haber sido cualquier otro
      valor). En este contexto, la función mod
      aceptaría estas dos llamadas como correctas y de
      resultados equivalentes:

      m1 = mod (2.0 , 0);
      m2 = mod (2.0);

        Un argumento por defecto no puede ser repetido o
      cambiado en una siguiente declaración dentro del
      mismo ámbito. Por ejemplo:

      void func (int x = 5);

      void func (int x = 5);    // Error:
      repetición de argumento por defecto
      {                        
      // nuevo ámbito
          void func (x = 7);   
      // L.4 Correcto: esta función oculta a la
      anterior
      }                        
      // el ámbito anterior vuelve a ser visible
      void func (x =
      7);        // Error:
      cambiar argumento por defecto

      Nota: a pesar de que la
      expresión de la línea 4 es correcta,
      tenga en cuenta que las declaraciones en ámbitos
      anidados que ocultan declaraciones del mismo nombre en
      ámbitos externos, suele ser fuente de errores y
      confusiones.

        Es muy de tener en cuenta esta regla en
      la definición de clases, ya que en ellas es
      frecuente que la declaración de métodos se realice en un punto
      (el cuerpo de la clase), y la definición se
      realice "off-

      line" (fuera del cuerpo de la clase). En caso
      que el método tenga argumentos por
      defecto recuerde no repetirlos más tarde
      en la definición.

        La gramática de C++ exige que los
      parámetros con valores por defecto deben ser los
      últimos en la lista de parámetros, y que
      si en una ocasión falta algún argumento,
      los que le siguen también deben faltar (adoptar
      también los valores por defecto).

      Nota: como puede verse, C++ no admite
      la posibilidad de otros lenguajes de saltarse
      parámetros por defecto incluyendo una coma sin
      ningún valor en la posición
      correspondiente, por ejemplo:

      int somefunc (int, int = 1, char, long); 
      // Incorrecto!!
      ….
      x = somefunc ( 33, , 'c', 
      3.14);        
      // Error! No aceptable en C++
      x = somefunc (int, char*, char* = 0);

        Observe que en este último caso,
      el espacio de separación entre char* y = es
      importante, ya que *= es un operador de
      asignación. Así pues:

      x = somefunc (int, char*, char*=
      0);    // Error!


        Los argumentos por defecto
      de métodos (funciones-miembro de clases)
      no pueden ser otros miembros a no ser que sean
      estáticos. Ejemplo:

      class C {

        int v1;

        void foo(char, int =
      v1);    // Error!!

      };

      class B {

        static int v1;

        void foo(char, int =
      v1);    // Ok.

      }

      Un posible diseño de la clase C
      podría ser:

      class C {

        int v1;

        void foo(char, int =
      -1);    // Ok

      };

      más tarde, en la definición del
      método hacer:

      void C::foo(char a, int x) {

        if (x == -1) x = v1;

        …

      }

      Los argumentos por defecto no pueden
      ser otros argumentos:

      x = somefunc (int x, int y =
      x);    // Error!

        Los argumentos pasados por referencia
      solo pueden adoptar valores por defecto
      estáticos, globales o de un subespacio
      cualificado. Ejemplo:

      namespace ALPHA {
        long n = 20.10L;
      }
      long n = 10.10L;
      void f1 (long& lg = ALPHA::n);   //
      Ok.

      void f2 (long& lg =
      n);         
      // Ok.
      void f3 (long lg =
      10.2L);       // Ok.
      void f4 (long& lg = 10.2L
      );     // Error!!

    3. Argumentos por defecto

      Existen dos formas de pasar argumentos a las
      funciones: por valor y por
      referencia
      . El primero es utilizado por defecto con
      la declaración usual de parámetros. En el
      paso "por valor", se crean copias de los argumentos
      pasados a la función, los cuales, junto a las
      variables locales (incluyendo el posible valor
      devuelto), y la dirección de vuelta a la rutina
      que efectúa la invocación, son pasados a
      la pila en la secuencia de llamada. Más
      tarde, cuando termina su ejecución
      definitivamente, es decir, cuando el control vuelve a
      la función que la invocó, toda esta
      información es sacada de la pila
      mediante la secuencia de retorno (y se pierde).
      Estos procesos suponen un consumo de tiempo y espacio (memoria), a veces
      considerable.

    4.   Argumentos: por valor y por
      referencia

      Hemos visto que el paso de parámetros
      por valor significa que existen copias de los
      argumentos formales (estas copias son variables locales
      de la función llamada), y que una función
      no puede alterar ninguna variable de la función
      que la invocó.

        La única excepción es el
      caso de las matrices. Cuando se utiliza una matriz como
      argumento en la llamada a una función, el valor
      pasado es un puntero a la dirección de memoria
      del principio de la matriz.

        Cuando los argumentos pasan por valor
      pero no hay concordancia entre el tipo de los
      argumentos actuales y los argumentos formales
      utilizados en la declaración de la
      función, entonces se produce un modelado de tipo
      antes de la asignación. Supongamos el
      ejemplo:

      void func(int x) {   //
      definición de func.  Acepta un
      entero

         x = x * 2;

      }

      float f = 3.14;

      func(f);       //
      f es promovido a int antes de asignación a
      'x'

                     //
      x == 6

      Lo que sucede en estos casos es que la copia
      local f en func(x) es modificada para hacerla coincidir
      con el tipo esperado por la función, mientras
      que el valor original (f) permanece
      inalterado.

    5.   Paso por valor

      En C clásico, cuando se desea que la
      función llamada pueda alterar el valor de
      variables de la función que la invoca, o ahorrar
      el espacio que supone la copia local de los argumentos
      (que pueden ser estructuras de datos muy grandes), la
      solución consistía en utilizar punteros a
      las variables respectivas como argumentos para la
      función (en vez de pasar las variables en
      sí mismas). A su vez, la función llamada
      debía declarar el parámetro como puntero,
      y acceder a la variable indirectamente a través
      de él. En otras palabras: cuando en C se desea
      que un valor X pase a una función F y que
      esta pueda alterar el valor de X en la función
      que la invocó, el argumento utilizado es &X
      (la dirección de X). De esta forma, aunque
      F recibe una copia de &X, puede alterar el
      valor original a través de esta
      dirección. Esta técnica puede tener sus
      ventajas.  Por ejemplo, si X es una estructura muy
      grande, pero puede tener efectos colaterales
      peligrosísimos y ser una fuente de errores
      difíciles de detectar.

    6. Pasar un puntero

      Por supuesto, C++ permite utilizar la
      técnica del C clásico descrita arriba,
      pero también utilizar el paso de argumentos
      por referencia (en realidad es una variante
      semántica del proceso anteriormente descrito). Para
      ello se utiliza el declarador de referencia
      &.

      Las referencias presentan las ventajas de los
      punteros, en el sentido que permiten modificar los
      valores de los objetos pasados como argumento, y de que
      permiten ahorrar espacio si hay que pasar objetos muy
      grandes, pero no presentan los peligros potenciales de
      aquellos. En caso necesario las referencias pueden
      declararse constantes, indicando así que la
      función invocada no modificará
      estos valores. En estos casos, la utilización de
      referencias obedece casi exclusivamente a razones de
      eficacia en el mecanismo de
      llamada.

      Nota: en ocasiones el paso por
      referencia tiene una justificación de tipo
      físico. Es el caso en que los objetos utilizados
      como argumento representan dispositivos físicos.
      Por ejemplo, ficheros externos o dispositivos de
      comunicación. En estas
      circunstancias, el objeto no puede ser copiado
      alegremente por el mecanismo de invocación de
      funciones (que utilizaría el constructor-copia
      de la clase) si se utilizaran pasos por valor, y es
      necesario recurrir al paso por referencia.

      Otro uso muy común de las referencias
      es cuando la función debería devolver
      distintos valores.  Por ejemplo, supongamos que
      nos interesa que una función foo, devuelva
      cuatro valores: dos
      int posX y posY;
      una cadena de caracteres
      char* nombre, y un
      float altura.  Como una función no puede
      devolver más de un valor (al menos, no de forma
      directa), recurrimos a construir una estructura con los
      valores adecuados.  Esta estructura será
      pasada a la función por referencia, de forma que
      sus miembros podrán ser modificados desde el
      cuerpo de la función.  Una vez realizada la
      invocación, puede considerarse que la mencionada
      estructura contiene los valores "devueltos"
      [],
      aunque en realidad la función no devuelva nada
      (en el ejemplo que sigue devuelve
      void).

      El esquema de funcionamiento sería el
      siguiente:

      struct ST {
        int posX; 
        int posY;
        char* nombre;
        float altura;
      };

      void foo (ST& st) {
        …
        st.posX = value1;
        st.posY = value2;
        st.nombre = value3;
        st.altura = value4;
      }
       
      int main () { // =========
        …
        ST st;
        foo(st);

        cout << "Las coordenadas son: x =
      " << st.posX << "; y = " << st.posY
      << endl;

        cout << "es el punto <<
      st.nombre << " de altitud << st.altura
      << " metros" << endl;
        …
      }

    7.   Paso por referencia

      A continuación se muestran tres
      implementaciones de una misma función; cada una
      con una forma distinta para paso del
      argumento.

      Implementación-1:   
      Sistema clásico, paso "por
      valor
      "

      int pru1(int n) {   // n
      entero; pasa "por valor"

         return 3 * n;

      }

      int x, i = 4;

      x = pru1(i);        // ahora:
      x = 12, i = 4

      int& ry = i;

      x = pru
      (ry);       // ahora: x =
      12, i = 4

      Observe que la última sentencia no es
      un paso por referencia, sino por valor (a pesar de que
      el argumento actual sea una referencia).


      Implementación-2:  
      Sistema
      clásico, paso de "punteros por valor"
      (seudo-referencia)

      void pru2(int* np) {  //
      np puntero-a-entero; pasa "por valor"
         *np = (*np) * 3;

      }
        . . .
      int x = 4;
      pru2(&x);             // ahora
      x = 12

      Observe que en este caso, pasar el valor
      &x (dirección de x) como argumento, es
      equivalente a pasar un puntero a dicha variable (que es
      lo exigido en la definición de pru2). Es decir,
      la última línea se puede sustituir por
      las siguientes:

      int* ptr =
      &x         //
      define puntero-a-x
      pru2(ptr);            //
      pasa el puntero como argumento


      Implementación-3:   
      Sistema
      C++,  paso "por referencia"

      void pru3(int& n) { // n tipo
      "referencia-a-int"; pasa "por referencia"
         n = 3 * n;
      }
        . . .
      int x = 4;
      pru3(x);            // ahora
      x = 12

        Atención a la sintaxis:
      aquí la invocación a pru3 tiene la
      forma:  pru3(x), no pru3(&x) como en el
      caso anterior. Es decir, la notificación de que
      el argumento pasa por referencia hay que hacerla en la
      definición de la función, y no es
      necesario indicarlo en el momento de la
      invocación.

      En este último caso, la
      declaración int& n como parámetro de
      la función pru3, establece que este n sea
      declarado como "referencia-a-entero", de forma que
      cuando se pasa el argumento x, la función crea
      un valor n que es una especie de alias o espejo de x,
      de forma que la expresión n = 3*n tiene el mismo
      efecto que x = 3*x.

        Ya hemos visto que cuando, en la
      declaración de una referencia, el iniciador es
      una constante, o un objeto de tipo diferente que el
      referenciado, se crea un objeto temporal para el que la
      referencia actúa como un alias. Esta
      creación de objetos temporales es lo que permite
      la conversión de tipos referencia-a-tipoX
      cuando se utilizan como parámetros de funciones
      y no hay concordancia entre el valor recibido y el
      esperado (suponiendo que exista posibilidad de
      conversión). Este sería el mecanismo
      utilizado en el siguiente caso:

      void pru(int& n) { // n tipo
      "referencia-a-int" (pasa "por referencia")
         n = 3 * n;
      }
        . . .
      float f = 4.1;
      pru(f);
                 // ahora
      f = 12

    8. Comparativa
    9.   Ejemplo
  1. Parámetros y argumentos

En el programa que sigue se muestra un caso de paso por
referencia y acceso a subespacios.

#include <iostream.h>

namespace ALPHA {
   class CAlpha {
     int x;
     public:
     int getx(void) { return x; }
     void putx(int i) { x = i; }
   };
   CAlpha
CA1;          
// instancia de CAlpha (en ALPHA)
}
int func (ALPHA::CAlpha& ca, int i);  /* prototipo:
ca es la referencia
                         
a un objeto de la clase CAlpha en ALPHA */

int main (void) {        //
========================
  int x = 0;
  cout << "x = " << x << endl;
  ALPHA::CA1.putx(10);   // invocación al
método putx de CA1
  x = func(ALPHA::CA1, 3);
  cout << "x = " << x << endl;
}

int func (ALPHA::CAlpha& ca, int i) {  //
definición
  return (i + ca.getx());
}

Salida:

x = 0
x = 13

Conceptos de implementación

Esta sección trata sobre las consideraciones
principales a la hora de implementar las aplicaciones de
C++.

  1. Los proyectos de
    Visual C++
    utilizan normalmente la instalación de Windows
    Installer tradicional para la implementación. Para
    preparar una implementación con Windows Installer, se
    ha de empaquetar la aplicación en un archivo
    setup.exe y distribuir este archivo junto con un paquete del
    instalador (.msi). A continuación, los usuarios
    ejecutarán setup.exe para instalar la
    aplicación.

    La aplicación se empaqueta agregando un
    proyecto de
    instalación a la solución; una vez generado,
    crea los archivos del
    paquete del instalador y de configuración que se
    distribuyen a los usuarios. Para obtener más
    información.

  2. Implementación de Windows
    Installer en C++

    Cuando una aplicación de C/C++ se genera
    utilizando una funcionalidad proporcionada por las bibliotecas de Visual C++, se hace dependiente
    en presencia de dichas bibliotecas en tiempo de
    ejecución. Para que la aplicación se ejecute,
    se debe vincular, estática o dinámicamente, a las
    bibliotecas de Visual C++ necesarias. Si una
    aplicación se vincula dinámicamente a una
    biblioteca
    de Visual C++, cuando se ejecute, esa biblioteca debe estar
    presente para que se pueda cargar. Por otro lado, si la
    aplicación se vincula estáticamente a una
    biblioteca de Visual C++, no es necesario que el archivo DLL
    correspondiente esté presente en el equipo del
    usuario. Sin embargo, la vinculación estática
    tiene algunos efectos negativos, como el aumento del
    tamaño de los archivos de la aplicación y la
    posibilidad de que el mantenimiento sea más
    difícil.

    Las bibliotecas de Visual C++ se empaquetan como
    archivos DLL y todas las bibliotecas necesarias para las
    aplicaciones de C/C++ las instala Visual Studio en el equipo
    del desarrollador. Sin embargo, al implementar la
    aplicación para sus usuarios, no es factible en muchos
    casos pedirles que instalen Visual Studio para ejecutar la
    aplicación. Es importante redistribuir solamente las
    partes de Visual C++ que necesita la aplicación para
    ejecutarse correctamente.

    Abstracción

    Abstracción consiste en aislar un elemento de
    su contexto o del resto de los elementos que lo
    acompañan. En programación,
    el término se refiere al énfasis en el
    "¿qué hace?" más que en el
    "¿cómo lo hace?" (Característica de caja
    negra). El común denominador en la evolución de
    los lenguajes de programación, desde los
    clásicos o imperativos hasta los orientados a objetos,
    ha sido el nivel de abstracción del que cada uno de
    ellos hace uso.

    Los lenguajes de
    programación son las herramientas mediante las cuales los
    diseñadores de lenguajes pueden implementar los
    modelos
    abstractos. La abstracción ofrecida por los lenguajes
    de programación se puede dividir en dos
    categorías: abstracción de datos
    (pertenecientes a los datos) y abstracción de control
    (perteneciente a las estructuras de
    control).

    Los diferentes paradigmas
    de programación han aumentado su nivel de
    abstracción, comenzando desde los
    lenguajes máquina, lo más
    próximo al ordenador y más lejano a la
    comprensión humana; pasando por los lenguajes de
    comandos, los
    imperativos, la orientación a objetos (OO), la
    Programación Orientada a Aspectos (POA); u otros
    paradigmas como la Programación Declarativa,
    etc…

    La abstracción encarada desde el punto de
    vista de la programación orientada
    a objetos expresa las
    características esenciales de un
    objeto, las cuales distinguen al objeto de los demás.
    Además de distinguir entre los objetos provee límites conceptuales. Entonces se puede
    decir que la encapsulación separa las
    características esenciales de las no esenciales dentro
    de un objeto. Si un objeto tiene más
    características de las necesarias los mismos
    resultarán difíciles de usar, modificar,
    construir y comprender.

    La misma genera una ilusión de simplicidad
    dado a que minimiza la cantidad de características que
    definen a un objeto.

    Durante años, los programadores se han
    dedicado a construir aplicaciones muy parecidas que
    resolvían una y otra vez los mismos problemas.
    Para conseguir que los esfuerzos de los programadores puedan
    ser utilizados por otras personas se creó la POO. Que
    es una serie de normas de
    realizar las cosas de manera que otras personas puedan
    utilizarlas y adelantar su trabajo,
    de manera que consigamos que el código se pueda
    reutilizar.

    La POO no es difícil, pero es una manera
    especial de pensar, a veces subjetiva de quien la programa,
    de manera que la forma de hacer las cosas puede ser diferente
    según el programador. Aunque podamos hacer los
    programas de formas distintas, no todas ellas son correctas,
    lo difícil no es programar orientado a objetos sino
    programar bien. Programar bien es importante porque
    así nos podemos aprovechar de todas las ventajas de la
    POO

    1. Pensar en términos de objetos es muy
      parecido a cómo lo haríamos en la vida
      real. Por ejemplo vamos a pensar en un coche para tratar
      de modelizarlo en un esquema de POO. Diríamos que
      el coche es el elemento principal que tiene una serie de
      características, como podrían ser el
      color,
      el modelo
      o la marca.
      Además tiene una serie de funcionalidades
      asociadas, como pueden ser ponerse en marcha, parar o
      aparcar.

      Pues en un esquema POO el coche sería el
      objeto, las propiedades serían las
      características como el color o el modelo y los
      métodos serían las funcionalidades
      asociadas como ponerse en marcha o parar.

      Por poner otro ejemplo vamos a ver cómo
      modelizaríamos en un esquema POO una
      fracción, es decir, esa estructura matemática que tiene un numerador y
      un denominador que divide al numerador, por ejemplo
      3/2.

      La fracción será el objeto y
      tendrá dos propiedades, el numerador y el
      denominador. Luego podría tener varios
      métodos como simplificarse, sumarse con otra
      fracción o número, restarse con otra
      fracción, etc.

      Estos objetos se podrán utilizar en los
      programas, por ejemplo en un programa de matemáticas harás uso de
      objetos fracción y en un programa que gestione un
      taller de coches utilizarás objetos coche. Los
      programas Orientados a objetos utilizan muchos objetos
      para realizar las acciones que se desean realizar y ellos
      mismos también son objetos. Es decir, el taller de
      coches será un objeto que utilizará objetos
      coche, herramienta, mecánico, recambios,
      etc.

      7. Manejo
      de excepciones y concurrencia

      El Manejo de excepciones es una
      estructura de control de los lenguajes de
      programación diseñada para manejar
      condiciones anormales que pueden ser tratadas por el
      mismo programa que se desarrolla.

      Por ejemplo, un programa puede admitir
      cierto número de errores en el formato de los
      datos y continuar su proceso para producir el mejor
      resultado posible en lugar de producir una salida
      aparatosa llena de mensajes de error probablemente
      incomprensibles para el usuario. Muchas veces la
      acción asociada a una excepción es
      simplemente producir un mensaje informativo y terminar,
      otras veces, es sólo indicación de la
      necesidad de un cambio en la estrategia de resolución del
      problema.

      Algunos lenguajes de programación, por
      ejemplo Lisp, Ada, C++, C#, Delphi, Objective C, Java,
      PHP ,
      Python ,Eiffel y Ocaml incluyen soporte para el manejo de
      excepciones. En esos lenguajes, al producirse una
      excepción se desciende en la pila de
      ejecución hasta encontrar un manejador para la
      excepción, el cual toma el control en ese
      momento.

      Ejemplo de manejo de excepción en
      Java:

      import java.io.IOException;

      // …

      public static void main(String[] args)
      {

      try {

      // Se ejecuta algo que puede producir una
      excepción

      } catch (IOException e) {

      // manejo de una excepción de
      entrada/salida

      } catch (Exception e) {

      // manejo de una excepción
      cualquiera

      } finally {

      // código a ejecutar haya o no
      excepción

      }

      }

      Ejemplo de manejo de excepción en
      Delphi:

      procedure TForm1.Button1Click(Sender :
      TObject);

      begin

      try

      try

      a := b / c;

      finally

      // Este código siempre se ejecuta,
      independientemente de si ocurre o no una
      excepción.

      end;

      except

      on e:EZeroDivide do

      // Manejo de la excepción División
      por cero.

      on e:Exception do

      // Manejo de una excepción
      "genérica".

      end;

      end;

      Concurrencia:

      (concurrency). En computación, la concurrencia es la
      propiedad de los sistemas que permiten que
      múltiples procesos sean
      ejecutados al mismo tiempo, y que potencialmente puedan
      interactuar entre sí.

      Los procesos concurrentes pueden ser
      ejecutados realmente de forma simultánea,
      sólo cuando cada uno es ejecutado en diferentes
      procesadores. En cambio, la concurrencia
      es simulada si sólo existe un procesador encargado de ejecutar los
      procesos concurrentes, simulando la concurrencia,
      ocupándose de forma alternada en uno y otro
      proceso a pequeñísimos intervalos de
      tiempo. De esta manera simula que se están
      ejecutando a la vez.

      Debido a que los procesos concurrentes en un
      sistema pueden interactuar entre otros
      también en ejecución, el número de
      caminos de ejecución puede ser extremadamente
      grande, resultando en un comportamiento sumamente complejo. Las
      dificultades asociadas a la concurrencia han sido
      pensadas para el desarrollo de lenguajes
      de programación y conceptos
      que permitan hacer la concurrencia más
      manejable.

      8.
      Lenguajes imperativos

      En ciencias de la computación se
      llama lenguajes
      imperativos
      a
      aquellos en los cuales se le ordena a
      la
      computadora cómo realizar una tarea siguiendo
      una serie de pasos o instrucciones, por
      ejemplo:

      Paso 1, solicitar número.

      Paso 2, multiplicar número por
      dos.

      Paso 3, imprimir resultado de la
      operación.

      Paso 4, etc,

      Algunos ejemplos de lenguajes imperativos son:
      BASIC, C, C++, Java, Clipper, Dbase, C# y
      Perl.

      1. Paradigma imperativo
    2. Ejemplo
  3. Dependencias de la biblioteca

Los lenguajes de programación que cumplen el
paradigma
imperativo se caracterizan por tener un estado
implícito que es modificado mediante instrucciones o
comandos del lenguaje. Como resultado, estos lenguajes tienen una
noción de secuenciación de los comandos para
permitir un control preciso y determinista del estado.

  • Definición de procedimientos
  • Definición de tipos de
    datos
  • Chequeo de tipos en tiempo de
    compilación
  • Cambio de estado de variables
  • Pasos de ejecución de un proceso

A.- Funciones

En el ámbito de la
programación, una función es un
tipo subalgoritmo, es el término para describir una
secuencia de órdenes que hacen una tarea específica
de una aplicación más grande.

Las declaraciones de funciones generalmente son
especificadas por:

  • Un nombre único en el
    ámbito.- Nombre de la función con el
    que se identifica y se distingue de otras. No podrá
    haber otra función ni procedimiento con ese nombre
    (salvo sobrecarga o polimorfismo en programación
    orientada a objetos).
  • Un tipo de dato de retorno.-
    Tipo de dato del valor que la función
    devolverá al terminar su
    ejecución.
  • Una lista de
    parámetros.- Especificación del
    conjunto de argumentos (pueden ser cero, uno o más) que
    la función debe recibir para realizar su
    tarea.
  • El código u órdenes de
    procesamiento
    .- Conjunto de órdenes y sentencias que
    debe ejecutar la función.

La diferencia entre funciones y los
procedimientos (otro tipo de subalgotitmos) radica en
que estos últimos no devuelven un
resultado.

Las funciones en programación generalmente
son las que realizan los cálculos para retornar el
valor correspondiente a una función matemática
más o menos compleja.

Ej: La siguiente función en C
es la analogía al cálculo
del promedio matemático. El nombre "Promedio", retorna un
valor decimal correspondiente a la suma de 2 valores enteros de
entrada (A,B):

float Promedio(int A, int B){

float r;

r=(A+B)/2.0;

return r;

}

Así una llamada a Promedio(3,5)
retornará el valor real (float)
4.0.

B.- Declaraciones

Una declaración es una construcción del lenguaje que asocia un
nombre con una entidad. Ada distingue cuidadosamente entre
declaraciones (que introducen nuevos identificadores) y
sentencias (que utilizan dichos identificadores). Hay dos clases
de declaraciones:

  • Implícitas: que ocurren como
    consecuencia de la semántica de otra
    construcción.
  • Explícitas: aparecen en el texto del
    programa y pueden ser:
    • Declaraciones de tipo,
      subtipos, variables y constantes (objetos), excepciones,
      especificaciones de subprogramas o paquetes,
      cláusulas de representación o
      cláusulas use.
    • Los cuerpos de los subprogramas, paquetes
      y tareas.
  1. En ocasiones es necesario utilizar
    declaraciones de subprogramas, por ejemplo, si se va a
    utilizar la recursividad entre dos
    procedimientos:

    procedure P; — Declaración de P,
    necesaria para utilizara en Q.

    procedure Q is — Cuerpo de Q.

    begin

    P;

    — …

    end Q;

    procedure P is — Repite especificación
    para declarar el cuerpo.

    begin

    Q;

    — …

    end P;

    También puede resultar útil declarar
    las especificaciones de los subprogramas en el comienzo del
    programa a modo de índice, sobre todo si hay muchos
    cuerpos.

  2. Declaraciones de
    subprogramas
  3. Vista de una
    entidad

Todas las declaraciones contienen una definición
de vista de una entidad. Una vista consiste en:

  • Características específicas de la vista
    que afectan al uso de la entidad a través de dicha
    vista.

En la mayoría de los casos, una
declaración contiene la definición de la vista y de
la entidad misma, pero una declaración de renombrado, sin
embargo, no define una entidad nueva, sino que define una nueva
vista de una entidad.

  1. Parte
    declarativa

Una secuencia de declaraciones constituye una parte
declarativa. Las siguientes construcciones de Ada tienen
asociada una parte declarativa:

  • Bloque.
  • Cuerpo de un subprograma.
  • Cuerpo de un paquete.
  • Cuerpo de una tarea.
  • Cuerpo de una entrada a un objeto
    protegido.

Por ejemplo, en un procedimiento, la parte declarativa
comprendería las sentencias entre procedure y begin. El
cuerpo de un procedimiento puede contener en su parte declarativa
el cuerpo de otro procedimiento. Por tanto, los procedimientos
pueden ser declarados sin límite de niveles de anidamiento
sucesivos.

En ocasiones, las declaraciones requieren una segunda
parte (se dice que requieren una terminación). La
declaración y su terminación deben tener el mismo
nombre y deben ocurrir en la misma región declarativa. Por
ejemplo, un paquete necesita un cuerpo (que sería la
terminación) si en su parte declarativa contiene alguna
declaración que requiere una terminación que no se
encuentre en dicha declaración.

  1. Región declarativa de una
    declaración

Hay que distinguir entre región declarativa de
una declaración y parte declarativa. En el supuesto de una
declaración de una variable (por ejemplo I:
Integer := 0;) se extiende por una región de texto
que abarca sólo una línea, sin embargo, otras
declaraciones más complejas como procedimientos y paquetes
constituyen muchas más líneas de texto. En
Ada, existen las siguientes construcciones que tienen
asociada una región declarativa:

  • Cualquier declaración que no sea
    terminación de otra.
  • Bloque
  • Bucle
  • Construcción accept.
  • Manejador de excepción.

La región declarativa de cada una de estas
construcciones comprende:

  • El texto de la construcción misma.
  • Texto adicional, determinado de esta
    manera:
    • Si una declaración está
      incluida en la región, también lo está
      su terminación.
    • Si una unidad de biblioteca
      está incluida en la región, también lo
      están sus unidades hijas.
    • Si está incluido el requerimiento de
      compilación separada, también lo está
      su subunidad
      correspondiente.

Así, se pueden extraer las siguientes
conclusiones:

  • La especificación de un paquete y su
    cuerpo forman parte de la misma región declarativa
    porque el cuerpo es la terminación de la
    especificación, por lo que no se puede declarar la misma
    variable en la especificación y en el
    cuerpo.
  • Ya que la declaración y el cuerpo de un
    paquete pueden estar en compilaciones distintas, la
    región declarativa de una declaración de paquete
    puede abarcar porciones de texto en varias unidades de
    compilación distintas.
  • Todas las unidades de biblioteca son hijas de
    Standard, luego toda unidad de biblioteca
    pertenece a su región
    declarativa.

C.- Orientación a objetos

La Programación Orientada a Objetos (POO
u
OOP según sus siglas en inglés)
es un paradigma de programación que usa objetos y sus
interacciones para diseñar aplicaciones y programas de
computadora.
Está basado en varias técnicas,
incluyendo herencia,
modularidad, polimorfismo, y encapsulamiento. Su uso se
popularizó a principios de la
década de 1990. Actualmente son muchos los lenguajes de
programación que soportan la orientación a
objetos.

  1. Los objetos son entidades que combinan
    estado, comportamiento e identidad:
  • El estado está compuesto de
    datos, serán uno o varios atributos a los que se
    habrán asignado unos valores concretos
    (datos).
  • El comportamiento está definido por los
    procedimientos o métodos con que
    puede operar dicho objeto, es decir, qué operaciones se
    pueden realizar con él.
  • La identidad es una propiedad de un objeto que
    lo diferencia del resto, dicho con otras palabras, es su
    identificador (concepto
    análogo al de identificador de una
    variable o una constante).

La programación orientada a objetos
expresa un programa como un conjunto de estos objetos, que
colaboran entre ellos para realizar tareas. Esto permite hacer
los programas y módulos más fáciles de
escribir, mantener y reutilizar.

De esta forma, un objeto contiene toda la
información que permite definirlo e identificarlo frente a
otros objetos pertenecientes a otras clases e incluso frente a
objetos de una misma clase, al poder tener valores bien
diferenciados en sus atributos. A su vez, los objetos disponen de
mecanismos de interacción llamados
métodos que favorecen la
comunicación entre ellos. Esta comunicación
favorece a su vez el cambio de estado en los propios objetos.
Esta característica lleva a tratarlos como unidades
indivisibles, en las que no se separan ni deben separarse
el estado y el
comportamiento.

Los métodos (comportamiento) y atributos (estado)
están estrechamente relacionados por la propiedad de
conjunto. Esta propiedad destaca que una clase requiere de
métodos para poder tratar los atributos con los que
cuenta. El programador debe pensar
indistintamente en ambos conceptos, sin separar ni darle mayor
importancia a ninguno de ellos, hacerlo podría producir el
hábito erróneo de crear clases contenedoras de
información por un lado y clases con métodos que
manejen a las primeras por el otro. De esta manera se
estaría realizando una programación estructurada
camuflada en un lenguaje de programación orientado a
objetos.

Esto difiere de la
programación estructurada tradicional, en la
que los datos y los procedimientos están separados y sin
relación, ya que lo único que se busca es el
procesamiento de unos datos de entrada para obtener
otros de salida. La programación
estructurada anima al programador a pensar sobre todo en
términos de procedimientos o funciones, y en segundo lugar
en las estructuras de datos que esos procedimientos manejan. En
la programación estructurada sólo se escriben
funciones que procesan datos. Los programadores que emplean
éste nuevo paradigma, en cambio, primero definen objetos
para luego enviarles mensajes solicitándoles que realicen
sus métodos por sí mismos.

Los conceptos de la programación orientada a
objetos tienen origen en Simula 67, un lenguaje diseñado
para hacer simulaciones, creado por Ole-Johan
Dahl y Kristen Nygaard del Centro de
Cómputo Noruego en Oslo. Al parecer, en este centro,
trabajaban en simulaciones de naves, y fueron confundidos por la
explosión combinatoria de cómo las diversas
cualidades de diversas naves podían afectar unas a las
otras. La idea ocurrió para agrupar los diversos tipos de
naves en diversas clases de objetos, siendo responsable cada
clase de objetos de definir sus propios datos y
comportamiento. Fueron refinados más tarde en Smalltalk,
que fue desarrollado en Simula en Xerox PARC (y cuya primera
versión fue escrita sobre Basic) pero diseñado para
ser un sistema completamente dinámico en el cual los
objetos se podrían crear y modificar "en marcha" en lugar
de tener un sistema basado en programas
estáticos.

La programación orientada a objetos tomó
posición como el estilo de programación dominante a
mediados de los años ochenta, en gran parte debido a la
influencia de C++, una extensión del
lenguaje de programación C. Su dominación fue
consolidada gracias al auge de las Interfaces gráficas de usuario, para las cuales la
programación orientada a objetos está
particularmente bien adaptada. En este caso, se habla
también de programación dirigida por eventos.

Las características de orientación a
objetos fueron agregadas a muchos lenguajes existentes durante
ese tiempo, incluyendo Ada, BASIC, Lisp,
Pascal, entre otros. La adición de estas
características a los lenguajes que no fueron
diseñados inicialmente para ellas condujo a menudo a
problemas de compatibilidad y a la capacidad de mantenimiento del
código. Los lenguajes orientados a objetos "puros", por
otra parte, carecían de las características de las
cuales muchos programadores habían venido a depender. Para
saltar este obstáculo, se hicieron muchas tentativas para
crear nuevos lenguajes basados en métodos orientados a
objetos, pero permitiendo algunas características
imperativas de maneras "seguras". El Eiffel
de Bertrand Meyer fue un temprano y moderadamente acertado
lenguaje con esos objetivos pero
ahora ha sido esencialmente reemplazado por
Java, en gran parte debido a la aparición de
Internet, y a la
implementación de la máquina virtual de Java en la
mayoría de navegadores.
PHP en su versión 5 se ha ido modificando y soporta una
orientación completa a objetos, cumpliendo todas las
características propias de la orientación a
objetos.

La programación orientada a objetos es una
nueva forma de programar que trata de encontrar una
solución a estos problemas. Introduce nuevos conceptos,
que superan y amplían conceptos antiguos ya conocidos.
Entre ellos destacan los siguientes:

  • Objeto: entidad provista de un conjunto de
    propiedades o atributos (datos) y de comportamiento o
    funcionalidad (métodos). Corresponden a los objetos
    reales del mundo que nos rodea, o a objetos internos del
    sistema (del programa). Es una instancia a una
    clase.—
  • Clase: definiciones de las propiedades y
    comportamiento de un tipo de objeto concreto. La
    instanciación es la lectura
    de estas definiciones y la creación de un objeto a
    partir de ellas.
  • Método: algoritmo
    asociado a un objeto (o a una clase de
    objetos), cuya ejecución se desencadena tras la
    recepción de un "mensaje". Desde el punto de vista del
    comportamiento, es lo que el objeto puede hacer. Un
    método puede producir un cambio en las propiedades del
    objeto, o la generación de un "evento" con un nuevo
    mensaje para otro objeto del sistema.
  • Evento: un suceso en el sistema (tal como una
    interacción del usuario con la máquina, o un
    mensaje enviado por un objeto). El sistema maneja el evento
    enviando el mensaje adecuado al objeto pertinente.
    También se puede definir como evento, a la
    reacción que puede desencadenar un objeto, es decir la
    acción que genera.
  • Mensaje: una comunicación dirigida a un
    objeto, que le ordena que ejecute uno de sus métodos con
    ciertos parámetros asociados al evento que lo
    generó.
  • Propiedad o atributo: contenedor de un tipo de
    datos asociados a un objeto (o a una clase de objetos), que
    hace los datos visibles desde fuera del objeto y esto se define
    como sus características predeterminadas, y cuyo valor
    puede ser alterado por la ejecución de algún
    método.
  • Estado interno: es una propiedad invisible de
    los objetos, que puede ser únicamente accedida y
    alterada por un método del objeto, y que se utiliza para
    indicar distintas situaciones posibles para el objeto (o clase
    de objetos).
  • Componentes de un objeto:atributos, identidad,
    relaciones y métodos.
  • Representación de un objeto: un objeto
    se representa por medio de una tabla o entidad que esté
    compuesta por sus atributos y funciones
    correspondientes.

En comparación con un lenguaje imperativo, una
"variable", no es más que un contenedor interno del
atributo del objeto o de un estado interno, así como la
"función" es un procedimiento interno del método
del objeto.

  1. Características de la
    POO

Hay un cierto desacuerdo sobre exactamente qué
características de un método de programación
o lenguaje le definen como "orientado a objetos", pero hay un
consenso general en que las características siguientes son
las más importantes (para más información,
seguir los enlaces respectivos):

  • Abstracción: Cada objeto en el sistema
    sirve como modelo de un "agente" abstracto que puede realizar
    trabajo, informar y cambiar su estado, y "comunicarse" con
    otros objetos en el sistema sin revelar cómo se
    implementan estas características. Los procesos, las
    funciones o los métodos pueden también ser
    abstraídos y cuando lo están, una variedad de
    técnicas son requeridas para ampliar una
    abstracción.
  • Encapsulamiento: Significa reunir a todos los
    elementos que pueden considerarse pertenecientes a una misma
    entidad, al mismo nivel de abstracción. Esto permite
    aumentar la cohesión de los componentes del sistema.
    Algunos autores confunden este concepto con el principio de
    ocultación, principalmente porque se suelen emplear
    conjuntamente.
  • Principio de ocultación: Cada objeto
    está aislado del exterior, es un módulo natural,
    y cada tipo de objeto expone una interfaz a otros
    objetos que específica cómo pueden interactuar
    con los objetos de la clase. El aislamiento protege a las
    propiedades de un objeto contra su modificación por
    quien no tenga derecho a acceder a ellas, solamente los propios
    métodos internos del objeto pueden acceder a su estado.
    Esto asegura que otros objetos no pueden cambiar el estado
    interno de un objeto de maneras inesperadas, eliminando efectos
    secundarios e interacciones inesperadas. Algunos lenguajes
    relajan esto, permitiendo un acceso directo a los datos
    internos del objeto de una manera controlada y limitando el
    grado de abstracción. La aplicación entera se
    reduce a un agregado o rompecabezas de
    objetos.
  • Polimorfismo: comportamientos diferentes,
    asociados a objetos distintos, pueden compartir el mismo
    nombre, al llamarlos por ese nombre se utilizará el
    comportamiento correspondiente al objeto que se esté
    usando. O dicho de otro modo, las referencias y las colecciones
    de objetos pueden contener objetos de diferentes tipos, y la
    invocación de un comportamiento en una referencia
    producirá el comportamiento correcto para el tipo real
    del objeto referenciado. Cuando esto ocurre en "tiempo de
    ejecución", esta última característica se
    llama asignación tardía o
    asignación dinámica. Algunos lenguajes
    proporcionan medios
    más estáticos (en "tiempo de compilación")
    de polimorfismo, tales como las plantillas y la sobrecarga de
    operadores de C++.
  • Herencia: las clases no están aisladas,
    sino que se relacionan entre sí,
    formando una jerarquía de clasificación.
    Los objetos heredan las propiedades y el comportamiento de
    todas las clases a las que pertenecen. La herencia organiza y
    facilita el polimorfismo y el encapsulamiento permitiendo a los
    objetos ser definidos y creados como tipos especializados de
    objetos preexistentes. Estos pueden compartir (y extender) su
    comportamiento sin tener que reimplementar su comportamiento.
    Esto suele hacerse habitualmente agrupando los objetos en
    clases y estas en árboles o
    enrejados que reflejan un comportamiento común.
    Cuando un objeto hereda de más de una clase se dice que
    hay herencia múltiple; esta característica
    no está soportada por algunos lenguajes (como
    Java).
  1. Lenguajes orientados a
    objetos

Entre los lenguajes orientados a objetos destacan los
siguientes:

  • ActionScript
  • ActionScript 2
  • ActionScript 3
  • Ada
  • C++
  • C#
  • Clarion
  • Lenguaje de programación D
  • Delphi
  • Harbour
  • Eiffel
  • Java
  • Lexico (en castellano)
  • Objective-C
  • Ocaml
  • Oz
  • Lenguaje de programación R
  • Perl (soporta herencia múltiple)
  • PHP (en su versión 5)
  • PowerBuilder
  • Python
  • Ruby
  • Smalltalk
  • Turbo Pascal 7
  • Magik (SmallWorld)
  • VB.NET
  • Visual FoxPro
  • XBase++

Muchos de estos lenguajes de programación
no son puramente orientados a objetos, sino que son
híbridos que combinan la POO con otros
paradigmas.

Al igual que C++ otros lenguajes, como
OOCOBOL, OOLISP, OOPROLOG y Object REXX, han sido
creados añadiendo extensiones orientadas a objetos a un
lenguaje de
programación clásico.

Un nuevo paso en la abstracción de paradigmas de
programación es la Programación
Orientada a Aspectos (POA). Aunque es todavía una metodología en estado de maduración,
cada vez atrae a más investigadores e incluso proyectos
comerciales en todo el mundo.

También es necesario recalcar que en la
programación orientada a objetos es factible de utilizar
en JavaScript

Bibliografía.

Internet www.educaweb.com

www.e_magister.com

www.monografias.com

www.postgrado.inea.org

www.inea.uva.es

www.tu_discovery.com

www.aulafacil.com

www.tecniciencia.com

www.wikipedia.com

 

Elaborado por:

T.S.U. Henry Jesus Mendoza Pacheco,

37 Años de edad.

Trabajo elaborado el 20 de Enero de 2008.

 

Partes: 1, 2, 3
 Página anterior Volver al principio del trabajoPágina siguiente 

Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

Categorias
Newsletter