arreglos
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Próxima revisión | Revisión previa | ||
| arreglos [2012/08/03 00:16] – creado lmateu | arreglos [2016/09/27 13:02] (actual) – [Arreglos globales] lmateu | ||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| ===== Arreglos ===== | ===== Arreglos ===== | ||
| - | En realidad C no posee verdaderos arreglos como ocurre en Java. En C un arreglo de n elementos de un tipo T corresponde a un puntero al comienzo de un área de memoria que contiene n variables consecutivas de tipo T. De modo que lo que se vió en el capítulo sobre punteros es el 90% de lo que se puede escribir sobre arreglos. | + | En realidad C no posee verdaderos arreglos como los de Java. En C un arreglo de n elementos de un tipo T corresponde a un puntero al comienzo de un área de memoria que contiene n variables consecutivas de tipo T. De modo que lo que se vió en el capítulo sobre punteros es el 90% de lo que se puede escribir sobre arreglos. |
| - | El otro 10% corresponde la declaración de arreglos de tamaño constante. | + | El otro 10% corresponde |
| ==== Arreglos globales ==== | ==== Arreglos globales ==== | ||
| Línea 23: | Línea 23: | ||
| </ | </ | ||
| - | El primero es un arreglo de 100 elementos inicializados por omisión en 0. El tipo de la expresión //a// es //double*// y corresponde a la dirección del primer elemento de un área de memoria global con espacio para 100 variables consecutivas de tipo double. | + | El primero es un arreglo de 100 elementos inicializados por omisión en 0. El tipo de la expresión //a// es //double*// y corresponde a la dirección del primer elemento de un área de memoria global con espacio para 100 variables consecutivas de tipo double. |
| En este caso //a// **no es una variable**. | En este caso //a// **no es una variable**. | ||
| Línea 29: | Línea 29: | ||
| a= (double*)malloc(100*sizeof(double)); | a= (double*)malloc(100*sizeof(double)); | ||
| | | ||
| - | En este caso el identificador //a// representa una constante | + | En este caso el identificador //a// representa una constante |
| - | El arreglo b corresponde a un arreglo de 4 elementos preinicializados con constantes conocidas en tiempo de compilación. | + | {{ : |
| + | Volviendo al código de arriba, el arreglo b corresponde a un arreglo de 4 elementos preinicializados con constantes conocidas en tiempo de compilación. | ||
| + | |||
| + | Nótese que el compilador no genera ningún código para inicializar los arreglos globales. | ||
| + | |||
| + | === Inicialización de punteros globales === | ||
| + | |||
| + | Las siguientes declaraciones globales son válidas: | ||
| + | |||
| + | < | ||
| + | int x, y; | ||
| + | int *p= &x; | ||
| + | int *q[]= {&x, &y}; | ||
| + | </ | ||
| + | |||
| + | En este caso //&x// y //&y// se considera constantes. | ||
| ==== Arreglos automáticos ==== | ==== Arreglos automáticos ==== | ||
| - | También es posible declarar un arreglo local a una función. | + | También es posible declarar un arreglo local a una función. |
| < | < | ||
| + | void ordenar(int *p, int n) { | ||
| + | ... | ||
| + | } | ||
| + | |||
| int f(int *p) { | int f(int *p) { | ||
| int a[20], i, s= 0; | int a[20], i, s= 0; | ||
| for (i= 0; i<20; i++) | for (i= 0; i<20; i++) | ||
| a[i]= p[i]; | a[i]= p[i]; | ||
| - | ordenar(a, 20); | + | ordenar(a, 20); /* ordenar recibe ' |
| for (i= 1; i<20; i++) | for (i= 1; i<20; i++) | ||
| s+= a[i]-a[i-1]; | s+= a[i]-a[i-1]; | ||
| Línea 48: | Línea 67: | ||
| </ | </ | ||
| + | Acá //a// es un arreglo de 20 elementos que es creado al inicio de f y destruidos en el retorno de f. Cuidado, una función no debe retornar la dirección de un arreglo local. | ||
| + | |||
| + | Observe aquí como se usa el arreglo en donde corresponde usar un puntero. | ||
| + | |||
| + | === Arreglos locales preinicializados === | ||
| + | |||
| + | También es posible inicializar un arreglo local. | ||
| + | |||
| + | < | ||
| + | double f(double x) { | ||
| + | double a[]= { x, x*x, x*x*x }; | ||
| + | ... | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | El compilador genera código de máquina para evaluar las 3 expresiones. | ||
| + | |||
| + | === Ejercicio === | ||
| + | |||
| + | Edite el archivo loop.c con el siguiente código: | ||
| + | |||
| + | < | ||
| + | int main() { | ||
| + | int i, j, a[10]; | ||
| + | for (i= 0; i<=10; i++) | ||
| + | a[i]= 0; | ||
| + | return a[5]; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Compile y ejecute con: | ||
| + | |||
| + | % gcc -m32 loop.c | ||
| + | % ./a.out | ||
| + | |||
| + | La opción -m32 especifica que se genere código para x86. De otro modo en plataformas de 64 bits se genera código de 64 bits con resultados diferentes. | ||
| + | |||
| + | * ¿Por qué pasa lo que pasa? | ||
| + | * Edite el programa y borre la variable j y vuelva a compilar y ejecutar | ||
| + | |||
| + | Vuelva a agregar la variable j exactamente como en el original y recompile nuevamente usando la opción -g para incluir información de debugging. | ||
| + | |||
| + | < | ||
| + | % gcc -m32 -g bug.c | ||
| + | % gdb a.out | ||
| + | GNU gdb (Gentoo 7.3.1 p2) 7.3.1 | ||
| + | ... | ||
| + | Reading symbols from / | ||
| + | (gdb) b main | ||
| + | Breakpoint 1 at 0x80483ba: file bug.c, line 4. | ||
| + | (gdb) run | ||
| + | Starting program: / | ||
| + | |||
| + | Breakpoint 1, main () at bug.c:4 | ||
| + | 4 for (i= 0; i<=10; i++) | ||
| + | (gdb) n | ||
| + | 5 a[i]= 0; | ||
| + | (gdb) n | ||
| + | 4 for (i= 0; i<=10; i++) | ||
| + | (gdb) n | ||
| + | 5 a[i]= 0; | ||
| + | (gdb) n | ||
| + | 4 for (i= 0; i<=10; i++) | ||
| + | (gdb) n | ||
| + | 5 a[i]= 0; | ||
| + | (gdb) n | ||
| + | 4 for (i= 0; i<=10; i++) | ||
| + | (gdb) n | ||
| + | 5 a[i]= 0; | ||
| + | (gdb) n | ||
| + | 4 for (i= 0; i<=10; i++) | ||
| + | (gdb) n | ||
| + | 5 a[i]= 0; | ||
| + | (gdb) n | ||
| + | 4 for (i= 0; i<=10; i++) | ||
| + | (gdb) p i | ||
| + | $1 = 4 | ||
| + | </ | ||
| + | |||
| + | Continúe así hasta que i tome el valor 10. Ejecute una iteración más. ¿Qué valor toma la variable i? | ||
| + | |||
| + | ==== Arreglos dinámicos ==== | ||
| + | |||
| + | Son todos los arreglos que se crean llamando a malloc y se destruyen explícitamente con free, como se vió en el capítulo sobre punteros. Por lo tanto se ubican en el heap. Su valor inicial es indeterminado y por lo tanto deben ser inicializados por el programador despúes de su creación. | ||
| + | |||
| + | Observe que Java no posee arreglos globales ni locales a una función. | ||
arreglos.1343952979.txt.gz · Última modificación: por lmateu
