TEORIA DE PUNTEROS
OBJETIVO: Aprender y Entender la teoría de punteros en
c , ya que es un tema muy importante en la programación , que debemos dominarlo
, para poder resolver problemas sobre este tema , es importante y la vez
entretenido , este tema es muy extenso y existen varias formas de aprender y de
resolver
TEORIA DE PUNTEROS
CONCEPTO: Un puntero o apuntador es una variable que contiene una
dirección de memoria. En esa posición de memoria se encuentra almacenada una
variable de un tipo determinado (entera, real o carácter). Su tamaño es de 4
bytes.
Se dice que la primera variable (el puntero) apunta a la segunda.
Un puntero también puede apuntar a otro puntero, es decir, almacenar la dirección de memoria de otro puntero.
DECLARACIÓN:
Se dice que la primera variable (el puntero) apunta a la segunda.
Un puntero también puede apuntar a otro puntero, es decir, almacenar la dirección de memoria de otro puntero.
DECLARACIÓN:
Para que un puntero pueda apuntar a una variable
debe ser declarado de la siguiente manera:
tipo*identificador
donde tipo es el tipo de variable a la que apunta (si es variable entera, int; si es real, float o double; y si es un carácter, char), * indica que es un puntero, e identificador es el nombre del puntero.
Los punteros sólo pueden apuntar a variables del mismo tipo que ellos.
(A partir de ahora llamaremos p, q... a identificadores de punteros en general, que deberemos inicializar para poder usarlos).
Si queremos que un puntero q apunte a otro p se declara así:
tipo* *q
OPERADORES:
tipo*identificador
donde tipo es el tipo de variable a la que apunta (si es variable entera, int; si es real, float o double; y si es un carácter, char), * indica que es un puntero, e identificador es el nombre del puntero.
Los punteros sólo pueden apuntar a variables del mismo tipo que ellos.
(A partir de ahora llamaremos p, q... a identificadores de punteros en general, que deberemos inicializar para poder usarlos).
Si queremos que un puntero q apunte a otro p se declara así:
tipo* *q
OPERADORES:
Los operadores que se usan con los punteros son &, *, y el operador asignación =.
-En C, al contrario que en otros lenguajes de programación, se puede obtener directamente la dirección de memoria de cualquier variable sobre la que opera el puntero. Esto es posible hacerlo con el operador referencia & de la siguiente forma:
p=&x
donde x es la variable a la que apunta el puntero.
-Para acceder a la variable a la que apunta el puntero se utiliza el operador desreferencia * de esta forma:
x=*p
donde x es la variable que obtiene un nuevo valor (el valor de la variable a la que apunta el puntero).
Si un puntero q apunta a otro p, se utiliza dos veces el operador *.
-En C, al contrario que en otros lenguajes de programación, se puede obtener directamente la dirección de memoria de cualquier variable sobre la que opera el puntero. Esto es posible hacerlo con el operador referencia & de la siguiente forma:
p=&x
donde x es la variable a la que apunta el puntero.
-Para acceder a la variable a la que apunta el puntero se utiliza el operador desreferencia * de esta forma:
x=*p
donde x es la variable que obtiene un nuevo valor (el valor de la variable a la que apunta el puntero).
Si un puntero q apunta a otro p, se utiliza dos veces el operador *.
ARITMÉTICA DE PUNTEROS:
-Suma/resta de punteros:
Sólo puede hacerse suma y resta de un puntero con un entero. Esta operación avanza o retrasa el puntero tantas veces como indica el entero con el que se opera. Se procede así:
p=p+n
donde n es un entero. (Por ejemplo, si n=1, el puntero p avanza 4 bytes).
-Comparación de punteros:
Se pueden comparar punteros, es decir, comparar las relativas posiciones de memoria:
Si tenemos que p>q, significa que p apunta a una dirección de memoria mayor que q.
Si tenemos que p<q, significa que p apunta a una dirección de memoria menor que q.
ERRORES COMUNES CON PUNTEROS:
Sólo puede hacerse suma y resta de un puntero con un entero. Esta operación avanza o retrasa el puntero tantas veces como indica el entero con el que se opera. Se procede así:
p=p+n
donde n es un entero. (Por ejemplo, si n=1, el puntero p avanza 4 bytes).
-Comparación de punteros:
Se pueden comparar punteros, es decir, comparar las relativas posiciones de memoria:
Si tenemos que p>q, significa que p apunta a una dirección de memoria mayor que q.
Si tenemos que p<q, significa que p apunta a una dirección de memoria menor que q.
ERRORES COMUNES CON PUNTEROS:
-Asignar punteros de distinto tipo (un float con
un char, un int con un double...).
Por ejemplo:
int a=1 ;
int *p ;
double b=2.0 ;
double *q ;
p=&a ;
q=&x ;
q=p; ERROR
-Usar punteros no inicializados.
Por ejemplo:
char *p;
*p='a';
(FALTARÍA PONER: char c;
p=&c; )
-Asignar valores al puntero en vez de a la variable:
Por ejemplo:
int x;
int *p;
p=&x;
p=7; MAL (DEBERÍA SER *p=7)
-Hacer asignaciones a la dirección de memoria NULL (dirección de memoria cero).
Por ejemplo:
int *p=NULL;
*p=6; // ERROR (NO SE PUEDE ASIGNAR NADA A LA DIRECCIÓN DE MEMORIA NULL)
RELACIÓN ENTRE PUNTEROS Y VECTORES:
Por ejemplo:
int a=1 ;
int *p ;
double b=2.0 ;
double *q ;
p=&a ;
q=&x ;
q=p; ERROR
-Usar punteros no inicializados.
Por ejemplo:
char *p;
*p='a';
(FALTARÍA PONER: char c;
p=&c; )
-Asignar valores al puntero en vez de a la variable:
Por ejemplo:
int x;
int *p;
p=&x;
p=7; MAL (DEBERÍA SER *p=7)
-Hacer asignaciones a la dirección de memoria NULL (dirección de memoria cero).
Por ejemplo:
int *p=NULL;
*p=6; // ERROR (NO SE PUEDE ASIGNAR NADA A LA DIRECCIÓN DE MEMORIA NULL)
RELACIÓN ENTRE PUNTEROS Y VECTORES:
Un vector es un conjunto de variables del mismo
tipo que se referencian con un mismo nombre y con un índice.
En C, los punteros y los vectores están fuertemente relacionados, hasta el punto de que el nombre de un vector es un puntero al primer elemento del vector. Para ir avanzando sobre el vector, cuyos elementos están situados en memoria consecutivamente, basta ir moviendo el puntero con simples incrementos sobre el vector. Así pues, siendo v el nombre de un vector en general, tenemos que:
v[i] es equivalente a *(v+i)
(Ej: v[4]=v[3]+7 es equivalente a *(v+4)=*(v+3)+7)
&v[i] es equivalente a (v+i)
(Ej: &v[2] es equivalente a (v+2))
Por tanto, todas las operaciones que utilizan vectores e índices pueden realizarse mediante punteros.
Sin embargo, hay que tener cuidado a la hora de no rebasar los límites del trozo de memoria donde se almacena el vector.
RELACIÓN ENTRE PUNTEROS Y MATRICES:
En C, los punteros y los vectores están fuertemente relacionados, hasta el punto de que el nombre de un vector es un puntero al primer elemento del vector. Para ir avanzando sobre el vector, cuyos elementos están situados en memoria consecutivamente, basta ir moviendo el puntero con simples incrementos sobre el vector. Así pues, siendo v el nombre de un vector en general, tenemos que:
v[i] es equivalente a *(v+i)
(Ej: v[4]=v[3]+7 es equivalente a *(v+4)=*(v+3)+7)
&v[i] es equivalente a (v+i)
(Ej: &v[2] es equivalente a (v+2))
Por tanto, todas las operaciones que utilizan vectores e índices pueden realizarse mediante punteros.
Sin embargo, hay que tener cuidado a la hora de no rebasar los límites del trozo de memoria donde se almacena el vector.
RELACIÓN ENTRE PUNTEROS Y MATRICES:
Una matriz es un conjunto de variables del mismo
tipo que se referencian con un mismo nombre y con dos índices.
Al igual que con vectores, en C, al declarar una matriz, se crea un puntero con el mismo nombre que la matriz. También se puede avanzar en la matriz y realizar operaciones de idéntica forma que con los vectores.
Siendo m una matriz en general, m[DIM1][DIM2], tenemos que:
m[i] es equivalente a &m[i][0]
(Ej: m[7]=&m[7][0])
m[i][j] es equivalente a *(m[i]+j) y es equivalente a *(m[0]+i*DIM2+j)
(Ej: m[2][3]=20 es equivalente a *(m[2]+3) y es equivalente a *(m[0]+2*DIM2+3)
(m+i) es equivalente a &m[i]
(Ej: (m+4) es equivalente a &m[4])
m[i][j] es equivalente a *(*m+i*DIM2+j)
(Ej: m[5][6] es equivalente a *(*m+5*DIM2+6))
EJEMPLOS DE COLA Y PILA
CONCLUSION:
Al igual que con vectores, en C, al declarar una matriz, se crea un puntero con el mismo nombre que la matriz. También se puede avanzar en la matriz y realizar operaciones de idéntica forma que con los vectores.
Siendo m una matriz en general, m[DIM1][DIM2], tenemos que:
m[i] es equivalente a &m[i][0]
(Ej: m[7]=&m[7][0])
m[i][j] es equivalente a *(m[i]+j) y es equivalente a *(m[0]+i*DIM2+j)
(Ej: m[2][3]=20 es equivalente a *(m[2]+3) y es equivalente a *(m[0]+2*DIM2+3)
(m+i) es equivalente a &m[i]
(Ej: (m+4) es equivalente a &m[4])
m[i][j] es equivalente a *(*m+i*DIM2+j)
(Ej: m[5][6] es equivalente a *(*m+5*DIM2+6))
EJEMPLOS DE COLA Y PILA
Ejemplo: Pila basada en un arreglo estático
#include <iostream>
using namespace std;
#define STACK_SIZE 256 /* capacidad máxima */
typedef char arreglo[STACK_SIZE];
class Stack {
int sp; /* puntero de lectura/escritura */
int items; /* número de elementos en lista */
int itemsize; /* tamaño del elemento */
arreglo pila; /* el arreglo */
public:
// constructor
Stack() {
sp = STACK_SIZE-1;
items = 0;
itemsize = 1;
}
// destructor
~Stack() {};
/* regresa el número de elementos en lista */
int size() { return items; }
/* regresa 1 si no hay elementos en la lista, o sea, si la lista está vacia */
int empty() { return items == 0; }
/* insertar elemento a la lista */
int put(char d)
{
if ( sp >= 0) {
pila[sp] = d;
sp --;
items ++;
}
return d;
}
/* retirar elemento de la lista */
int get()
{
if ( ! empty() ) {
sp ++;
items --;
}
return pila[sp];
}
}; // fin de clase Stack
// probando la pila.
// Nota: obseve cómo los elementos se ingresan en orden desde la A hasta la Z,
// y como los mismos se recuperán en orden inverso.
int main()
{
int d;
Stack s; // s es un objeto (instancia) de la clase Stack
// llenando la pila
for (d='A'; d<='Z'; d++) s.put(d);
cout << "Items =" << s.size() << endl;
// vaciando la pila
while ( s.size() ) cout << (char)s.get() << " ";
cout << "\nPara terminar oprima <Enter>...";
cin.get();
return 0;
}
}
Ejemplo: Pila basada en un arreglo dinámico
/*---------------------------------------------------------------+
+ ejemplo de una pila ( STACK ) enlazada dinámicamente +
+ +
+ Autor: Oscar E. Palacios +
+ email: oscarpalacios1@yahoo.com.mx +
+ +
+ Manifiesto: +
+ Este programa puede distribuirse, copiarse y modificarse de +
+ forma libre. +
+---------------------------------------------------------------*/
#include <iostream>
//#include <conio.h>
using namespace std;
/* tipo de dato que contendrá la lista */
typedef char DATA_TYPE;
// declaraci¢n de estructura nodo
struct nodo {
DATA_TYPE data;
nodo *next;
};
class StackDin {
// atributos
int ITEMS; /* número de elementos en la lista */
int ITEMSIZE; /* tamaño de cada elemento */
nodo *SP; /* puntero de lectura/escritura */
public:
// constructor
StackDin() : SP(NULL), ITEMS(0), ITEMSIZE(sizeof(DATA_TYPE)) {}
// destructor
~StackDin() {}
/* agregar componente a la lista */
DATA_TYPE put(DATA_TYPE valor)
{
nodo *temp;
temp = new nodo;
if (temp == NULL) return -1;
temp->data = valor;
temp->next = SP;
SP = temp;
ITEMS ++;
return valor;
}
int empty() { return ITEMS == 0; }
/* retirar elemento de la lista */
DATA_TYPE get()
{
nodo *temp;
DATA_TYPE d;
if ( empty() ) return -1;
d = SP->data;
temp = SP->next;
if (SP) delete SP;
SP = temp;
ITEMS --;
return d;
}
}; // fin de la clase StackDin
/* punto de prueba para la clase StackDin */
int main()
{
//clrscr();
StackDin s;
DATA_TYPE d;
for (d='A'; d<='Z'; d++) s.put(d);
while ( ! s.empty() )
cout << (DATA_TYPE)s.get() << " ";
cout << "\nPara terminar presione <Enter>...";
cin.get();
return 0;
}COLA
cola
|
+---+---+---+---+---+
| | | | | | al principio
+---+---+---+---+---+
|
cabeza
cola
|
+---+---+---+---+---+ put('A');
| A | | | | | después de haber agregado el primer elemento
+---+---+---+---+---+
|
cabeza
...
cola
|
+---+---+---+---+---+
| A | B | C | D | | después de haber agregado cuatro elementos
+---+---+---+---+---+
|
cabeza
Vaciando la cola.
cabeza
|
+---+---+---+---+---+
| A | B | C | D | | antes de haber retirado elementos
+---+---+---+---+---+
cabeza
|
+---+---+---+---+---+ get();
| A | B | C | D | | después de haber retirado un elemento
+---+---+---+---+---+
...
cabeza
|
+---+---+---+---+---+ al final
| A | B | C | D | | después de haber retirado todos los elementos
+---+---+---+---+---+
|
cola
CONCLUSION:
Este tema de
punteros me pude dar cuenta que es muy útil e importante para aprender a
programar muy fácilmente, debemos saber como resolver ya que este tema es muy
complejo , y un poco difícil de entender , si fallas una linesa programación no
te puede salir
BIBLIOGRAFÍA:
http://www.mailxmail.com/curso-introduccion-lenguaje-c/punteros
www.uhu.es/04004/material/Transparencias6.pdf