power point unidad 1 punteros

Upload: felipe-miranda-aravena

Post on 15-Oct-2015

40 views

Category:

Documents


1 download

TRANSCRIPT

  • Almacenamiento de punteros

    Estructura de DatosLus Fdo. Miranda S.19/04/2010

  • Almacenamiento de punterosContenido

    ConceptosDeclaracin de punteros Asignacin de valores a punteros Punteros y parmetros

  • Declaraciones de punteros.El operador "direccin de" (&).El operador de desreferenciacin (*).Arreglos de punteros.

  • Son variables que siguen todas las convenciones sobre nombres que utilizan las variables regulares de todos los dems tipos. Se deben declarar las variables de tipo puntero antes de poder utilizarlas.Existe un tipo de puntero para cada tipo de dato en C.Puede declarar puntero globales o locales, segn donde se los declare. Los punteros contienen direcciones de datos en memoria. Existen dos tipos de operadores de punteros en C:

    & El operador "direccin de".

    * El operador de desreferenciacin.

  • Cuando vea el & utilizado con variables de tipo puntero, considrelo equivelente a las palabras "direccin de". El operador & siempre retorna la direccin de memoria de lo que venga despus del mismo. El operador *, cuando se lo emplea con punteros, puede declarar un puntero o desreferenciar (entregar) el valor que se encuentra alojado en la direccin que referencia el puntero.

  • Declaracin de punterosDeclarar punteros es tan sencillo como declarar variables convencionales.

    Si necesitara declarar una variable que almacenara su edad, podra hacerlo con la declaracin siguiente:

    int edad=30; // Declaro una variable que almacenara mi edad

    Al declarar edad de esa manera se llevan a cabo varias cosas. C ahora sabe que usted necesitar una variable denominada edad, as que reserva espacio en memoria para esa variable. C tambin sabe que en esa variable, almacenar solo valores enteros, no de punto flotante o de punto flotante doble. Esa declaracin tambin requiere de C que ste, una vez que haya reservado espacio en memoria para la variable edad, almacene en sta el valor 30.

  • En qu lugar de la memoria C almacena edad? Como programador, a usted no debera importarle dnde decida C almacenar edad. Usted no necesita conocer la direccin de esa variable porque nunca se va a referir a edad por su direccin. Si quisiera calcular o imprimir con edad, directamente la llamara por su nombre, edad.

    CONSEJOAsgneles a sus variables puntero nombres que tengan significado en el contexto. El nombre punteroArchivo es ms entendible para un puntero de archivo que x13, aunque cualquiera de los dos es un nombre vlido.

  • Declare una variable puntero. Esta variable puntero no almacenar su edad, sino que apuntar a edad, la variable de tipo numrico que contiene su edad. (Para qu necesita de toda esa complicacin ser explicado a continuacin.) pEdad podra ser un buen nombre para una variable puntero. La Figura a continuacin ilustra lo que el programador quiere hacer. La figura muestra que C almacen edad en la direccin de memoria 350.606; sin embargo, es su compilador el que determina la direccin que asignar a edad, as que esta puede ser cualquiera.

  • El nombre pEdad por s mismo no tiene nada que ver con los punteros, excepto que es el nombre que se asign al puntero de edad. pEdad podra para el caso haber sido llamado miguelito, X43344, viaje_espacial o cualquier otra cosa que se le pudiera ocurrir al programador, lo mismo sucede con los nombres de las variables (en tanto dichos nombres se ajusten a las convenciones formales sobre nombres de variables).

    pEdad es un buen nombre para una variable que apunta hacia Edad, como lo seran tambin punteroEdad o punteroAEdad.

    Para declarar la variable de tipo puntero pEdad. deber hacer lo siguiente:

    int * pEdad; // Declara un puntero a variable de tipo entero

  • Algunos prefieren declarar una variable sin dejar un espacio en blanco luego del *, como sigue: int *pAge;// Declara un puntero a variable de tipo entero

    CONSEJOEn la definicin de una variable cada vez que aparezca el operador de desreferenciacin ( *variable, esa variable que se declara es siempre un puntero.

  • Asignacin de valores a punteros pEdad es un puntero a una variable entera. Esto es muy importante. pEdad puede apuntar solo a variables de tipo entero, nunca a variables de tipo punto flotante, doble punto flotante o siquiera a variables alfanumricas.

    C no inicializa los punteros cuando se los declara. Si hubiese declarado pEdad como se acaba de describir, y quisiera que pEdad sealara hacia edad, tendra que asignarle en forma explcita a pEdad la direccin de edad. La sentencia siguiente hace justamente eso: pAge = &edad; // Asigna a pEdad la direccin de edad

  • Qu valor est alojado ahora en pEdad?

    En lugar de asignar la direccin de edad a pEdad con un operador de asignacin, puede declarar e inicializar un puntero al mismo tiempo. Estas lneas declaran e inicializan tanto edad como pEdad. int edad=30;/* Declara una variable entera ordinaria, asignndole el valor 30*/int *pEdad=&edad;/* Declara un puntero a variable entera, inicializndolo con la direccin de edad */

    ObservacinEstas dos lneas producen las variables que se describen en la Figura anterior.

  • Si usted quisiese imprimir el valor de edad, podra hacerlo con la siguiente printf ();

    printf("%d", edad);// Imprime el valor de edad

    Tambin podra imprimir el valor de edad como sigue:

    printf("%d", *pEdad); // Desreferencia pEdad

    El operador de desreferenciacin le indica al puntero que lo que debe imprimir no es su propio contenido sino el contenido de la variable a la cual apunta. Sin el *, la ltima printf () hubiera impreso una direccin (la direccin donde se encontrase edad). Con el *, la printf () imprime el valor numrico alojado en esa direccin.

  • Usted puede asignarle a edad un valor diferente con la sentencia siguiente:

    edad=41; /* Asigna a edad un nuevo valor */

    Tambin le puede asignar el mismo valor as:

    *pEdad=41;

    Esta declaracin asigna el valor 41 a la variable a la que apunta pEdad.

    CONSEJOEl * aparece antes de una variable puntero en solo dos lugares: a) cuando se la declara, y b) cuando se desreferencia dicha variable (para obtener el valor contenido en la variable a la cual apunta).

  • Punteros y parmetros Cuando se transfera una variable ordinaria a scanf (), haba que preceder el nombre de la variable con el operador &. Por ejemplo, la siguiente scanf () obtiene tres valores enteros que ingresa el usuario:

    scanf (" %d %d %d", &nuraero1, &numero2, &nurnero3);

    Esta scanf () no transfiere las tres variables a su cdigo interno, sino que le transfiere las direcciones de esas tres variables. Como scanf ( ) sabe las ubicaciones exactas de estos parmetros en la memoria (porque se le pasaron sus direcciones como argumentos), su cdigo interno localiza estas direcciones y les asigna los valores ingresados desde el teclado.

  • La siguiente funcin transfiere la variable intentos por direccin a la funcin receptora denominada imprimirlo().

    Imprimirlo(&intentos); /* Transfiere la variable entera intentos a imprimirlo() por direccin (intentos seria normalmente transferida por copia) */

    La funcin siguiente, imprimirlo (), recibe la direccin de intentos, ya que la variable intentos le es transferida por direccin:

    imprimirlo(int *intentos)/* Recibe la variable intentos por direccin para proceder a desreferenciar su valor */

  • { *intentos++; /* Esto modifica intentos tanto en la funcin invocante como en la funcin llamada*/return 0; }

    Ahora que usted comprende los operadores & y *, est en condiciones de comprender totalmente la transferencia de argumentos no-arreglo por direccin a las funciones receptoras. (Los arreglos son transferidos por direccin como opcin predeterminada, y por lo tanto no requieren que se los preceda por & ni por *.)

  • 1. El siguiente fragmento de programa declara tres variables ordinarias de tres tipos diferentes de datos, y tres punteros que apuntan a cada una de esas variables.

    char inicial =Q;/* Declara tres variables ordinarias */ int numero=40;/* cada una de ellas de un tipo diferente */float ventas= 2321.59;

    char *plnicial=&inicial;/* Declara tres punteros. */int * punteroANumero=№ /* Los nombres de estos y el espaciado */ float * DireccionDeVentas = &ventas; /* despus del * no resultan criticos. */

  • 2. Usted puede inicializar punteros, igual que en el caso de las variables ordinarias, con sentencias de asignacin. No hace falta inicializarlos er. el momento en que se los declara. Las siguientes lneas de programa son equivalentes al cdigo del ejemplo anterior.

    Observe que no se coloca el operador * delante de los nombres de las variables puntero cuando se les asignan valores (direcciones de otras variables). Solo se los precede con * cuando se las desreferencia.

  • char inicial; int numero; float ventas;/* Declara tres variables ordinarias */ /* de tres tipos diferentes*/char *plnicial;/* Declara tres punteros pero todaviaint * punteroANumero;/* no los inicializa*/float * DireccionDeVentas;

    inicial='Q';numero=40;ventas=2321.59;/* Inicializa las variables ordinarias /* con valores*/ plnicial=&inicial;/* Inicializa los punteros con "/punteroANumero=№ /* las direcciones de sus*/direccionDeVentas=&ventas; /* correspondientes variables*

  • Observacin:En este ejemplo, a las variables punteros se les podra haber asignado las direcciones de las variables ordinarias antes de que a estas ltimas se le hubiesen asignado a su vez valores. La operacin del programa no mostrara ninguna diferencia. A los punteros les son asignadas las direcciones de las variables ordinarias sin que importen para nada los valores que estas puedan contener.

  • Mantenga consistencia en el tipo de cada puntero y su correspondiente variable. No le asigne al puntero de una variable de punto flotante la direccin de una variable de tipo entero. Por ejemplo, no se puede efectuar la siguiente asignacin:

    plnicial = &ventas;/* Asignacin de puntero invalida */

  • 3. El programa siguiente es un ejemplo que usted debiera estudiar en forma atenta. Ensea ms sobre los punteros y sus operadores, que lo que lo podran hacer varias pginas de texto.

    /* Filename: C20POINT.CDemuestra el empleo de las declaraciones de punterosy de su operadores */ #include main(){int numero=123; // Variable entera ordinariaint *pNumero; // Declara un puntero de tipo enteroprintf("El contenido de la variable numero es %d\n", numero);// Imprime el valor de nmero printf("La direccin de la variable numero es %ld \n", &numero) ;// Imprime la ubicacin de numero

  • pNumero = № // Asigna la direccin de numero a pNumero, // haciendo que pNmero apunte hacia // numero. No va ningn * delante de pNumero printf ("*pNumero es %d \n", *pNumero) ; // Imprime el valor de numero printf ("pNumero es %ld \n", pNmero); // Imprime la direccin denumero

  • La salida de este programa es la siguiente:

    El contenido de la variable numero es 123

    La direccin de la variable numero es 65522

    *pNumero es 123

    pNumero es 65522

    Si usted hiciera ejecutar este programa, tal vez obtendra resultados diferentes para el valor de pNumero, porque su compilador probablemente colocara la variable numero en otra ubicacin de memoria, segn sea la configuracin de su computadora. Sin embargo, la direccin efectiva no es lo importante del ejemplo. Como el puntero pNumero siempre contendr la direccin de la variable numero, y como usted puede en todos los casos desreferenciar pNumero para obtener el valor alojado en numero, la direccin efectiva no resulta crtica. Lo que s es crtico es que el programa pueda encontrarla.

  • 4. El programa siguiente incluye una funcin que permuta los valores de dos nmeros enteros cualquiera que le sean ingresados. Recuerde que una funcin puede regresar un solo valor cada vez que es llamada. Por lo tanto, hasta ahora, usted no poda escribir una funcin que cambiase dos valores diferentes y retornase ambos valores al mismo tiempo a la funcin que la haba invocado.

  • Para permutar dos variables (intercambiando sus valores para propsitos de ordenamiento, como se vio en el Captulo 19, "Trabajo con arreglos"), necesita contar con la posibilidad de transferir ambas variables por direccin. En este caso, cuando la funcin permute los valores de las variables, los valores presentes en la funcin invocante tambin resultarn permutados.

  • Observe el empleo que hace la funcin de los operadores de desreferenciacin antes de cada ocurrencia de numero1 y numero2. Usted no debe preocuparse respecto de las direcciones efectivas donde estn almacenadas las variables numero1 y numero2, sino que solo debe asegurarse de desreferenciar las direcciones que se le hayan transferido a la funcin receptora.

  • Asegrese de transferir los argumentos que sern recibidos por direccin precedindolos del operador &, como se hace aqu en main ().

  • /* Nombre de archivo: C20PERMT.CPrograma que incluye una funcin para permutar valores a la que se le transfieren dos valores enteros */tfinclude void permutarlos(int *numero1, int *numero2);void main(void);void main(void){int i=10, j=20;printf("\n\nAntes permutar sus valores, i vale %d y j vale%d\n\n", i, j); permutarlos(&i, &j); printf("\n\nDespues de la permutacin, i vale %d y j vale%d\n\n", i, j); return 0;}void permutarlos(int *numero1, int *numero2)int temp;temp = *numero1; ///* Variable auxiliar que almacena el valor de la permutacin intermedia. *'/ Los asteriscos garantizan que sean las numl = *numero2; // direcciones de las variables de la funcin invocante (y no los valores de las mismas) las que se transfieran a esta.funcin*num2 = temp; return 0;