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: 2012/08/03 00:16 por lmateu