estructuras
Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
estructuras [2014/08/28 13:46] – [Alineamiento] lmateu | estructuras [2015/09/30 20:03] (actual) – [Estructuras recursivas] lmateu | ||
---|---|---|---|
Línea 88: | Línea 88: | ||
(*u).x ≡ u->x | (*u).x ≡ u->x | ||
| | ||
- | Y por lo tanto podemos reescribir la función | + | Y por lo tanto podemos reescribir la función |
< | < | ||
Línea 134: | Línea 134: | ||
struct punto *nuevoPunto(float x, float y) { | struct punto *nuevoPunto(float x, float y) { | ||
/* se pide espacio para un punto en el heap */ | /* se pide espacio para un punto en el heap */ | ||
- | struct punto *pa= (struct punto*)malloc(sizeof(struct punto)); | + | struct punto *pa= malloc(sizeof(struct punto)); |
pa->x= x; | pa->x= x; | ||
pa->y= y; | pa->y= y; | ||
Línea 152: | Línea 152: | ||
==== Typedef ==== | ==== Typedef ==== | ||
- | Escribir siempre struct punto en cada declaración resulta pesado sintácticamente. | + | Escribir siempre |
< | < | ||
Línea 158: | Línea 158: | ||
</ | </ | ||
- | Esto intruduce 2 nuevos tipos: ENTERO y PUNTERO. | + | Esto intruduce 2 nuevos tipos: |
< | < | ||
Línea 171: | Línea 171: | ||
</ | </ | ||
- | Es como haber eliminado el typedef y substituido ENTERO por x y PUNTERO por p. | + | Es como haber eliminado el //typedef// y substituido |
¿A qué sería equivamente escribir lo siguiente? | ¿A qué sería equivamente escribir lo siguiente? | ||
Línea 179: | Línea 179: | ||
</ | </ | ||
- | De la misma forma se pueden declarar el tipo Punto: | + | De la misma forma se pueden declarar el tipo //Punto//: |
< | < | ||
Línea 196: | Línea 196: | ||
</ | </ | ||
+ | Observe que la etiqueta que viene después de //struct// es opcional. | ||
+ | También se pudo haber colocado explícitamente la etiqueta //punto//: | ||
+ | |||
+ | < | ||
+ | typedef struct punto { | ||
+ | float x, y; | ||
+ | } Punto; | ||
+ | </ | ||
+ | |||
+ | //La etiqueta del struct se puede omitir cuando no se va a usar a continuación en el archivo.// | ||
==== Estructuras recursivas ==== | ==== Estructuras recursivas ==== | ||
Línea 213: | Línea 223: | ||
</ | </ | ||
- | La declaración de Node también se puede escribir como: | + | La declaración de //Node// también se puede escribir como: |
< | < | ||
Línea 222: | Línea 232: | ||
</ | </ | ||
- | Pero esto genera | + | Observe que en este caso la etiqueta //node// sí se debe especificar porque se usa dentro de //Nodo//. |
+ | No se puede usar //Node// directamente como en el ejemplo de más abajo porque se generaría | ||
< | < | ||
Línea 231: | Línea 242: | ||
</ | </ | ||
- | El problema es que el tipo Node es desconocido en el momento de declarar el campo next. Recuerde que en C, el alcance de un identificador comienza en el punto de programa en donde se definió. | + | El problema es que el tipo Node es desconocido en el momento de declarar el campo next. Recuerde que en C, el alcance de un identificador comienza en el punto del programa en donde se definió. |
=== Ejemplo: recorrer una lista enlazada === | === Ejemplo: recorrer una lista enlazada === | ||
Línea 251: | Línea 262: | ||
< | < | ||
void insertar(Node **ppnode, int y) { | void insertar(Node **ppnode, int y) { | ||
- | Node *ins; | + | Node *pnode= *ppnode; |
- | while (*ppnode!=NULL && | + | while (pnode != NULL && |
- | ppnode= &(*ppnode)-> | + | ppnode= & pnode->next; |
- | + | pnode= *ppnode; | |
- | ins= (Node*)malloc(sizeof(Node)); | + | |
+ | | ||
+ | | ||
ins->x= y; | ins->x= y; | ||
- | ins-> | + | ins-> |
*ppnode= ins; | *ppnode= ins; | ||
} | } | ||
Línea 285: | Línea 298: | ||
=== Ejercicio 2 === | === Ejercicio 2 === | ||
- | Resuelva la parte b de la pregunta 2 del [[http:// | + | Resuelva la parte b de la pregunta 2 del [[http:// |
==== Enum ==== | ==== Enum ==== | ||
Línea 303: | Línea 316: | ||
Los identificadores INT y FLOAT son constantes y por lo tanto no pueden aparecer al lado izquierdo de una asignación. | Los identificadores INT y FLOAT son constantes y por lo tanto no pueden aparecer al lado izquierdo de una asignación. | ||
+ | |||
+ | Alternativamente se puede usar typedef para poder usar el tipo Tag en vez de enum tag que es muy largo: | ||
+ | |||
+ | < | ||
+ | #include < | ||
+ | |||
+ | typedef enum { INT, FLOAT } Tag; | ||
+ | |||
+ | int main() { | ||
+ | Tag a= INT; | ||
+ | Tag b= FLOAT; | ||
+ | printf(" | ||
+ | } | ||
+ | </ | ||
Para hacer que las etiquetas comiencen de 1: | Para hacer que las etiquetas comiencen de 1: | ||
Línea 415: | Línea 442: | ||
</ | </ | ||
- | ¿Cómo se puede garantizar que n esté alineado? | + | ¿Cómo se puede garantizar que //n// esté alineado? |
estructura sin saber su tipo. Conoce el tamaño la región pedida, pero no sabe si es para un arreglo de 8 caracteres, | estructura sin saber su tipo. Conoce el tamaño la región pedida, pero no sabe si es para un arreglo de 8 caracteres, | ||
- | para el cual no hay requerimiento de alineamiento, | + | para el cual no hay requerimiento de alineamiento, |
- | se pone en el peor caso: 8. Malloc siempre retorna direcciones múltiplo de 8. | + | se pone en el peor caso: 8. |
- | Pero aún así si el compilador asigna un desplazamiento 0 para c y un desplazamiento 1 para n, la variable n | + | Pero aún así si el compilador asigna un desplazamiento 0 para //c// y un desplazamiento 1 para //n//, |
- | estaría desalineada. | + | la variable |
- | ocupar los bytes 1, 2 y 3 de la estructura. | + | La solución está en que el compilador asigna un desplazamiento 4 para //n// y deja sin |
+ | ocupar los bytes 1, 2 y 3 de la estructura. | ||
El compilador sacrifica un poco de memoria para ganar eficiencia en tiempo de ejecución. | El compilador sacrifica un poco de memoria para ganar eficiencia en tiempo de ejecución. | ||
una variable no está alineada, el procesador requiere más ciclos del reloj para leerla o modificarla. | una variable no está alineada, el procesador requiere más ciclos del reloj para leerla o modificarla. | ||
Línea 428: | Línea 456: | ||
//bus error// y el programa no continúa. | //bus error// y el programa no continúa. | ||
- | Para responder cual es el tamaño de '' | + | Para responder cual es el tamaño de //sizeof struct T// consideremos este código: |
< | < |
estructuras.1409233619.txt.gz · Última modificación: 2014/08/28 13:46 por lmateu