1. Conceptos de memoria.

Documentos relacionados
Apuntadores en C y C++

Tema 18: Memoria dinámica y su uso en C

PUNTEROS (Apuntadores)

Tema 6: Memoria dinámica

Apuntadores (Punteros)

Tema 13: Apuntadores en C

Elementos de un programa en C

ESTRUCTURA DE DATOS. Memoria estática Memoria dinámica Tipo puntero Declaración de punteros Gestión de memoria dinámica Resumen ejemplo

Laboratorio de Arquitectura de Redes. Punteros en lenguaje C

Tipos de Datos Estructurados

Informática PRÀCTICA 9 Curs Práctica Nº 9: Rango y precisión de representación de números en el ordenador.

Tema 2. El lenguaje JAVA

Nelson David Muñoz Politécnico CJIC TUTORIAL DISPLAYS

APUNTADORES. Un apuntador es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable.

Curso de Programación en C. Licenciatura, FCQeI. APUNTADORES.

Tipos de datos y Operadores Básicos

Definición de Memoria

Desde los programas más simples escritos en un lenguaje de programación suelen realizar tres tareas en forma secuencial.

PUNTEROS (APUNTADORES)

Informática PRÀCTICA 3 Curs Práctica Nº 3: Tipos de datos simples. Constantes y variables. Operadores aritméticos. Formato de salida.

Tema 2: Desarrollo de Algoritmos. E.E. de Algorítmica

UNIVERSIDAD DE LOS ANDES NUCLEO UNIVERSITARIO RAFAEL RANGEL (NURR) DEPARTAMENTO DE FISICA Y MATEMATICA AREA COMPUTACION TRUJILLO EDO.

TEMA 8: Gestión dinámica de memoria

Memoria Estática Punteros, Vectores y Matrices

Algoritmo, Estructuras y Programación II Ing. Marglorie Colina

El lenguaje C. 1. Identificadores, constantes y variables

TEMA 2. EL LENGUAJE C. ELEMENTOS BÁSICOS

LENGUAJE. Tema 2 Elementos de un programa

Guia#9: Punteros en C#.

Autoestudio 2: Variables y Operadores

abril de 2017 Desarrollo de aplicaciones en Java Tipos de datos primitivos Tipos de datos Elementos de aplicaciones simples

Organización de Computadoras. Clase 6

Memoria en C++ Punteros - Referencias Clases Y ahora, a trabajar! Memoria Dinámica en C++

Punteros. Programación en C 1

Conocimientos previos

ESTRUCTURAS. Struct Identificador_ tipo_estructura { Tipo miembro_1; /*Declaración de los miembros*/

Tema 05: Elementos de un programa en C

TEMA 02 TIPOS, OPERADORES Y EXPRESIONES

INTRODUCCIÓN A LA POO EN C++

Tema 1. Programación modular. Programación Avanzada Ingeniería Técnica en Informática de Gestión Jorge Badenas

Programación. Test Autoevaluación Tema 3

Operadores aritméticos. / División operando enteros o reales si operandos son entero resultado es entero. Resto de caso resultado real

Punteros. Lenguaje C ANSI

Laboratorio 5 Tema 7. Tipos de Datos Estructurados: Arreglos, Registros y Archivos

Punteros y aritmética de punteros. se almacena el operando

Punteros. Índice. 1. Qué es un puntero y por que son importantes.

Algoritmos y Programación I

Introducción a variables de tipo Puntero (Apuntadores) Contenidos. 1. Introducción a las variables puntero 2. Repaso:

INTRODUCCIóN A LA PROGRAMACIóN APUNTES DE JAVA APUNTES DE JAVA

Lección 2 Introducción al lenguaje C

Tema: Punteros.Puntero this en C#.

Memoria Dinámica. Jornadas de Marzo 2010 Grupo de Usuarios de Linux Tania Pérez

Práctica 2 - Manejo de estructuras de datos y punteros

UNIVERSIDAD TECNOLÓGICA DE LOS ANDES INGENIERÍA DE SISTEMAS E INFORMÁTICA FUNDAMENTOS DE PROGRAMACIÓN ARREGLOS (ARRAYS)

Una expresión es una combinación de uno o más operandos y operadores para obtener un resultado.

TEMA 2. LENGUAJE C. CONCEPTOS BÁSICOS Y PROGRAMACIÓN ELEMENTAL.

Diagrama de una computadora. Unidad Central de procesamiento (CPU)

Para crear un arreglo de cualquier tipo de elementos la sintaxis es:

Tipos de variables. Lenguaje C. Departamento de Electrónica. Tipos de datos, variables y constantes. Fundación San Valero

DEFINICIONES BÁSICAS DE LAS ESTRUCTURAS DE DATOS

Curso de Programación Avanzada en C

Unidad I Tipos de Datos en C

FUNDAMENTOS DE PROGRAMACIÓN. PRÁCTICA 11: Apuntadores

6.1.- Introducción a las estructuras de datos Tipos de datos Arrays unidimensionales: los vectores Operaciones con vectores.

Ficha de Aprendizaje N 13

Tema 10: Arreglos estáticos en C

Unidad Didáctica 2. Elementos básicos del lenguaje Java Tipos, declaraciones, expresiones y asignaciones

Objetivos de la sesión. Aplicación de consola 7/30/11. Código con que se inicia un programa en Visual C# (aplicación de consola)

VARIABLES, CONSTANTES Y EXPRESIONES ASIGNACIÓN. TIPOS ELEMENTALES. PRECEDENCIA DE LOS ESTRUCTURAS DE CONTROL. CONDICIONAL E

1.1 Tipos de Datos Primitivos. 1.2 Tipos de datos estructurados. 1.3 Definición de estructura de datos

Java. Introducción a la Programación Orientada a Objetos

funciones printf scanf

4. Operadores Operador asignación

Prof. Dr. Paul Bustamante

Práctica 3. Paso de parámetros entre subrutinas. 3. Consideraciones sobre el paso de parámetros

Clases y Objetos en C++

Especificación IEEE-754, para representar valores decimales en punto flotante de simple precisión.

Principios de Computadoras II

Repaso de lenguaje C. Índice. Repaso de lenguaje C. Repaso de lenguaje C: Tipos básicos

Memoria Dinámica en C++

Programación en Lenguaje C

Expresiones y sentencias

Comprender las diferencias entre tipos de datos primitivos similares, y aprender a elegir el tipo más conveniente en cada caso.

Lenguajes de Programación I

Manual de referencia de C++ Parte IV Variables Punteros. Preparado por Prof. Luis A. Ortiz Ortiz

Tipos Recursivos de Datos

Estructuras Dinámicas

ALGORITMOS Y PROGRAMACIÓN I Unidad 3

Programación I Unidad III. Tema: Tipos, estructuras y uniones

Transcripción:

1. Conceptos de memoria. Cuando se habla de memoria en el contexto de un programa, se trata de una serie de celdas que tienen la capacidad de almacenar datos durante la ejecución del programa. Estas celdas se denominan byte o antiguamente word representados en 8 bits. Que es la unidad básica de manejo de información en sistemas. Estas celdas tienen características básicas: Su dirección. Es el lugar donde el procesador encontrará esta celda. Esta dirección será un valor numérico que es único para cada celda. Las direcciones de las celdas se escriben por convención en formato hexadecimal. (Ej.: X03C4782). El valor almacenado. Cada celda tiene un tamaño de 8 bits, que permite un rango de 256 valores (de 0 a 255 / x00 a xff / 00000000 a 11111111). Su organización. Toda la memoria se organiza en forma secuencial (consecutivo), que significa que las celdas tienen una dirección que va incrementándose hasta el final físico de la misma. Las computadoras actuales estan organizadas de acuerdo a la arquitectura Von Neuman Dependiendo de las características de cada máquina, las direcciones de la memoria se organizan dentro de rango específicos de valores que luego cada sistema administra de acuerdo al contexto del hardware y software de base. Cuando se trabaja con máquinas con un sistema operativo subyacente, la administración de la memoria es propiedad exclusiva del sistema con el cual interactúa un programa. En el caso de programas que operan directamente sobre hardware, la administración es responsabilidad del propio programa. El programa solicita al sistema porciones de memoria para su uso interno y lleva un control sobre los bloques de memoria libres y en uso. Informática II Pág. 1

2. Variables: Tipos, tamaños y alojamiento. En los lenguajes de programación se definen variables, pero que son las variables? Son entidades que tienen un nombre, es de un tipo, un valor y un lugar donde se almacena. En la declaración de una variable se definen tres cosas: Nombre. Que tiene sus convenciones. En C una variable debe comenzar con una letra y luego tener la secuencia de letras y números hasta un máximo de longitud. Lugar de alojamiento. Porción de memoria que se reserva a esa variable. La variable tiene asociada la dirección de memoria donde comienza el alojamiento de los datos, cuantos bytes consecutivos se asignaron depende del tipo de variable. Para obtener la dirección asignada a una variable se utiliza un operador &. Entonces la dirección de cualquier variable se obtiene haciendo &variable. Tipo. Propios del lenguaje.(ej. int, float,etc). El tipo define dos cosas muy importantes: La longitud en byte que necesita (para el rango de valores que define), y la forma binaria en que se almacenan los valores asignados a la variable. En un instrucción de asignación, (int n= 8), el sistema toma su dirección donde almacenar y el tipo para definir el formato en bytes del dato a guardar. Es decir cuando la variable esta a la izquierda del igual, podemos decir que indica donde y como guardar. Cuando se usan variables dentro de una expresión, como un argumento de función, etc. (n!=6), aquí decimos en general que nos referimos al valor, pese a que el sistema buscará la dirección donde está, su tipo y luego interpreta para obtener el valor. Esto nos acerca a la idea de que la referencia a una variable dentro de una expresión, siempre hace mención al dato guardado y nos oculta la problemática de donde y como estan guardados los datos. Esto es una facilidad enorme para muchos usos dentro de la programación. Pero esto nos reduce las posibilidades de nuestros programas a cosas sencillas, ninguna posibilidad de controlar donde y como almacenar. Tampoco puedo definir datos complejos. A partir de este razonamiento es que surgen el concepto de punteros, que en el lenguaje C y luego el C++, tienen un papel determinante en la potencia del lenguaje. Resumen: a partir de una declaración del tipo, float area; queda definido: Nombre area. Tipo de dato float. Forma de almacenar: punto flotante de 32 bits. Comienza su almacenamiento en la dirección &area. Informática II Pág. 2

3. Los punteros. Los punteros se definen como un tipo de variable que almacena direcciones. Como toda variable tiene un nombre, es de un tipo, un valor y una dirección donde se almacena. Las características de las variables puntero, es que estan vinculadas a los tipos de datos primitivos del lenguaje o a tipos ya conocido o declarados en el programa. Si bien todos los punteros almacenan direcciones, por lo tanto su longitud (tamaño del dato que se almacena) es la misma, toman algunas características del tipo de dato del que provienen. Puedo definir punteros asociados a variables, a vectores (array) o a estructuras más complejas, como así tambien punteros universales. Para declarar un puntero, se debe especificar a que tipo de datos apuntara la dirección que contiene. La forma de declarar un puntero es: tipo * nombre; Ejemplo: float * nro; Esta variable puede almacenar un valor entero positivo, que representa una dirección, no almacena un número flotante, indica que en esta dirección (valor de la variable nro) comienza el almacenamiento de un número del tipo float y por lo tanto desde esa dirección serán cuatro 4 bytes. Para obtener el valor del flotante almacenado en la dirección que dice el puntero nro, se utiliza un operador de indirección *. Ejemplo: int n; declara una variable entera (32 bits / 4 bytes). int *j; declara un puntero tipo entero (almacena direcciones 32 bits / 4 bytes). j contiene una dirección donde comienza un entero. *j valor entero almacenado en la dirección apuntada por j (indirección). n contenido= valor del entero j contenido= valor de la dirección. &n dirección del entero en n *j contenido en la dirección de j. j = &n Almaceno en j la dirección de n. *j Representa el valor entero almacenado en n. Informática II Pág. 3

Representamos int n=40, *j=&n; suponemos que se almacenan: n en la dirección 0x0013FF60 y j en la dirección 0x0013FF48 Lugar: 4 byte donde esta almacenado j Lugar: 4 byte donde esta almacenado n Valor j 0x0013FF60 Valor *j=n 40 = 0x00000028 Dirección de j: &j 0x0013FF48 Dirección de n:&n j 0x0013FF60 4. Administración dinámica de memoria. Hasta ahora vimos definición de variables y punteros tomando direcciones de las variables ya definidas. Esto significa que lo definido es lo que puedo usar. El uso de punteros me permite administrar datos de longitud variable, como ser los array de tamaño dinámico. En el desarrollo de un programa, el array puede variar de tamaño por distintas situaciones. Como ejemplo simple si tenemos un archivo de texto que se necesita cargar a memoria. Al hacer el programa no se conoce cuantas líneas tiene y no se conoce el largo de cada línea. La solución es poder administrar la memoria de los datos en forma dinámica, que en este caso del ejemplo es poder hacer los array del tamaño que necesita al leer una línea. Es una modalidad diferente, que le da sentido al uso de punteros. Cuando se declara un puntero, se reserva memoria para almacenar el valor que maneja: una dirección, por lo tanto en las máquinas de 32 bits, el tamaño será de 4 bytes. Pero no reserva memoria para lo que apunta, y debe darse valor antes de usarse, para lo cual se utilizan funciones específicas. Para usar la memoria en forma dinámica en necesario recurrir a punteros, el cual apunta el inicio de la memoria reservada. Existen funciones especiales para solicitar al sistema bloques de memoria del tamaño que se necesite. Por ejemplo, si necesitamos un array de enteros, declaramos un puntero a enteros, (int *pint) que asigna memoria para la variable puntero (32 bits/4bytes), pero no memoria para el array, hay que obtenerla. Cuando se obtiene asigna al puntero la dirección del primer elemento del array. Aquí aparece un segundo objeto que es generado en forma dinámica y se accede a través del puntero. En este caso el puntero apunta a una zona de memoria reservada en forma dinámica. Esta memoria luego puede liberarse y asignar al puntero otro sector de diferente tamaño de acuerdo a las necesidades. La obtención de memoria en C++ se realiza con el operador new y su liberación con delete. Informática II Pág. 4

También podemos usar las llamadas de que provee C: void *malloc( size ); //llamada que devuelve puntero a un bloque de size bytes de tamaño. void *calloc(nmemb, size); //llamada que devielve puntero a un bloque de nmemb mienbros de size tamaño. void *free(void *ptr); //Libera un bloque otorgando por malloc/calloc. Ejemplos: acción requerida Asignación Liberación Un elemento del tipo 'float' float * pf = new float; delete pf; Array de '40' elementos de tipo 'float' float * pf = new float[40]; delete [] pf; Con el operador new obtenemos bloques de memoria según se necesite, asignando al puntero el valor de comienzo de la zona. Cuando se quiere liberar esa memoria usamos delete. Cuando se solicita cierta cantidad de memoria, puede pasar que no tenga disponible. El operador en ese caso devuelve un valor NULL, (cero binario). Por lo tanto es necesario tener en cuenta que en programas que requieren grandes cantidades de memoria puede fallar la asignación y es necesario verificar que el resultado del pedido no sea NULL. En el caso del ejemplo del array, el puntero tiene asignada la dirección del primer elemento, para acceder al segundo se debe incrementar el valor del puntero lo suficiente como para que apunte al siguiente elemento float. El puntero fue definido del tipo float, eso define el tamaño de lo que apunta, por lo tanto al incrementar (pf++) automáticamente avaza los 4 bytes que necesita para apuntar el segundo elemento. 5. Aritmética de punteros. La posibilidad de operar con punteros se ve facilitada por su propia algebra. Las operaciones matemáticas con punteros son ligeramente modificadas para darle un efecto que facilite los accesos a datos dentro de los bloques de memoria. Si es un apuntador a enteros (int *pi), cuando se incremente se quiere que avance hasta el próximo entero, por lo tanto deberá subir 4 posiciones de memoria que es el tamaño del un entero (int). De aquí que el incremento (decremento) de las variables punteros dependen del tipo de dato que apuntan. Este criterio es el usado en todas las operaciones básicas que pueden realizarse con variables punteros. La unidad de operación es el tamaño del tipo de datos que lo define. Podríamos decir entonces que si el puntero: Apuntador de char, su unidad de incremento/decremento será de 1 byte. Apuntador de short, su unidad de incremento/decremento será de 2 bytes. Apuntador de int, su unidad de incremento/decremento será de 4 bytes. Apuntador de double, su unidad de incremento/decremento será de 8 bytes. Si se extiende esta lógica a todas las operaciones, el resultado de una operación tendrá en cuenta el tipo. Las direcciones de memorias pueden considerarse números naturales, las operaciones básicas contempladas (+,-,*,/) deben devolver números naturales, para que apunten a una dirección válida. Informática II Pág. 5

Ejemplos: int *arr = new int[230];... cout << *(arr+22) << endl;... int suma=0; for (n=0;n<230;n++) suma += *(arr+n); Define un puntero y asigna memoria para un array. El valor de arr apunta al primer elemento. (arr+22) significa avanzar 22 posiciones, como las posiciones son (0,1,2,..,22) por lo tanto apunta al elemento 23. El valor de la direccion será valor de arr + 4*22. Este caso es idéntico, buscara el elemento n+1 valor de arr + 4*n. Nota: el * indica que nos interesa el valor almacenado. En los ejemplos puede verse claramente la facilidad de operar con punteros. Para recuperar el contenido de lo apuntado se utilisa el *, por lo tanto tener en cuenta que *(arr+n) significa el n+1elemmento, muy diferente de *arr+22 que significa sumar 22 al entero que apunta arr. int *arr = new int[230]; int *pfin=arr+229; int suma=0;... for (;arr<=pfin;pfin--) suma += *pfin; cout << suma << endl;... Define un puntero y asigna memoria para un array. Define otro puntero. Valor inicial: dirección de la posicion 229 apunta al elemento 230. Bucle ligeramente distinto, pero sumamente eficiente y simple. Recorre el array en sentido inverso, muestra la versatilidad de los punteros. Informática II Pág. 6

6. Doble indireción. Punteros de punteros. Los punteros contienen como datos direcciones, donde esta el valor almacenado. Si en esa dirección hay como dato otra dirección que indica donde esta el valor real, surge el concepto de punteros de punteros. Y puede darse que a su vez en el valor final apuntado haya otro puntero y así sucesivamente. Este concepto se conoce como in dirección. A través del operador * se definen punteros de doble in dirección. Ejemplo: int nro=4652, *pnro=&nro,**ppnro=&pnro; // Definicion y asignacion. cout << "Dir nro:" << &nro << " Valor :" << nro << endl; // Valores de un entero común. cout << "Dir pnro:" << &pnro << " Valor :" << pnro << endl; // Acceso a traves del puntero. cout << "Dir nro:" << &ppnro << " Valor :" << ppnro << endl; // Acceso a traves del puntero. cout << "Valor:" << *pnro << " Valor :" << **ppnro << endl; // Definicion y asignacion. Salida: Dir nro: 0013FF60 Valor :4652 // Direccion asignada al entero, y valor de la variable. Dir pnro:0013ff54 Valor :0013FF60 // Direccion asignada al puntero, y valor como variable. // Es la direccion que se asigno a la variable nro. Dir nro: 0013FF48 Valor :0013FF54 // Direccion asignada al puntero doble y valor almacenado // como variable, que es la direccion asignada a pnro. Valor: 4652 Valor: 4652 // Valores finales recuperados a través de los punteros Representación gráfica de doble in dirección Lugar: 4 byte donde esta almacenado ppnro ppnro 0x0013FF54 int n= 4562; int *pnro = &n; int **ppnro =&pnro; &n 0x0013FF60 &pnro 0x0013FF54 &ppnro 0x0013FF48 Dirección: &ppnro 0x0013FF48 Dirección: &pnro 0x0013FF54 pnro 0x0013F60 Lugar: 4 byte donde esta almacenado pnro Lugar: 4 byte donde esta almacenado nro **ppnro=*pnro=nro *ppnro=pnro ppnro 4562 0x0013FF60 0x0013FF54 **ppnro=*pnro=nro 4562 Dirección: &nro 0x0013FF60 Informática II Pág. 7

La potencia del uso de punteros se puede visualizar a través del siguiente ejemplo, donde se define en forma dinámica una matriz de números flotantes de dimensiones variables. float **matrix; int filas=5, col=5; // puntero a un área de punteros a float. // tamaño de las filas y columnas de la matriz. // Cada fila podría ser de distinta longitud de columnas Matriz no rectangular. matrix = new float*[filas]; //primer reserva de un array de punteros: uno puntero a cada fila. for(int i=0;i<filas;i++){ matrix[i] = new float[col]; // p/cada fila reserva 5 celdas float de cada columna. Tam: 5*4 =20 bytes. for(int j=0; j<col;j++) matrix[i][j]=(float)(i+1)*(j+1)*3.14; } // Asignamos valore iniciales (una cuenta obvia). Podemos acceder a esta matriz de diferentes formas, con idénticos resultados: for(int i=0;i<filas;i++){ for(int j=0; j<col;j++) cout << matrix[i][j] << "\t" ; cout <<endl; } Salida: 3.14 6.28 9.42 12.56 15.7 6.28 12.56 18.84 25.12 31.4 9.42 18.84 28.26 37.68 47.1 12.56 25.12 37.68 50.24 62.8 15.7 31.4 47.1 62.8 78.5 float *f;// puntero intermedio for(int i=0;i<filas;i++){ f = *(matrix+i); for(int j=0; j<col;j++) cout << *f++ << "\t"; cout <<endl; } Salida: 3.14 6.28 9.42 12.56 15.7 6.28 12.56 18.84 25.12 31.4 9.42 18.84 28.26 37.68 47.1 12.56 25.12 37.68 50.24 62.8 15.7 31.4 47.1 62.8 78.5 for(int i=0;i<filas;i++){ for(int j=0; j<col;j++) cout << *(*(matrix+i)+j) << "\t " ; cout <<endl; } Salida: 3.14 6.28 9.42 12.56 15.7 6.28 12.56 18.84 25.12 31.4 9.42 18.84 28.26 37.68 47.1 12.56 25.12 37.68 50.24 62.8 15.7 31.4 47.1 62.8 78.5 Informática II Pág. 8

7. Estructuras. Las agrupaciones de datos a través de los vectores (arrays) son homogéneos, ya que son del mismo tipo. Las estructuras son un tipo de datos que define el usuario permitiendo asociar diversos tipos de datos y manejarlos como una unidad o grupo. Las estructuras permiten crear registros de información de entidades/objetos complejos. Una entidad necesita asociar sus datos de diferentes tipos, y manejarlos como una unidad de información. Para la definición de los datos agrupados se utiliza la siguiente sintaxis: struct nombre_del_tipo { datos/campos... } //fin de la declaración Supongamos que necesitamos asociar en un registro los resultados de un turno de exámenes. Datos involucrados: Numero acta, fecha, materia, datos del alumno y nota. Una definición primaria de un registro de cada examen sería: Nombre del tipo/ estructura: examen Lista de campos miembros. Lista de variables. reg_exa Referencia a campos miembros. Array de estructuras. Informática II Pág. 9

Se define un tipo de datos/registro llamado examen, que contiene miembros detallados en el orden que serán almacenados. Al final se declara una variable del tipo examen llamada reg_exa. Asigna memoria para todos los tipos de datos que involucra la estructura o registro. El ejemplo muestra como se pueden seguir definiendo otras variables (nuevoexa), de la misma forma se declara un array y como se accede al miembro 33 a través del subíndice 32. El punto es el operador de conexión entre la variable del registro y el miembro al que se referencia. En este caso tomará la dirección de comienzo del registro, almacenada en la variable reg_exa y le sumará el desplazamiento necesario para alcanzar el dato buscado. En el caso de reg_exa.nacta, como es el primer campo de la estructura, el desplazamiento es cero, pero en el caso de reg_exa.fechaexamen tendrá un desplazamiento de 4 byte, que es lo que ocupa el campo nacta. Una definición más elaborada sería: Que se usa de la siguiente manera: En la definición rg.alumno.legajo.nro el punto es el operador de conectividad, y el lugar donde se aloja el entero nro se aplica las mismas reglas del desplazamiento de memoria mencionadas. Como en todo tipo de datos, es posible definir punteros a estructuras, que tienen las características típicas de todo puntero: Almacenan una dirección donde comienzan los datos del registro/estructura. Tienen el tamaño de la estructura y operan en su aritmética con ellos. Ocupan en memoria lo necesario para almacenar una dirección (4 bytes). Tienen la misma versatilidad de los punteros de tipos primitivos. Permiten la administración dinámica de memoria. Informática II Pág. 10

En el caso particular de estructuras/registros para evitar confusiones, se utiliza el operador -> para el uso de punteros. En el ejemplo analizado un puntero se define: examennew *pexa; pexa = new examennew[9]; pexa->nmesa.nacta = 33; pexa->nmesa.materia = 456; Haciendo extensivo, analizar la siguiente porción de código: Formas de inicializar. Array de Punteros. Uso de Punteros. Cálculo de tamaños. Salida.. Informática II Pág. 11

Uniones. Las uniones son otro tipo de datos que pueden definir. Es un tipo especial de estructura. Su función es poder redefinir un segmento de memoria de acuerdo a las necesidades. Los miembros de una unión, comparten el mismo segmento de memoria, por lo tanto solo puedo usar una por vez. A veces esto es requerido para almacenar de una forma y recuperar de otra los datos, haciendo las conversiones más simples. Pero su mayor uso, es el compartir áreas de datos que de acuerdo a ciertos condicionantes puedan almacenar diferentes tipos de datos. En el siguiente ejemplo, en una misma área de datos puedo guardar números en formato enteros largos, enteros cortos o números en formato flotantes. union int_float { int nint [10]; float nfloat [10]; unsigned char nchar [40]; } i_f; i_f.nint[0]=1254; i_f.nfloat[1] = 9.8f; i_f.nchar[8] = 58; Esto es extensible a tipos de datos más complejos, como estructuras, lo que permite que compartan áreas de memoria registros con formatos totalmente diferentes. Informática II Pág. 12