Ámbito (Programación)

Revisión del 10:42 8 nov 2012 de Majibacoa2 jc (discusión | contribuciones) (Página creada con ' <div align="justify">{{Definición|Nombre= Ámbito (Programación) |imagen= |concepto= Se corresponde con una zona del código fuente englobada entre llaves }} '''Ámbito (Prog...')
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Ámbito (Programación)
Información sobre la plantilla
Concepto:Se corresponde con una zona del código fuente englobada entre llaves

Ámbito (Programación) . Se corresponde con una zona del código fuente englobada entre llaves { }, una lista de parámetros en una función o plantilla, o el espacio de una unidad de compilación no incluido en cualquier otro ámbito. Cada identificador es introducido en el código mediante una declaración. A partir de este punto de declaración, es conocido por el compilador en una región que llamada ámbito; es la zona en que la declaración tiene efecto. Dentro de este ámbito no puede existir otra declaración con el mismo identificador. Dentro del ámbito existen zonas en las que el identificador es visible, es decir, puede ser utilizado para designar a la misma entidad sin necesidad de un cualificador. En la práctica ocurre que cada identificador solo es visible en algunas regiones de su ámbito (que pueden ser discontinuas). El conjunto de estas regiones es su área de visibilidad ("scope"). La razón por la que un identificador deja de ser visible dentro de su ámbito es que sea eclipsado por otra declaración explícita que utiliza el mismo nombre. La nueva declaración puede ocurrir en un bloque de código anidado (en el mismo no es posible la nueva declaración), o en una clase derivada. En el programa existen dos entidades distintas: un identificador, o lo que es lo mismo, un nombre conocido por el compilador (visible o invisible momentáneamente) y una zona de memoria donde está la entidad que referencia la etiqueta (el Rvalue); que el identificador tiene su propio ámbito y visibilidad, y que la única forma que tiene el compilador para acceder al objeto es mediante su identificador (o mediante el identificador de un objeto que lo señale -un puntero-). En estas circunstancias, al menos teóricamente, pueden suponerse diversas situaciones:

Clases de ámbitos

Hay siete categorías de ámbitos: De sentencia; de bloque (o local); de función; de prototipo de función; de fichero; de clase y de espacio de nombres. El ámbito depende de como y donde es declarado el identificador.

Ámbito de Sentencia

Los lenguajes de programación soportan declaraciones en expresiones condicionales; pueden declararse variables dentro de las expresiones de las sentencias for, if, while y switch; entonces el ámbito de las variables es el de la sentencia. En el caso de if el ámbito incluye también el bloque else. Ejemplo:

...
for (j = 0; j>10; j++) { // comienza el ámbito de j
  int x = 0;             // comienza el ámbito de x
   ...
}                         // termina el ámbito de j x (ver nota)
    ...

Ámbito de Bloque

El ámbito de un identificador con ámbito local (o de bloque), empieza en el punto de declaración y termina al final del bloque que contiene la declaración (el denominado bloque contenedor). Ejemplo:

...
{
  ...
  char c = 'c';   // comienza el ámbito de c
  int x = 0;      // comienza el ámbito de x
  ...
}                 // termina el ámbito de c x
...

El ámbito de los parámetros declarados en la definición de una función es el del bloque que define dicha función. Ejemplo:

...
int func (int x, int y) {  // comienza el ámbito de x y
   ...
   int y = 12;             // Error!! declaración duplicada
   return (x + y);
}                          // termina el ámbito de x y
...

Ámbito de Función

Los únicos identificadores que tienen ámbito de función son las etiquetas de goto, razón por la cual sus nombres deben ser únicos en la función. Su ámbito es el de la función que las contiene, de forma que pueden ser utilizados por las sentencias goto en cualquier punto de la función en que se han declarado. Los identificadores de función tienen enlazado externo, lo que significa que pertenecen al ámbito global (el mismo para todas). Es decir, pueden ser referenciadas desde cualquier punto del fichero, incluso desde otras funciones, incluyendo main(), o desde ellas mismas (recursión), pero el bloque de código que engloba el cuerpo de cada función, incluyendo sus variables, es un espacio oculto, no puede ser accedido directamente desde su exterior. Por esta razón no es posible, por ejemplo, realizar un salto goto a una etiqueta en otra función. La única manera de acceder a una función es mediante una llamada a la misma siguiendo el formato específico definido en su prototipo. El único valor que se puede manejar directamente es el que devuelve y aún así, no es el valor original, sino una copia modelada de este Los nombres contenidos en la lista de parámetros formales de una función pertenecen al ámbito del bloque más externo de la función (el que define el cuerpo de la función). Una consecuencia de que todas las funciones comparten el mismo ámbito global es que no puedan declararse funciones dentro de funciones.

Ámbito de Prototipo

Los nombres declarados en la lista de parámetros de un prototipo de función (que no sea parte de una declaración) tienen ámbito reducido al prototipo. En realidad estos nombres solo son utilizados para el posible anuncio por el compilador de errores o advertencias sobre el prototipo que se declara.

Ámbito de Fichero

Los identificadores con ámbito de fichero, son llamados también globales o externos. Son declarados fuera de cualquier bloque, clase o función. Su ámbito abarca desde el punto de declaración hasta el final del fichero (por esta razón se suelen declarar al principio del fichero, justo después de las directivas # de preproceso).

Ámbito de Clase

Una clase es una colección de elementos (miembros) junto con las operaciones que se realizan con ellos. El término ámbito de clase se aplica a los nombres de los miembros de una clase particular. Las clases y sus miembros tienen reglas de acceso y de ámbito muy especiales. El nombre N de un miembro de una clase C tiene ámbito “local a C”, y puede ser utilizado solo en las siguientes situaciones: En funciones miembro (métodos) de C. En expresiones tales como c.N, donde c es un objeto de C (Selector directo de miembro) En expresiones tales como cptr->N, donde cptr es un puntero a una instancia de C (Selector indirecto de miembro) En expresiones tales como C::N o D::N, donde D es una clase derivada de C. En referencias anticipadas de miembros dentro de la clase.

Ámbito de espacio de nombres

El espacio de nombre es el ámbito en el que un identificador debe ser único. A este respecto, C usa cuatro clases distintas de identificadores: Nombres de etiquetas goto. Deben ser únicas dentro de la función en que se han declarado (el goto tiene ámbito de función). Nombres estructuras, uniones y enumeraciones. Deben ser únicas dentro del bloque en que se han definido. Las etiquetas definidas fuera de cualquier función deben ser únicas (ya que son globales al fichero). Nombres de miembros de estructuras y uniones. Deben ser únicos dentro de la estructura o unión en que se han definido. No existe restricción en el tipo de miembros del mismo nombre en diferentes estructuras. Variables, funciones, typedef y enumeradores. Deben ser únicos dentro del ámbito en que han sido definidos. Los identificadores declarados externos deben ser únicos entre las variables declaradas externas. C++ tiene una palabra clave: namespace, que es en realidad un recurso para manejar los identificadores. Permite dividir el espacio total de nombres en regiones distintas e independientes respecto a los identificadores.

Ocultación

Un nombre puede ser ocultado por una declaración explícita del mimo nombre en un bloque más profundo o en una clase. Ejemplo:

int x = 3, j;
for (j = 0; j>10; j++) {
  int x = 0;        // oculta al anterior
  ...
}
cout << x << endl;  // la x original vuelve a ser visible

Los parámetros formales de las funciones ocultan cualquier otra variable o función externas del mismo nombre. Por ejemplo:

int x, y;           // espacio global
func(double x, double y) {
   ...              // x e y globales no son visibles aquí

Acceso cualificado

El miembro oculto m de una clase CL es todavía accesible utilizando el operador de acceso a ámbito :: con un nombre de clase: CL::m. Un nombre de ámbito global (de fichero) oculto, puede ser todavía referenciado utilizando el operador ::. Ejemplo:

  1. include <iostream>

using namespace std;

int x = 1; // x-global int main() { // ==============

  cout << "1. x = " << x << endl;
  x = 2;                // se refiere a x-global
  cout << "2. x = " << x << endl;
  int x = 4;            // Nueva x (x-de-main) oculta a la anterior
  for (int j = 0; j<1; j++) {
     int x = 3;         // Nueva x (x-de-for) oculta a la anterior
     cout << "3. x = " << x << endl;
     ::x = 5;           // se refiere a x-global
  }
  cout << "4. x = " << x << endl;
  cout << "5. x = " << ::x << endl;

} Salida: 1. x = 1 2. x = 2 3. x = 3 4. x = 4 5. x = 5 Un nombre de clase puede ser ocultado por el nombre de un objeto, función o enumerador declarado dentro de su ámbito, con independencia del orden en que se hubiesen declarado los nombres. Aunque la clase oculta puede ser todavía accesible precediendo su identificador con la palabra clave apropiada: class, estruct o union. Ejemplo: class C { .... };

int main() { // =============

  int C;
  C c;         // Error clase C no definida (oculta por int C)
  class C c;   // Ok. compila sin dificultad

}

Punto de declaración

A todos estos efectos, el punto de declaración de un nombre x es inmediatamente después de su declaración completa, pero antes de su inicializador si es que existe alguno.

Acceso a entidades

Cuando el compilador encuentra en el código la utilización de un identificador, intenta relacionarlo con alguna declaración previa de dicho nombre. Este proceso es conocido como búsqueda de nombre ("Name-lookup"). El proceso puede asociar más de una declaración con un nombre si este corresponde a una función (funciones sobrecargadas); en este caso, la selección de la definición adecuada sigue al "name-lookup" en un proceso conocido como resolución de sobrecarga.

Véase también

Fuente