sábado, 8 de julio de 2017

Video Explicativo De Inicialización De Apuntadores


Inicialización De Apuntadores


     < Almacenamiento > < Tipo > * < Nombre > = < Expresión >
     Si <Almacenamiento> es extern static, <Expresión> deberá ser una expresión constante del tipo <Tipo> expresado.
     Si <Almacenamiento> es auto, entonces <Expresión> puede ser cualquier expresión del <Tipo> especificado.
     Ejemplos:
1.    La constante entera 0, NULL (cero) proporciona un apuntador nulo a cualquier tipo de dato:
int *p;
p = NULL; //actualización
2.  El nombre de un arreglo de almacenamiento static extern se transforma según la expresión:
a. float mat[12];
float *punt = mat;
b. float mat[12];
float *punt = &mat[0];
3.    Un “cast” apuntador a apuntador:
int *punt = (int *) 123.456;
Inicializa el apuntador con el entero. Esto es, en la dirección a la que apunta la variable punt se almacena el valor 123.
4.    Un apuntador a carácter puede inicializarse en la forma:
char *cadena = Esto es una cadena”;
5.    Se pueden sumar o restar valores enteros a las direcciones de memoria en la forma:
(aritmética de apuntadores)
static int x;
int *punt = &x+2, *p = &x-1;
6.    Equivalencia: Dos tipos definidos como apuntadores a objeto P y apuntador a objeto son equivalentes sólo si P y Q son del mismo tipo. Aplicado a matrices:

nombre_apuntador = nombre_matriz;


Declaración e inicialización de apuntadores


Video Explicativo De Aritmética De Apuntadores


Aritmética De Apuntadores

La aritmética de punteros se limita a suma, resta, comparación y asignación. Las operaciones aritméticas en los punteros de tipoX (punteros-a-tipoX) tienen automáticamente en cuenta el tamaño real de tipoX. Es decir, el número de bytes necesario para almacenar un objeto tipoX [2]. Por ejemplo, suponiendo una matriz de double con 100 elementos, si ptr es un puntero a dicha matriz, la sentencia ptr++; supone incrementar el Rvalue de ptr en 6.400 bits, porque el tamaño de la matriz es precisamente 100x64 bits.
Nota: no confundir el puntero-a-matriz con un puntero a su primer elemento (que aquí sería puntero-a-double).
La aritmética realizada internamente en los punteros depende del modelo de memoria en uso y de la presencia de cualquier modificador superpuesto.
Las operaciones que implican dos punteros exigen que sean del mismo tipo o se realice previamente un modelado apropiado .

Sean ptr1, ptr2 punteros a objetos del mismo tipo, y n un tipo entero o una enumeración; las operaciones permitidas y los resultados obtenidos con ellas son:


La comparación de punteros solo tiene sentido entre punteros a elementos de la misma matriz; en estas condiciones los operadores relacionales ( 4.9.12): ==,  !=, <,  >, <=, >=, funcionan correctamente.
Cuando se crea un arreglo unidimensional o de 'n' dimensiones, todos los elementos de dicho arreglo se acomodan en la memoria de manera adjunta o lineal, es decir, se puede desplazar por el arreglo moviéndonos de una dirección de memoria a otra con un apuntador, y simplemente sumando o restando unidades al apuntador se logra que dicho apuntador pueda recorrer el arreglo.
En la siguiente imagen se puede ver como se almacena un arreglo y como apuntar a él:

Como se puede observar todos los elementos del arreglo están adjuntos entre ellos, si el arreglo fuera bi-dimensional sería lo mismo.






Video Explicativo de Asignación De Apuntadores


Asignación De Apuntadores

     Se pueden asignar a un apuntador direcciones de variables a través del operador de referenciación (‘&’) o direcciones almacenadas en otros apuntadores. 
     Ejemplos:
     Un apuntador puede convertirse en un alias de una variable destino (target) a través de una sentencia de asignación de punteros, que es ejecutable y tiene la forma: 



Donde puntero es una variable con atributo pointer y objetivo es una variable con atributo target o bien atributo pointer. Una vez que un puntero se convierte en alias de un destino, se puede utilizar en cualquier punto en lugar de la variable destino.

     
     La figura  muestra algunos ejemplos de asignaciones con punteros. Téngase en cuenta que una asignación como:
p2 => p1 + 4.3             ! Error
     No está permitida porque no se puede asociar un puntero con una expresión aritmética.


     El destino de un puntero puede ser también un vector. La figura muestra algunos ejemplos de esta posibilidad. Hay varios aspectos que hemos de tener en cuenta:
     El puntero pv1 se asocia en diferentes momentos con vectores (secciones de vector) de diferentes extensiones. Esto se permite porque lo que cuenta es el rango, no la extensión.



Video Explicativo De Declaración de Apuntadores


Declaración De Apuntadores.

Cuando se declara una variable, el compilador reserva un espacio de memoria para ella y asocia el nombre de ésta a la dirección de memoria desde donde comienzan los datos de esa variable. Las direcciones de memoria se suelen describir como números en hexadecimal. Un apuntador es una variable cuyo valor es la dirección de memoria de otra variable. Se dice que un apuntador “apunta” a la variable cuyo valor se almacena a partir de la dirección de memoria que contiene el apuntador. Por ejemplo, si un apuntador p almacena la dirección de una variable x, se dice que “p apunta a x”.
Los apuntadores como cualquier otra variable deben de ser declarados antes de que puedan ser utilizados. El tipo de un apuntador lo proporciona implícitamente el tipo de la variable a la que apunta.
Los apuntadores pueden ser declarados para apuntar a objetos de cualquier clase.
La sintaxis general de declaración es:
<tipo> * <variable>
Ejemplos de declaraciones:
La variable contPtr es del tipo apuntador a entero, (int *) y se lee ``contPtr es un apuntador a int'' o ``contPtr apunta a una variable entera''.
NOTA: Un apuntador a cualquier tipo de variables es una dirección en memoria, la cual es una dirección entera, pero un apuntador NO es un entero.
La razón por la cual se asocia un apuntador a un tipo de dato, es por que se debe conocer en cuantos bytes esta guardado el dato. De tal forma, que cuando se incrementa un apuntador, se incrementa el apuntador por un ``bloque'' de memoria, en donde el bloque esta en función del tamaño del dato. Por lo tanto para un apuntador a un char, se agrega un byt a la dirección y para un apuntador a entero o a flotante se agregan 4 bytes. De esta forma si a un apuntador a flotante se le suman 2, el apuntador entonces se mueve dos posiciones float que equivalen a 8 bytes.
Para declarar un apuntador se especifica el tipo de dato al que apunta, el operador ‘*’, y el nombre del apuntador. La sintaxis es la siguiente:
<tipo de dato apuntado> *<indentificador del apuntador>
     A continuación se muestran varios ejemplos:

Ejemplos
En los ejemplos siguientes se muestran declaraciones de puntero.
char *message; /* Declares a pointer variable named message */

El puntero message señala a una variable con el tipo char.
int *pointers[10];  /* Declares an array of pointers */

La matriz de pointers tiene 10 elementos; cada elemento es un puntero a una variable con el tipo int.
int (*pointer)[10]; /* Declares a pointer to an array of 10 elements */

La variable de puntero señala a una matriz con 10 elementos. Cada elemento de esta matriz tiene el tipo int.
int const *x;      /* Declares a pointer variable, x,
         to a constant value */

El puntero x se puede modificar para que señale a un valor int diferente, pero el valor al que señala no puede modificarse.
const int some_object = 5 ; 
int other_object = 37; 
int *const y = &fixed_object; 
int volatile *const z = &some_object; 
int *const volatile w = &some_object; 
La variable y en estas declaraciones se declara como un puntero de constante a un valor int. El valor al que señala se puede modificar, pero el propio puntero debe señalar siempre a la misma ubicación: la dirección de fixed_object. De igual forma, z es un puntero de constante, pero también se declara para que señale a un elemento int cuyo valor no lo pueda modificar el programa.
El especificador adicional volatile indica que aunque el valor de const int al que señala z no lo puede modificar el programa, podría modificarlo de forma legítima un proceso ejecutado simultáneamente con el programa. La declaración de w especifica que el programa no puede cambiar el valor al que se señala y que el programa no puede modificar el puntero.
struct list *next, *previous; /* Uses the tag for list */
En este ejemplo se declaran dos variables de puntero, next y previous, que señalan al tipo de estructura list. Esta declaración puede aparecer antes que la definición del tipo de estructura list (vea el ejemplo siguiente), mientras que la definición de tipo list tiene la misma visibilidad que la declaración.
struct list  
    char *token; 
    int count; 
    struct list *next; 
} line; 

La variable line tiene el tipo de estructura denominado list. El tipo de estructura list tiene tres miembros: el primer miembro es un puntero a un valor char, el segundo es un valor int y el tercero es un puntero a otra estructura list.
struct id  
    unsigned int id_no; 
    struct name *pname; 
} record; 
La variable record tiene el tipo de estructura id. Observe que pname se declara como un puntero a otro tipo de estructura denominado name. Esta declaración puede aparecer antes de que se defina el tipo name.

Video Explicativo De Operaciones Con Apuntadores


Estructura de Apuntadores


Operaciones De Apuntadores

1. Un operador de dirección &:
Representa la dirección de memoria de la variable que le sigue; Operador unario que regresa la dirección de su operando, ejemplo:
                            main()
                           {
                                            int y;
                                            int *yPtr;
                                            y = 5;
                                            yPtr = &y;
                            }
2. Un operador de indirección o de desreferencia:
*. El operador * aplicado al nombre de un apuntador indica el valor de la variable apuntada; Regresa el valor del objeto hacia el cual su operando apunta, es decir un apuntador, ejemplo:
                           main()
                            {
                                            int x,y;
                                            int *py;
                                            y = 5;
                                            *py = y;
                                            x = *py + 5;
                                            printf(''%d %d nn'',*py,x);
                            }

     Se verá con un ejemplo en la diferencia entre todos estos conceptos
Es decir: int x = 25, *pint;
pint = &x;
     La variable pint contiene la dirección de memoria de la variable x. La expresión: *pint representa el valor de la variable (x) apuntada, es decir 25. La variable pint también tiene su propia dirección: &pint
   •      Se pueden realizar asignaciones entre punteros.
int a = 15;
int *p, *q;
q = &a;
p = q;                   /* se asigna la dirección que contiene q a p */
cout<<p;             /* imprime la dirección almacenad en p. */
   •      Se pueden operar solamente el +, el -, el ++ y el --.
Int p;
p = p + 1;            p avanza un entero.
p = p – 2;            p retrocede dos enteros.
p++;         p apunta al siguiente entero.
p--;           p apunta al entero anterior.
   •      Los punteros se pueden comparar.
int            2;
     En el siguiente código se realiza un programa que emplea los operadores (& y *).
#include <iostream.h>
#include <conio.h>
int main()
{
 clrscr();
 int a; //a es un puntero
int * ap;          //ap es un apuntador a un puntero
 a = 7;
 ap= & a;        //ap toma la dirección de a
 cout <<"la dirección de a es " <<&a;
 cout<<" \n el Valor de ap es " << ap;
 cout <<"\n el valor de a es" <<a;
 cout<<"\n el valor de *ap es " << *ap;
 cout<<"\n\n\n Mostrando los valores de * y &" ;
 cout <<"\n &* ap = " <<&*ap;
 cout <<"\n *& ap = " << *&ap;
 getch();
 return 0;
}



Ejemplos de Apuntadores



Los Apuntadores

Cuando se declara una variable, el compilador reserva un espacio de memoria para ella y asocia el nombre de ´está a la dirección de memoria desde donde comienzan los datos de esa variable. Las direcciones de memoria se suelen describir como números en hexadecimal.
Un apuntador es una variable cuyo valor es la dirección de memoria de otra variable. Se dice que un apuntador “apunta” a la variable cuyo valor se almacena a partir de la dirección de memoria que contiene el apuntador. Por ejemplo, si un apuntador p almacena la dirección de una variable x, se dice que “p apunta a x”.


Los apuntadores son variables que almacenan direcciones de memoria.
·     En general una variable contiene un valor específico dependiendo de cómo fue declarada.
·     Un apuntador contiene la dirección de una variable que contiene un valor específico.
·       Una variable se refiere directamente a un valor y un apuntador se refiere indirectamente a un valor.
·      Apuntadores usados en C debido a que a veces son la única manera de expresar un cálculo.
·      Se puede llegar a obtener un código más compacto y eficiente.
·   Cuando se emplean sin cuidado pueden crear programas imposibles de entender.
·       Cuentan con una declaración propia.
·       Los apuntadores disponen de dos operadores:
·       El operador unario o monádico “&” devuelve la dirección de memoria de una variable;
·     El operador de indirección o desreferencia “*” devuelve el "contenido de un objeto apuntado por un apuntador''.
     Hay que recordar que: 
·         Una variable es un campo de memoria destinado a almacenar datos que pertenezcan a un determinado tipo de dato.
·         Todo campo de memoria es un segmento de RAM que se reconoce por la asignación de una dirección representada en hexadecimal.
     Un apuntador es…
  •  Una variable que puede almacenar específicamente direcciones de memoria.
  •      Variable cuyo dato es la dirección de memoria de otra variable.