apuntes puntero o apuntadores

15
 1 Los apuntadores permiten a los programadores simular las llamadas por referencia, y crear y maninpular estructuras de datos dinámicas, es decir estructuras de datos que pueden crecer y encogerse en tiempo de ejecución. PUNTERO O APUNTADORES Las variables se almacenan en un lugar de memoria. (Dirección) Estas direcciones generalmente se expresan en números hexadecimales. Ej. 1 Int x; En esta esquema la variable x guarda los datos en una área de la memoria llamada x x=10; Una variable contiene directamente un valor especifico. 1 .- APUNTADORES Los apuntadores permiten simular llamadas por referencia, crear, y manipular estructura de datos. Un puntero es una variable que guarda localizaciones de memoria. Un puntero guarda las dirección de las variables. Los punteros son variables que pueden co ntener la dirección de otra variable, y están almacenados en memoria teniendo su propia dirección. Un puntero e s u na dirección de memoria. 2.- DECLARACIÓN DE PUNTEROS. tipo *nombrepuntero numbrepuntero o el nombre del apuntador. Ej. 2.1 int *p; Es un puntero de nombre p a variable entero. p apunta a un objeto de tipo entero p es un apuntador a un entero.

Upload: israelar

Post on 05-Nov-2015

2 views

Category:

Documents


0 download

DESCRIPTION

apuntes sobre programación con apuntadores

TRANSCRIPT

  • 1

    Los apuntadores permiten a los programadores simular las llamadas por referencia, y crear y maninpular estructuras de datos dinmicas, es decir estructuras de datos que pueden crecer y encogerse en tiempo de ejecucin.

    PUNTERO O APUNTADORES

    Las variables se almacenan en un lugar de memoria. (Direccin) Estas direcciones generalmente se expresan en nmeros hexadecimales.

    Ej. 1 Int x;

    En esta esquema la variable x guarda los datos en una rea de la memoria llamada x

    x=10;

    Una variable contiene directamente un valor especifico.

    1 .- APUNTADORES

    Los apuntadores permiten simular llamadas por referencia, crear, y manipular estructura de datos.

    Un puntero es una variable que guarda localizaciones de memoria. Un puntero guarda las direccin de las variables. Los punteros son variables que pueden contener la direccin de otra variable, y estn almacenados en memoria teniendo su propia direccin. Un puntero e s una direccin de memoria.

    2.- DECLARACIN DE PUNTEROS.

    tipo *nombrepuntero

    numbrepuntero o el nombre del apuntador. Ej. 2.1 int *p; Es un puntero de nombre p a variable entero. p apunta a un objeto de tipo entero p es un apuntador a un entero.

  • 2

    Ej. 2.2

    int *p, q; // declara a p como apuntador que podr tener la direccin de cualquier variable de tipo entero y q se declara como una variable de tipo entero,

    Ej. 2.3

    int *ptrsuma; //ptrsuma es un puntero a valores enteros

    Una vez declarada una variable de apuntador es necesario conocer:

    & operador de direccin(referencia) * operador de in direccin (desreferencia)

    3.- & OPERADOR DE DIRECCIN O DE REFERENCIA

    & Es un operador unuario que asigna la direccin de su operando.

    p=&q //p contiene la direccin de q. p apunta a q.

    Se asigna la direccin de la variable q a el apuntador p La direccin de q es guardada en p.

    Un puntero apunta a una variables si su contenido es la direccin de esa variable

    NO significa

    p=q ESTO ES UN ERROR.

    &q regresa la direccin de la variable q y se le asigna a p.

    * OPERADOR DE INDIRECCIN O DESREFERENCIA.

    * Es un operador unuario de in direccin o desreferencia, el cual accede a el valor de positado en la zona de memoria a la que apunta un puntero.,

    Regresa el valor del objeto hacia el cual su operando apunta.

  • 3

    Devuelve el valor del objeto al cual apunta su operando (es decir, un apuntador).

    NOTA: Las constantes y expresiones no tienen direccin. *(&q) da el valor al cual esta direccionando la variable q. Ej. 3.1

    int i,j,*p; // p es un puntero

    p=&i;// p contiene la direccin de la variable i *p=10// i toma el valor de 10 p=&j,// pe contiene a hora la direccin de *P=-2 //j toma el valor de -2

    Ej. 3.2

    Int *p, y; // apuntador y a cualquier variable de tipo entero

    p=&y se asigna la direccin de y al apuntador x. p contiene la direccin de y *p=10// se regresa el valor al cual apunta es decir el valor de 10. printf(%d,*p)

    Ej. 3.3 # include # include

    main() { int i=5,j; int *ptr; // apuntador ptr a variable de tipo entero ptr=&i; //asigna la direccin de memoria de la variable // i al apuntador ptr // ptr apunta a la variable i printf(" i=%d\n",i); // valor de la variable i printf(" ptr=&i;\n ptr=%d\n ",ptr);// direccin de memoria de la variable i printf("*ptr=%d\n",*ptr);// regresa el valor que tiene apuntando a la

    //variable i *ptr=10; printf(" i=%d\n",i); // valor de la variable i printf("ptr=%d\n ",ptr);// direccin de memoria de la variable i printf("*ptr=%d\n",*ptr);// regresa el valor que tiene apuntando a la

  • 4

    //variable i ptr=&j; //asigna la direccion de memoria de la variable j al //apuntador ptr j=-4; printf(" j=%d\n",j); // valor de la variable j printf(" ptr=&j;\n ptr=%d\n ",ptr);// direccin de memoria de la variable j printf("*ptr=%d\n",*ptr);// regresa el valor que tiene apuntando a la variable j

    system("pause"); } RESULTADOS:

    i=5 ptr=&i;

    ptr=2293620 *ptr=5 i=10 ptr=2293620 *ptr=10 j=-4

    ptr=&j; ptr=2293616 *ptr=-4 Presione una tecla para continuar . . .

  • 5

    RECORDANDO LAS FUNCIONES CON VALOR DE RETORNO o

    Es decir Pasar argumentos a una funcin mediante llamadas por valor

    Ejemplo 1 //CUADRADO DE UN NUMERO UTILIZANDO FUNCION CON VALOR DE RETORNO #include #include

    int cuadrado(int); //prototipo de funcion

    main ( ) // archivo cabecera (header) { printf("cuadrado de un numero "); printf("los argumentos a una funcion"); printf(" pasan por valor"); int num=2; printf("numero %d\n",num); num=cuadrado(num); //llamado de la funcion donde num es el // argumento de entrada y regresa la funcion // regreso por valor // printf("cuadrado %d\n",num); system("pause"); return 0; } int cuadrado(int y) //definicin de funcion { // y es una copia del argumento de la funcion int c; c=y*y; return c; //devuelve el valor cuadrado de y como un int //o retun y*y; } // pasa la variable y a la funcion cuadrado mediante una llamada por valor //argumento de entrada por valor // la funcion cuadrado eleva al cubo su argumento y regresa el valor de c // a main mediante la instruccion return.

    SE PUEDE TAMBIEN REGRESAR VALORES POR REFERENCIA COMO SE VIO EN PASO ARREGLO DE FUNCION POR REFERENCIA

    Pasar argumentos a una funcin mediante llamadas por valor referencia Ahora #include #include

  • 6

    void cuadrado(int *pnum); //prototipo de funcion

    main ( ) // archivo cabecera (header) { printf("cuadrado de un numero\n "); printf("los argumentos a una funcion\n"); printf(" pasan por referencia\n"); int num=2; printf("numero %d\n",num); cuadrado(&num); //llamado de la funcion donde &num // da la direccion a la funcion printf("cuadrado %d\n",num); system("pause"); return 0; } void cuadrado(int *pnum) //definicin de funcion { //

    *pnum=*pnum**pnum;

    }

    Ej. cambios con funciones.

    //cambio # include # include

    void cambiar (int, int);

    main( ) { printf("cambiar\n"); int a=1, b=2; printf("en principal\n"); printf("a=%d y b=%d\n", a,b); cambiar (a,b); printf("regresando de la funcion en principal\n"); printf("a=%d y b=%d\n", a,b); system ("pause"); return 0; }

  • 7

    void cambiar (int a, int b) { int c; c=a; a=b; b=c; printf("en funcion cambiar\n"); printf("a=%d y b=%d\n",a,b); }

    //cambio 1 # include # include

    void cambiar (int, int);

    main( ) {

    int a=1, b=2; printf ("cambio1/n"); printf("a=%d y b=%d\n", a,b); printf ("en main\n"); cambiar (a,b); printf( "regresando de la funcion\n"); printf("a=%d y b=%d\n", a,b); system ("pause"); return 0; }

    void cambiar (int a, int b) { int c; c=a; a=b;

  • 8

    b=c; printf( "dentro de la funcion\n"); printf("a=%d y b=%d\n",a,b); }

    //cambio 2 //cambio 2 # include # include

    void cambiar (int*, int*);

    main( ) { int a=1, b=2;

    printf("imprimiento valores asignados en main\n"); printf("a=%d y b=%d\n", a,b);// son los valores asignados cambiar (&a,&b); //se pasa la direccin de a y b a la funcin // cambiar. // la funcin llamada modifica a la variable // que llama printf("Regresando a Main\n"); printf("a=%d y b=%d\n", a,b); system ("pause"); return 0; }

    void cambiar (int *pa, int *pb) // toma como apuntadores a pa y pb ambos de // de tipo entero. { printf("Dentro de la funcin cambiar\n"); printf("pa=%d y pb=%d\n",pa,pb); int c; c=*pa; *pa=*pb; // se asigna el resultado a *pa *pb=c; // se asigna el resultado a *pb printf("pa=%d y pb=%d\n",pa,pb); printf("*pa=%d y *pb=%d\n",*pa,*pb); }

  • 9

    Los apuntadores y los arreglos estn ntimamente relacionados. En general todas las expresiones de arreglos con subndices pueden escribirse mediante un apuntador y un desplazamiento.

    int b[]={1,2,3,4}; int *pb;

    pb=b;// establece que pb apunte al arreglo b; int *pb=b;// establece que pb apunte al arreglo b

    pb=&b[0];// toma la direccin del primer elemento del arreglo

    *(pb+3);//indica el valor del arreglo al que hace referencia es decir // b[3]; // apuntador pb desplazamiento 3 *(b+3)// tambin hace referencia al elemento b[3] del arreglo.

    De igual forma como denotamos b[1] que hace referencia al valor del elemento 1 del arreglo, tambin se puede utilizar la expresin siguiente usando apuntadores pb[1] // dende esta expresin se conoce como apuntador /subndice.

  • 10

    Ejemplo

    #include #include main() {

    int j; int A[10];

    printf("impresion de datos del arreglo\n"); for(j=0;j

  • 11

    system("pause");

    int *pa=A;// establece que el apuntador pa de tipo entero apunte al arreglo b; printf("impresion de datos del apuntador pa notacion Subindices de arreglo\n"); for(j=0;j

  • 12

    Tarea inverstigar las siguientes instrucciones: sizeof y malloc sobre todo orientado a apuntadores. Sizeof, malloc, free Es un operador que regresa el tamao en bytes de datos o de un arreglo http://sopa.dis.ulpgc.es/so/cpp/intro_c/introc75.htm Tamao de memoria de los tipos de datos #include

    sizeof (char) 1 byte sizeof (short) 2 bytes sizeof(int) 4 bytes sizeof(float) sizeof(double) sizeof(short)

    malloc usos (sobre todo a punteros) sirve para que una variable sea dinmica

    var= sizeof (int) var=4 bytes indica que el dato de tipo entero es de 4 bytes var=sizeof(double) var=8 bytes

    Si declaramos un areglo como sigue: Doubl A [22]; int var; var= sizeof A; var= 22*8=176 bytes

    La funcin malloc sirve para solicitar un bloque de memoria del tamao suministrado como parmetro. Devuelve un puntero a la zona de memoria concedida:

    void* malloc ( unsigned numero_de_bytes );

    Punteros void*

    La funcin malloc devuelve un puntero inespecfico, que no apunta a un tipo de datos determinado. En C, estos punteros sin tipo se declaran como void* Muchas funciones que devuelven direcciones de memoria utilizan los punteros void*. Un puntero void* puede convertirse a cualquier otra clase de puntero:

    char* ptr = (char*)malloc(1000);

  • 13

    Funcin free

    Cuando una zona de memoria reservada con malloc ya no se necesita, puede ser liberada mediante la funcin free.

    void free (void* ptr);

    ptr es un puntero de cualquier tipo que apunta a un rea de memoria reservada previamente con malloc. Si ptr apunta a una zona de memoria indebida, los efectos pueden ser desastrosos, igual que si se libera dos veces la misma zona.

    EJEMPLO #include

    int* ptr; /* puntero a enteros */ int* ptr2; /* otro puntero */

    ...

    /* reserva hueco para 300 enteros */ ptr = (int*)malloc ( 300*sizeof(int) ); ...

    ptr[33] = 15; /* trabaja con el rea de memoria */

    rellena_de_ceros (10,ptr); /* otro ejemplo */

    ptr2 = ptr + 15; /* asignacin a otro puntero */

    /* finalmente, libera la zona de memoria */ free(ptr);

    EJEMPLO http://www.wikilearning.com/tutorial/asignacion_dinamica_de_memoria_y_estructuras_dinamicas-uso_de_malloc_sizeof_y_free/718-1 main() { int *ip, i; ip = (int *) malloc(100 * sizeof(int) );// reserva 100 huecos ip[0] = 1000; for (i=0; i

  • 14

    La funcin free() toma un apuntador como un argumento y libera la memoria a la cual el apuntador hace referencia. scanf("%d",ip++);}

    Si queremos utilizar en un programa para el promedio de n nmeros de estudiantes sin cambiar el numero de e imprimir la calificacin de cada u no de ellos y se podra calcula el menor y mayor de ellos y despus otra vez calcular. y para el calculo de calificaciones el primer grupo es de 30 alumnos y el segundo grupo es de 40 alumnos. Sin modificar empleados y despus queremos 100 include

    #include //printf #include //system("pause") #include //getch()

    main() {

    int *Ep; int i,n; printf("dame el numero de estudiantes"); scanf( "%d",&n); Ep = (int *) malloc(n * sizeof(int) );// reserva 100 huecos for (i=0; i

  • 15

    5.5. Sizeof and storage allocation The sizeof operator returns the size in bytes of its operand. Whether the result of sizeof is unsigned int or unsigned long is implementation definedwhich is why the declaration of malloc above ducked the issue by omitting any parameter information; normally you would use the stdlib.h header file to declare malloc correctly. Here is the last example done portably:

    #include /* declares malloc() */ float *fp;

    fp = (float *)malloc(sizeof(float));

    The operand of sizeof only has to be parenthesized if it's a type name, as it was in the example. If you are using the name of a data object instead, then the parentheses can be omitted, but they rarely are.

    #include

    int *ip, ar[100]; ip = (int *)malloc(sizeof ar);

    In the last example, the array ar is an array of 100 ints; after the call to malloc (assuming that it was successful), ip will point to a region of store that can also be treated as an array of 100 ints.

    The fundamental unit of storage in C is the char, and by definition

    sizeof(char)

    is equal to 1, so you could allocate space for an array of ten chars with

    malloc(10)

    while to allocate room for an array of ten ints, you would have to use

    malloc(sizeof(int[10]))

    If malloc can't find enough free space to satisfy a request it returns a null pointer to indicate failure. For historical reasons, the stdio.h header file contains a defined constant called NULL which is traditionally used to check the return value from malloc and some other library functions. An explicit 0 or (void *)0 could equally well be used.