PUNTEROS










1.1 TERMINOLOGÍA BASICA.

un puntero es una variable que representa la posición (en vez de valor) de otro dato, tal como una variable o un elemento de una formación. Los punteros son usados frecuentemente en C y tienen gran cantidad de aplicaciones. Por ejemplo para traspasar información entre una función y sus puntos de llamada.proporcionan una forma de devolver varios datos desde la función a través de los argumentos de la función . los punteros permiten también que referencias a otras funciones puedan ser especificadas como argumentos de una función entre otros.

dentro de la memoria de la computadora, cada dato almacenado ocupa una o mas celdas continuas de memoria . el número de memoria requeridas para almacenar un dato depende de su tipo.

Supongamos que v es una variable que representa un determinado dato. Podemos acceder al dato si conocemos la dirección del aprimera celda de memoria *.
La dirección de memoria de v puede ser determinada mediante la expresión &v donde & es el operador monario que se explica en las siguientes lineas.


1.2 DIRECCIONES Y PUNTEROS.

Para desplegar la direccion de una variable se puede utilizar el operador de direccion &, el cual significa la “direccion de” cuando se utiliza una instrucción que no es declarativa, el operador de direccion antepuesto al nombre de una variable se refiere a la direccion de una variable.

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{
     int num;
     num=10;

    printf("num es : %d",num);
    printf("la direccion de num es %d ",&num);

    return 0;

}

Lo anterior es relativamente sencillo desplegará el domicilio en el mapa de memoria en hexadecimal que le corresponde a la variable guardada num. en el ejemplo siguiente veremos como se utiliza el operador (*) que le llamaremos simbolo de indirección.

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int num, *pnum;
    num=10;
    pnum=#            //aqui es donde le digo al puntero a donde apuntar

    printf("num es : %d\n",num);
    printf("la direccion de num es %d\n ",&num);
    printf("el valor al que apunta *pnum es %d\n ",*pnum);

    return 0;
}

                              num es : 10
                              la direccion de num es 2555672
                              el valor al que apunta *pnum es 10

la declaración *pnum declara que pnum es una variable apuntadora usada para almacenar la dirreccion de una variable tipo entero. Almacena la direccion de num en el apuntador pnum.


1.3 DECLARACIÓN DE PUNTEROS.

Como todas las variables, los apuntadores deben ser declarados antes que puedan utilizarse para almacenar una dirección. Cuando se declara un apuntador se requiere que también se especifique el tipo de la variable al que apunta. Ejemplo.

int *pointerv;

Esta declaracion se lee como la variable a que apunta a pointer la variable es de tipo entero (la variable puede ser de cualquier tipo).
Ahora vamos a asignar la direccion de v a otra variable,pointerv. Así

int *pointerv;
pointerv=&v ;


1.4 OPERACIÓN DE PUNTEROS.

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int *px,*py;
    static int a[]={2,5,7,4,5,1};
    px=&a[0];
    py=&a[2];

    printf("los valores de %d mas %d es %d\n",*px,*py,*px**py);
    printf("el res es %d ",(*px+3));

return 0;
}

Operaciones con punteros.

1. A una variable puntero se le puede asignar la dirección de una variable ordinaria (pv = &v).
2. A una variable puntero se le puede asignar el valor de otra variable puntero siempre y cuando ambos         punteros apunten al mismo tipo de punteros (pv=px).
3. A una variable puntero se le puede asignar un valor nulo cero (pv=NULL).
4. A una variable puntero se le puede sumar o restar una cantidad entera (pv+3,++pv,etc).
5. Una variable puntero ser restada de otra con tal que ambas apunten a elementos de la misma formación.
6. Dos variables puntero pueden ser comparadas siempre que ambas apunten a datos del mismo tipo.


1.5 LA RELACION ENTRE ELEMENTOS DEL ARREGLO Y APUNTADORES.

#include "stdafx.h"
const int tamarr=5; //en este caso no es necesario declarar el tamaño
int cali[tamarr]={98,5,7,23,5};
int i,*pcali;

int _tmain(int argc, _TCHAR* argv[])
{
   pcali=cali; //pudo declararse pcali=&cali[0];
     for(i=0;i
          printf("la calificacion %d es %d\n",i+1,*(pcali+i));
return 0;
}

                                la calificacion 1 es 98
                                la calificacion 2 es 5
                                la calificacion 3 es 7
                                la calificacion 4 es 23
                                la calificacion 5 es 5


#include "stdafx.h"
#include "ctype.h>
#include "string.h>

char alfa[]="abcdefghijklmnopqrestuvwxyz";
int n=strlen(alfa);

int _tmain(int argc, _TCHAR* argv[])
{
    for(int i=0; i
      {
          char car=alfa[i];
          printf("\n%c = %d\n",car,car);
      }
     return 0;
}

Desplegara el alfabeto con su codigo ASCII corespondiente.

#include "stdafx.h"

char x[]="este es un ejemplo con arreglos sin puntero\n";
char *y="este es un ejemplo con arreglos con puntero\n";

int _tmain(int argc, _TCHAR* argv[])
{
     printf("%s",x);
     printf("%s",y);
   return 0;
}


1.6 PUNTEROS A CONSTANTES.

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
   int *dirnum;
   int millas, dist;

   dist = 158;
   millas =22;

  dirnum= &millas; //almacena la direccion de millas en dirnum
  printf("la direccion almacenada en dirnum es %d\n",dirnum);
  printf("el valor al que apunta dirnum es %d",*dirnum);
  dirnum=&dist;
  printf("la direccion almacenada en dirnum es%d ",dirnum);
  printf("el valor al que apunta dirnum es %d",*dirnum);

return 0;
}

                      la direccion almacenada en dirnum es 0012FE68
                      el valor al que apunta dirnum es 22
                      la direccion almacenada en dirnum es 0012FE5C
                      el valor al que apunta dirnum es 158

1.7 RESERVA DINAMICA DE MEMORIA.

Las funciones malloc y free y el operador sizeof , son esenciales en la asignación dinamica de memoria . la función malloc tomo como argumento el número de de bytes a asignarse, y regresa un puntero del tipo void*(puntero a void)a la memoria asignada.un apuntador void* puede asignarse a una variable de cualquier tipo de apuntador. La función malooc utiliza el operador sizeof. Puedes utilizar o no el operador free ejemplo free(x), para liberar la memoria después de no volverla a utilizar.

#include "stdafx.h"
#include

int _tmain(int argc, _TCHAR* argv[])
{
      int i,n,*x,*p=NULL;
      printf("cuantos valores vas a introducir\n");
      scanf("%d",&n);
      x=(int*)malloc(n*sizeof(int));
      for(i=0;i
        {
            printf("dame el elemento numero %d\n",i+1);
            scanf("%d",x+i);
         }
      for(i=0;i
        {
           printf(" el elemento numero %d es %d\n",i+1,*(x+i));
        }
   return 0;
}


Vemos que la función scanf especifica ahora la dirección del i-ésimo elemento como x+i en vez de &x[i] y la función printf representa el valor del i-ésimo elemento como *(x+i)en vez de x[i].


1.8 PASO DE PUNTEROS A UNA FUNCIÓN.

Cuando los punteros se utilizan como argumentos formales de una función, es necesario tener cuidado con la declaración de los argumentos formales dentro de la función. Los argumentos formales que sean punteros deben de ser precedidos por un (*) asterisco. Los prototipos de funciones se escriben de la misma manera. Si una declaración de función no incluye nombres de variables, el tipo de datos de cada argumento puntero debe ir segundo de un asterisco. El uso de argumentos puntero se ilustra en el siguiente ejemplo.

#include "stdafx.h"
void fun(int,int);
void fun1(int*,int*);
int u=3;
int v=5;
int _tmain(int argc, _TCHAR* argv[])
{
    printf("antes de la funcion: u=%d v=%d\n",u,v);
    fun(u,v);
    printf("despues de la funcion: u=%d v=%d\n",u,v);
    printf("antes de la funcion1: u=%d v=%d\n",u,v);
    fun1(&u,&v);
    printf("despues de la funcion1: u=%d v=%d\n",u,v);
 return 0;
}

void fun(int u,int v)
{
   u=0;
   v=0;
   printf("dentro de la funcion: u=%d v=%d\n",u,v);
}

void fun1(int *pu,int *pv)
{
  *pu=0;
  *pv=0;
  printf("dentro de la funcion: *pu=%d *pv=%d\n",*pu,*pv);
}


# include "stdafx"

int cuenta(char*);
char ca[64];
int _tmain(int argc, _TCHAR* argv[])
{
   cuenta(ca);
return 0;
}

int cuenta(char &ca)
{
   int i=0;
   printf("dame la cadena de caracteres\n");
   gets(ca);
       while(*ca)
        {
           printf("la letra del caracter es %c\n",*ca);
              ca++;
                i++;
        }
   printf("la cadena tiene %d letras\n",i);
return 0;
}

 
una función a un puntero

#include "stdafx.h"
int *fun(int *p);

int _tmain(int argc, _TCHAR* argv[])
{
   static int a[]={10,20,30,40,50};
   int *ptmax;
   ptmax=fun(a);

printf("max=%d\n",*ptmax);
return 0;
}

int *fun(int *p)
{
   int i,imax,max=0;
     for(i=0;i<5;i++)
        if (*(p+i)>max)
               {
                  max=*(p+i);
                  imax=i;
               }
  return (p+imax);
}

1.9 PUNTEROS VOID


El uso más importante de punteros void en C es pasar la dirección de tipos de datos diferentes en una llamada a función cuando no se conoce por anticipado que tipo de dato se pasa.


#include “stdafx.h”
 enum dato{caracter,real,entero,cadena};

void ver(void *,dato);

void main()
{
    char a='b';
     int x=3;
     double y=4.5;
     char *cad="hola";
     ver(&a,caracter);
     ver(&x,entero);
     ver(&y,real);
     ver(cad,cadena);
}

void ver( void *p, dato d)
{
   switch(d)
    {
        case caracter: printf("%c\n",*(char *)p);
        break;
        case entero: printf("%d\n",*(int *)p);
        break;
       case real: printf("%ld\n",*(double *)p);
       break;
       case cadena: printf("%s\n",(char *)p);
     }

}
===============================================