CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN...

8

Click here to load reader

Transcript of CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN...

Page 1: CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN …quidel.inele.ufro.cl/%7Ejhuircan/PDF_DISE%D1O/Hp03.pdf · 3.3. PUNTEROS Y ARREGLOS ... Ej 3.9. Acceso de matrices mediante punteros

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; ...}

Page 2: CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN …quidel.inele.ufro.cl/%7Ejhuircan/PDF_DISE%D1O/Hp03.pdf · 3.3. PUNTEROS Y ARREGLOS ... Ej 3.9. Acceso de matrices mediante punteros

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].

Page 3: CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN …quidel.inele.ufro.cl/%7Ejhuircan/PDF_DISE%D1O/Hp03.pdf · 3.3. PUNTEROS Y ARREGLOS ... Ej 3.9. Acceso de matrices mediante punteros

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).

Page 4: CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN …quidel.inele.ufro.cl/%7Ejhuircan/PDF_DISE%D1O/Hp03.pdf · 3.3. PUNTEROS Y ARREGLOS ... Ej 3.9. Acceso de matrices mediante punteros

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.

Page 5: CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN …quidel.inele.ufro.cl/%7Ejhuircan/PDF_DISE%D1O/Hp03.pdf · 3.3. PUNTEROS Y ARREGLOS ... Ej 3.9. Acceso de matrices mediante punteros

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.

Page 6: CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN …quidel.inele.ufro.cl/%7Ejhuircan/PDF_DISE%D1O/Hp03.pdf · 3.3. PUNTEROS Y ARREGLOS ... Ej 3.9. Acceso de matrices mediante punteros

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.

Page 7: CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN …quidel.inele.ufro.cl/%7Ejhuircan/PDF_DISE%D1O/Hp03.pdf · 3.3. PUNTEROS Y ARREGLOS ... Ej 3.9. Acceso de matrices mediante punteros

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");}

Page 8: CAPÍTULO 3 ARREGLOS, PUNTEROS Y ASIGNACIÓN …quidel.inele.ufro.cl/%7Ejhuircan/PDF_DISE%D1O/Hp03.pdf · 3.3. PUNTEROS Y ARREGLOS ... Ej 3.9. Acceso de matrices mediante punteros

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.