6
Laboratorio de Programación I Página 146 Mgter. Ángel Montesinos Murillo, Mgter. Manuel Zúñiga Carnero Sesión N° 27 UNIVERSIDAD CATÓLICA DE SANTA MARÍA PROGRAMA PROFESIONAL DE INGENIERÍA DE SISTEMAS SESIÓN 27: Punteros a Estructuras en C/C++ I OBJETIVOS Comprender los conceptos de estructuras y la gestión adecuada de variables tipo registro mediante punteros. Aplicar los punteros a estructuras para hacer más flexible la utilización de recursos de programación. Apreciar y valorar las capacidades y ventajas que ofrecen los punteros a estructuras en la construcción de programas. II TEMAS A TRATAR Introducción. punteros a estructuras Resumen. III MARCO TEORICO 1. INTRODUCCIÓN Al ser las struct un tipo de variable, esta variable también debe tener una dirección, como cualquier otro tipo de variable en lenguaje C, esta dirección debe de poder ser almacenada en un puntero al mismo tipo de dato, lenguaje C permite punteros a estructuras tal como permite punteros a cualquier otro tipo de variables. El uso principal de este tipo de punteros es pasar estructuras a funciones. Si tenemos que pasar toda la estructura el tiempo de ejecución puede hacerse eterno, utilizando punteros sólo se pasa la dirección de la estructura. Los punteros a estructuras se declaran poniendo * delante de la etiqueta de la estructura. Del mismo modo que ocurre con las funciones, las estructuras tienen una dirección, asumiendo que esta es el comienzo de su almacenamiento. Esto es especialmente cierto en C, donde las estructuras representan exclusivamente conjuntos de datos. En C++ las estructuras son cierto tipo de clases que pueden contener código (funciones), pero incluso entonces, lo que realmente se almacena en el cuerpo de la estructura son punteros (datos) a las funciones correspondientes. 2. PUNTEROS A ESTRUCTURAS Veremos que los punteros a estructuras son de uso muy frecuente para el manejo de estas; en especial cuando se pasan como argumentos a funciones o son devueltas por estas. Por ejemplo, la sentencia:

Guia_de_Practicas_de_Programacion_I_-_Sesion_27_-_2012.pdf

Embed Size (px)

Citation preview

  • Laboratorio de Programacin I Pgina 146

    Mgter. ngel Montesinos Murillo, Mgter. Manuel Ziga Carnero Sesin N 27

    UNIVERSIDAD CATLICA DE SANTA MARA PROGRAMA PROFESIONAL DE INGENIERA DE SISTEMAS

    SESIN N 27:

    Punteros a Estructuras en C/C++

    I

    OBJETIVOS

    Comprender los conceptos de estructuras y la gestin adecuada de variables tipo registro mediante punteros.

    Aplicar los punteros a estructuras para hacer ms flexible la utilizacin de recursos de programacin.

    Apreciar y valorar las capacidades y ventajas que ofrecen los punteros a estructuras en la construccin de programas.

    II

    TEMAS A TRATAR

    Introduccin. punteros a estructuras Resumen.

    III

    MARCO TEORICO

    1. INTRODUCCIN

    Al ser las struct un tipo de variable, esta variable tambin debe tener una direccin, como cualquier otro tipo de variable en lenguaje C, esta direccin debe de poder ser almacenada en un puntero al mismo tipo de dato, lenguaje C permite punteros a estructuras tal como permite punteros a cualquier otro tipo de variables. El uso principal de este tipo de punteros es pasar estructuras a funciones. Si tenemos que pasar toda la estructura el tiempo de ejecucin puede hacerse eterno, utilizando punteros slo se pasa la direccin de la estructura. Los punteros a estructuras se declaran poniendo * delante de la etiqueta de la estructura.

    Del mismo modo que ocurre con las funciones, las estructuras tienen una direccin, asumiendo que esta es el comienzo de su almacenamiento. Esto es especialmente cierto en C, donde las estructuras representan exclusivamente conjuntos de datos. En C++ las estructuras son cierto tipo de clases que pueden contener cdigo (funciones), pero incluso entonces, lo que realmente se almacena en el cuerpo de la estructura son punteros (datos) a las funciones correspondientes.

    2. PUNTEROS A ESTRUCTURAS

    Veremos que los punteros a estructuras son de uso muy frecuente para el manejo de estas; en especial cuando se pasan como argumentos a funciones o son devueltas por estas. Por ejemplo, la sentencia:

  • Laboratorio de Programacin I Pgina 147

    Mgter. ngel Montesinos Murillo, Mgter. Manuel Ziga Carnero Sesin N 27

    struct punto {int x; int y;} pto ={3,4}, *ptr = &pto, arsp[10];

    Define un tipo de estructura denominado punto, una estructura pto y un puntero ptr a dicha estructura; finalmente declara una matriz arsp de 10 estructuras tipo punto.

    A. SINTAXIS

    En general la sintaxis para declaracin de punteros a estructuras sigue la sintaxis general.

    * [ = ]

    En este caso tipo_objeto es de la forma struct punto, con lo que la declaracin es:

    struct punto * ptr;

    Opcionalmente puede incluirse un iniciador como en el ejemplo anterior:

    struct punto * ptr = &pto;

    En este caso ptr es un puntero, y *ptr representa la estructura pto. Los miembros de la estructura pueden referenciarse mediante el operador de acceso:

    (*ptr).x == 3; (*ptr).y == 4; // Ok:

    Los parntesis son necesarios, ya que el operador de acceso ( . ) tiene mayor precedencia que el de indireccin; por esta razn, *ptr.x es interpretada como *(ptr.x), lo que es errneo, ya que ptr.x no es un puntero (en este caso es un entero).

    La expresin:

    struct { int x1; char * str; long *arr[10]; } *ptr;

    Declara un puntero ptr a un tipo de estructura annima de tres componentes

    Aunque sintcticamente correcta y aceptable por el compilador, una declaracin como la anterior es prcticamente intil y muy peligrosa. Por ejemplo: (*ptr).int = 30; puede producir una catstrofe. La razn es la misma que se apunt en Expresiones peligrosas.

    Los punteros son muy importantes para el manejo de matrices y estructuras, por lo que en este caso se ha previsto una notacin alternativa ms corta:

    ptr->x == 3; ptr->y == 3; // Ok:

    Veamos las dos opciones de notacin para acceso de miembros en un ejemplo con estructuras anidadas:

    struct punto {

    int x; int y; } ;

    struct cuadro {

    struct punto p1; struct punto p2; } cu, *cptr = &cu;

    En las sentencias anteriores hemos definido dos tipos de estructuras, una instancia y un

  • Laboratorio de Programacin I Pgina 148

    Mgter. ngel Montesinos Murillo, Mgter. Manuel Ziga Carnero Sesin N 27

    puntero a dicha instancia; en estas condiciones, las expresiones que siguen son equivalentes (1 y 6 son preferibles por legibilidad):

    cu.p1.x // L1. (cu.p1).x (*cptr).p1.x

    ((*cptr).p1).x cptr->p1.x // L6. (cptr->p1).x

    Ejemplo.

    float pi = 3.14159; struct {

    int x;

    char * str; float *arr[10];

    struct punto pto; struct cuadro cuad; } str, *ptr = &str;

    Supuestas las declaraciones anteriores, a continuacin realizamos asignaciones a los miembros de str de dos formas: directamente y mediante expresiones del puntero ptr. Observe que segn lo indicado al respecto del espacio de nombres de estructuras, es perfectamente compatible el nombre str de estructura con el de uno de sus miembros (el puntero a carcter str).

    a) ASIGNACIONES DIRECTAS:

    str.x = 30; str.str = "Hola mundo";

    str.arr[0] = & pi; str.pto.x = 2; str.pto.y = 3; str.cuad.p1.x = 4; str.cuad.p1.y = 5;

    str.cuad.p2.x = 6; str.cuad.p2.y = 7;

    b) EXPRESIONES CON PUNTERO:

    ptr->x = 30;

    ptr->str = "Hola mundo";

    ptr->arr[0] = & pi; ptr->pto.x = 2; str.pto.y = 3;

    ptr->cuad.p1.x = 4; ptr->cuad.p1.y = 5; ptr->cuad.p2.x = 6; ptr->cuad.p2.y = 7;

    En el epgrafe relativo a la asociatividad y precedencia de operadores se ha sealado que los operadores:

    ( ) Llamada de funcin

    [ ] Subndices -> Acceso a miembro de estructura (mediante puntero) . Acceso a miembro de estructura

    :: Acceso a miembro de clase

    Constituyen el orden ms alto en la jerarqua de precedencia, y que su asociatividad es de izquierda a derecha, por lo que hay que prestar especial atencin a las expresiones en que aparecen. Para resaltar la importancia de las reglas de precedencia, en los ejemplos que siguen se exponen algunas expresiones, referidas al ejemplo, as como una explicacin de su significado.

  • Laboratorio de Programacin I Pgina 149

    Mgter. ngel Montesinos Murillo, Mgter. Manuel Ziga Carnero Sesin N 27

    ++ptr->x

    Debido a la precedencia de operadores, equivale a ++(ptr->x), as pues, incrementa el miembro x, no el valor del puntero ptr. Resultado: str.x == 31

    *ptr->x

    Del mismo modo, esta indireccin equivale a *(ptr->x) lo que resulta en un error, porque en el ejemplo indicado, ptr->x no es un puntero (es un int), y ya hemos visto [4.9.11] que el operando del operador de indireccin debe ser un puntero.

    *ptr->str

    En este caso, si es correcta la aplicacin del operador *; la expresin equivale a *(ptr->str), y ptr->str si es un puntero (a carcter); concretamente seala a la primera posicin de la cadena, es decir:

    *ptr->str == 'H'

    Se puede evidenciar como sigue:

    printf("Letra \"%c\"\n", *ptr->str); // Letra "H"

    ++*ptr->str

    Se ha sealado que *ptr->str equivale a 'H'; Ahora el compilador se enfrenta a la expresin: ++'H' == 'H'+1; el resultado depende del contexto, por ejemplo: 'H' = 'H'+1; es un error ('H' no es un Lvalue). Sin embargo la sentencia que sigue se compila correctamente y produce la salida indicada.

    printf("Letra \"%c\"\n", ++*ptr->str); // Letra "I"

    La explicacin es que el compilador pasa a printf el valor 'H'+1 (sin pretender ninguna otra asignacin), lo que, tras una conversin de tipo, se traduce en el carcter 'I' que sigue 'H' en la lista ASCII.

    *ptr++->str

    La expresin se traduce en: *((ptr++)->str) si se utiliza en una expresin que sigue, el resultado es el que se indica, pero cualquier posterior intento de utilizar ptr conduce a una catstrofe.

    printf("Letra \"%c\"\n", *ptr++->str); // Letra "H"

    La razn es que se enva a printf el valor *ptr->str, que produce la salida indicada y despus se produce el postincremento del puntero ptr, que queda apuntando a dios sabe donde, con lo que la utilizacin posterior seguramente producir el fallo del sistema por "Error grave".

    Si str hubiese apuntado a una matriz de estructuras y la posicin actual no fuese la ltima, el efecto hubiese sido simplemente dejar str apuntando a la siguiente estructura de la matriz.

    *++ptr->str

    La expresin equivale a *(++ (ptr->str)); nuevamente el resultado es correcto: ptr->str es

  • Laboratorio de Programacin I Pgina 150

    Mgter. ngel Montesinos Murillo, Mgter. Manuel Ziga Carnero Sesin N 27

    un puntero p que seala al carcter 'H'; su incremento en 1 lo hace apuntar al segundo, por lo que si utilizamos la expresin que sigue se produce la salida indicada:

    printf("Letra \"%c\"\n", *++ptr->str); // Letra "o" *ptr->str++

    Esta expresin equivale a (*(ptr->str))++, es decir: 'H'++; nuevamente el resultado depende del contexto. En la expresin que nos viene sirviendo para control produce la salida sealada, porque printf recibe como argumento un puntero a 'H' y el incremento se produce despus.

    printf("Letra \"%c\"\n", *ptr->str++); // Letra "H"

    3. RESUMEN

    Los punteros a estructuras se declaran de la misma forma que cualquier otro puntero es decir con el operador de indireccin *, para que una estructura tenga un puntero se deb declarar una variable puntero del mismo tipo de la estructura, cuando hacemos que un puntero a estructura almacene la direccin de una estructura podemos hacer que una funcin reciba la direccin de la estructura y no la estructura completa , esto agiliza la ejecucin del cdigo y disminuye la utilizacin de recursos, se debe hacer uso del operador -> el cual se usa para referirse a los datos miembro en la estructura.

    IV

    (La prctica tiene una duracin de 2 horas) ACTIVIDADES

    1. Encender el equipo de cmputo, si existe algn desperfecto o faltante en el equipo comunicarlo inmediatamente.

    2. Al aparecer la solicitud de contrasea hacer clic en el botn Cancelar o ingresar el nombre de cuenta(login) y contrasea(password) que especifique el Docente. Esperar que aparezca el mensaje de Inicio de sesin.

    3. Crear una carpeta que se llame Programacin I y dentro de ella una que se llame Prctica N 27 dentro de la carpeta Mis Documentos.

    4. Ejecute el Visual Studio 2010, crear un nuevo proyecto CRL, para esto elegir en la pestaa Archivo y aqu elegir la opcin ms adecuada.

    5. Nombrar los archivos como se indica en el archivo Actividades N 27 que se adjunta y asegurarse de almacenarlos en la carpeta Prctica N 27 al momento de crearlos.

    6. Realizar las acciones indicadas en el archivo adjunto. 7. Al finalizar la prctica de be guardar todos sus archivos, ya sea en su memoria USB o por

    correo electrnico y luego eliminar los archivos del equipo y vaciar la papelera de reciclaje.

    V

    EJERCICIOS

    1. Elaborar un programa que nos permita mediante estructuras y punteros a estructuras contar el nmero de palabras ingresadas por teclado en un texto hasta que se presione Ctrl.+Z.

    2. Depure el programa anterior para verificar el comportamiento de las variables y funciones empleadas.

    3. Modifique la aplicacin anterior para que la cantidad de palabras a contar sea variable.

    VI

    CUESTIONARIO

    1. Qu es un puntero a una estructura?.

  • Laboratorio de Programacin I Pgina 151

    Mgter. ngel Montesinos Murillo, Mgter. Manuel Ziga Carnero Sesin N 27

    2. Cmo se declara un puntero a una estructura?. 3. Cul es el operador que se usa para referirse a un puntero de estructuras?. 4. En qu se diferencia un puntero a estructura de un puntero a un variable simple?. 5. Qu utilidad tienen los punteros a estructuras?. 6. Cmo se accede mediante punteros a la informacin almacenada por una variable

    miembro de una estructura?. 7. Cmo se declara un arreglo de punteros a estructuras?. 8. Cmo se hace uso de un arreglo de punteros a estructuras?. 9. Cmo se declara un punteros a un arreglo de estructuras?. 10. Cmo se hace uso de un puntero a un arreglo de estructuras?. 11. Cmo se pasa a una funcin un arreglo de estructuras como argumento?.

    VII

    BIBLIOGRAFIA Y REFERENCIAS

    Deitel, Paul J., Deitel, Harvey M., "Cmo Programar en C++", 6ta Edicin, Ed. Pearson Educacin, Mxico 2009.

    Ceballos Sierra, Francisco J., "Curso de Programacin C++. Programacin Orientada a Objetos"; MADRID, RA-MA, 1991.

    Kernighan, Brian W., Ritchie, Dennis M., "El Lenguaje de Programacin C", 2da Edicin, Ed. Prentice Hispanoamrica S. A., Mxico 1991.