CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN...
Click here to load reader
Transcript of CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN...
CAPÍTULO 3
ARREGLOS, PUNTEROS Y ASIGNACIÓN DINÁMICA DE MEMORIA
Un arreglo, también llamado matriz (array), es un conjunto de elementos dispuestos secuencialmente, quecontienen datos del mismo tipo. El tamaño de un arreglo está dado por su número de elementos. El tamaño se debefijar cuando se declara el arreglo. El tamaño y el tipo de datos del arreglo definen el espacio de memoria queocupará dicha matriz. Estos arreglos pueden ser de uno o varias dimensiones. No existe límite, salvo la cantidadde memoria existente en el computador.
3.1. DECLARACIÓN DE UN ARREGLO O MATRIZ
Su formato es el siguiente:
tipo ident_arreglo[num_elementos]; tipo ident_arreglo[num_fila][num_col];
Ej 3.1. Declaración de arreglo unidimensional y bidimensional
void(){
int mat[10];...
}
void(){
int tabla[10][2];...
}
En este caso se ha definido un arreglo de 10 elementos enteros. Los que ocupan 20 bytes de memoria. Elacceso de los elementos se hace desde el elemento 0 al elemento 9, es decir:
mat[0] mat[1] ..... mat[9]
Acceso a los elementos de una matriz
Pueden ser accesado en forma individual o por medio de un índice, el cual debe ser entero. Para inicializarun elemento en particular:
Ej 3.2. Diferentes formas de acceso de un arreglo.
void main(){ int matriz[10]; matriz[3]=10; matriz[9]=5; ....}
void main(){ int m[10]; m[3]=m[9]=4; m[0]=0; ....}
void main(){ int m[5],i=3; m[i]=3; m[i*2-1]=65; ...}
26 Preparado por Juan Ignacio Huircán
Ej 3.3. Utilizando un ciclo for para inicializar un arreglo:
void main(){ int i, m[10]; for(i=0;i<10;i++) m[i]=0; /* pone en 0 todos los elementos del arreglo */...}
Ej 3.4. Declarando e inicializando un arreglo de 5 elementos.
void main() { int ma[5]={3,4,6,89,10}; .... }
Si se sobrepasan los límites del arreglo, el compilador NO entregará mensaje de error alguno. El acceso aarreglo bidimensional se puede realizar de acuerdo a Ej 3.3.
Ej 3.5. Declaración e inicialización de una matríz de dos dimensiones.
void main(){ int a[2][3]= {
{1,2,3},{4,5,6}
};}
En este caso es una matriz que tiene dos filas y tres columnas, donde:
a[0]: contiene la direccion de memoria de la primera filaa[1]: contiene la dirección de memoria de la segunda fila.a contiene la dirección de a[0].
Herramientas de Programación 27
Ej 3.6. El programa despliega el contenido de la matriz a[ ][ ] en pantalla.
#include<stdio.h>void main(){ int a[2][3]= {
{1,2,3}, {4,5,6} };
int i, j; for(i=0; i<2;i++)
for(j=0;j<3;j++) printf( "%d ", a[i][j]);}
3.2. CADENAS DE CARACTERES
Las cadenas de caracteres (string) son arreglos que se componen de caracteres alfanuméricos. El final deuna cadena se indica con un caracter especial, éste es un byte compuesto por 8 ceros binarios, es decir 0x00.Luego, el tamaño de la cadena debe ser lo suficientemente grande para contener dicho caracter inclusive. Unacadena declarada como cad[10], podrá contener como máximo 9 caractéres.
El archivo de cabecera string.h proporciona una serie de funciones que permiten el manejo de cadenasde caracteres. No existen operadores que permitan comparar cadenas o copiar una cadena en otra, por lo que sedebe hacer uso de las funciones definidas en string.h.
Ej 3.7. Tratamiento de cadenas.
#include<stdio.h>#include<string.h>
void main(){ char cad[10], buf[10]; strcpy(cad, "HOLA"); /* Copia en Cad la cadena "HOLA" */ strcpy(buf, cad); /* Pasa el contenido de cad a buf */ if (!strcmp(buf,cad)) printf("SON IGUALES!");}
La función strcpy es una contracción de la operación string copy. Al realizar dicha operación laprimera vez, el contenido de cad es el siguiente:
0x48 0x4f 0x4c 0x41 0x00 ?? ?? ?? ?? ??H O L A
La función strcmp permite comparar dos cadenas de caracteres. Esta comparación se realiza hasta elcaracter 0x00 de final de cadena. Es importante distinguir entre 'A' y "A", el primero es el caracter A que secodifica en un byte (0x41) y el segundo es la cadena que contiene un caracter A y ocupa dos bytes. (0x41,0x00).
28 Preparado por Juan Ignacio Huircán
Ej 3.8. Inicializando una matríz de caracteres.
void main(){ char nombres[3][10]={ "IGNACIO",
"PEDRO","JUAN"
};}
3.3. PUNTEROS Y ARREGLOS
También el acceso a los arreglos puede hacerse mediante punteros asignando un puntero al primerelemento del arreglo.
Ej 3.9. Acceso de matrices mediante punteros.
void main(){ char mat[10], *pmat, i; mat[0]=10;mat[1]=30;mat[2]=50;mat[3]=60; pmat=&mat[0]; /* pmat apunta a mat[0] */ pmat++; i=*pmat; i=*pmat +1; i=*(pmat+1); i=*++pmat; i=++*pmat;}
Las operaciones realizadas sobre mat son las siguientes:
pmat=&mat[0]; pmat apunta a mat[0]pmat++; pmat apunta a mat[1]i=*pmat; i= 30i=*pmat +1; i= 31i=*(pmat+1); i= 50, pmat apunta a mat[2]i=*++pmat; se efectua ++pmat, es decir pmat apunta a mat[3], luego i=60i=++*pmat; i=60, luego mat[2]= 61, se incrementa.
Herramientas de Programación 29
3.4. ASIGNACIÓN DINÁMICA DE MEMORIA.
Modelos de compilación
El compilador C permite el trabajo con diferentes modelos de compilación, es decir, las tres zonas queforman parte de un programa en C, el código, los datos y la pila (stack), pueden tener diferentes tamaños.
Considerando la forma de direccionamiento en la familia 80x86, se han implementado diferentes modelosde asignación de memoria para los computadores basados en dichos microprocesadores.
El modelo S (Small Model)
Para el caso del compilador TurboC, este es el modelo por defecto y es suficiente para la mayoría de lasaplicaciones. Las variables globales y estáticas no pueden ocupar más de 64Kbytes. Los punteros se codifican en16 bits (near).
reserva
pila
zonaasignación dinámica
variables globalesy estáticas
CODIGO Máx. 64Kb
Máx. 64Kb
Limitado según
SP
DS, SS
CS
(farheap)
(heap)
Mem disponible
Figura 3.1. Modelo small.
Para este modelo de compilación existen dos zonas de memoria, las cuales pueden ser utilizadas. Laprimera se encuentra entre las variables globales y la pila (stack), se conoce con el nombre "heap" y puede seraccesada utilizando punteros de tipo near, los cuales son codificados en16 bits. la otra zona se conoce comofarheap y debe ser accesada con punteros de tipo far, dicho puntero es codificado en 32 bits.
El modelo Tiny
Este modelo se utiliza cuando hay que limitar la cantidad de memoria que se dedica a un programa. Elcódigo, los datos y la pila se encuentran restringidos a un máximo de 64Kbytes. Se usan sólo punteros near.
30 Preparado por Juan Ignacio Huircán
pila
zonaasignación dinámica
variables globalesy estáticas
CODIGO
Máx. 64Kb
SP
CS, DS, SS
Figura 3.2. Modelo Tiny.
El modelo Medium
El CODIGO puede alcanzar hasta 1 Mbyte, pero las variables estáticas y la pila quedan restringidas a unmáximo de 64Kbytes. Los punteros del codigo son de tipo far y los de datos son de tipo near.
(farheap)
pila
zonaasignación dinámica
variables globalesy estáticas
CODIGO Máx. 1Mb
Máx. 64Kb
Limitado según
SP
DS, SS
CS
Mem disponible
Figura 3.3. Modelo small.
El modelo Compact
El CÓDIGO está limitado a 64 Kbytes, pero los datos pueden extenderse hasta 1Mbyte, esto implica quepunteros far deben ser usados para los datos.
El modelo Large
Tanto el CODIGO como las variables pueden extenderse hasta 1 Mbyte. Todos los punteros se codificanen 32 bits (far).
El modelo Huge
Son usados punteros tipo far tanto para el código como para los datos.
Herramientas de Programación 31
heap
pila
variables globalesy estáticas
CODIGO Máx. 1Mb
Máx. 1Mb
Limitado según
SP
DS
CS
Mem disponible
Figura 3.4. Modelo huge.
Utilizando memoria dinámica
La asignación dinámica de memoria nos permite la utilización y definición de variables las cuales excedenel máximo permitido por los modelos de compilación.
Existen diferentes funciones las que están definidas en alloc.h y mem.h.
Ej 3.10. Reservando memoria dinámica
#include<alloc.h>#include<conio.h>#include<stdio.h>float datos[10000];long sizemem=0;char *p; /* puntero near */void main(){ int i; sizemem=coreleft(); /* Verifica mem disponible */ printf("%lu ",sizemem); if(sizemem>20000) {
p=(char *)malloc(20000);for(i=0;i<20000;i++) *(p+i)=0x00; /* rellena con 0x00 la zona
reservada */getch();sizemem=coreleft();printf("%lu ",sizemem);getch();free(p); /* Libera memoria reservada */sizemem=coreleft();printf("%lu ",sizemem);
} else printf("NO EXISTE Memoria Suficiente\n");}
32 Preparado por Juan Ignacio Huircán
Ej 3.11.Reservando memoria dinámica en la zona "farheap"
/* Este programa se debe ejecutar fuera de editor del Turbo C */
#include<alloc.h>#include<conio.h>#include<stdio.h>
float datos[10000];long sizemem=0;
char far *p; /* Puntero far */
void main(){ long i; sizemem=farcoreleft(); /* Verifica memoria en zona farheap */ printf("%lu ",sizemem); if(sizemem>100000) {
p=(char far *)farmalloc(100000); /* Reserva 100000 bytes */for(i=0;i<100000;i++) *(p+i)=0x00;getch();sizemem=farcoreleft();printf("%lu ",sizemem);getch();farfree(p);sizemem=farcoreleft();printf("%lu ",sizemem);
}else{
printf("No queda Memoria disponible \n");getch();
}}
En estos programas se han utilizado algunas funciones definidas en alloc.h. Las funcionesfarcoreleft() y coreleft(), determinan cuanta memoria disponible existe tanto en el área far como en elárea near.