Copy Link
Add to Bookmark
Report

3x04: Como programar en C en muchos pasos (III)

eZine's profile picture
Published in 
0ri0n Team Venezuela
 · 2 hours ago

-[ 3x04.txt ]---------------------------------------------------------------- 
-[ Como programar en C en muchos pasos (III)]-------------------[ El_Max_5 ]-
--------------------------------------------------------[ maxz-5@cantv.net ]-

Indice:
ñññññññ
1. Arreglos.
2. Arreglos de Caracteres.
3. Arreglos multidimensionales.
4. Estructuras.
5. Arreglos y estructuras.
a. Arreglos de estructuras
b. Estructuras con arreglos como miembros.
6. Uniones


1. Arreglos
ññññññññ

En los arreglos se colocan variables del mismo tipo. Para declararlos se
usa la sintaxis siguiente:

int notas[100];

Se declara asi un arreglo capaz de contener hasta 100 valores enteros.

Si el arreglo notas es una variable global, todos los elementos se
inicializan en 0. Si el arreglo es local, sus elementos no se
inicializan.

La sentencia: Notas[5] = 89;

Asigna el valor 89 al sexto elemento ya que los indices empiezan en 0.

Los indices pueden ser: cualquier expresion entera, constantes,
variables, resultados de funcion, etc....


Ejemplo:


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define TAMARRAY 100

void LlenaArray(void);
void MuestraArray(void);
void Quicksort(int left, int right);
void SortArray(int n);

int array[TAMARRAY];

main()
{
LlenaArray();
MuestraArray();
SortArray(TAMARRAY);
MuestraArray();
return 0;
}

void LlenaArray(void)
{
int i;

srand((unsigned)time(NULL));
for (i = 0; i < TAMARRAY; i++)
array[i] = rand();
}

void MuestraArray(void)
{
int i;

puts("");
for (i = 0; i < TAMARRAY; i++)
printf("%8d", array[i]);
}

/* Algoritmo Quicksort segun C. A. R. Hoare */
void Quicksort(int left, int right)
{
int i = left;
int j = right;
register int test = array[(left + right) / 2];
int swap;

do {
while (array[i] < test) i++;
while (test < array[j]) j--;
if (i <= j) {
swap = array[i];
array[i] = array[j];
array[j] = swap;
i++;
j--;
}
} while (i <= j);
if (left < j) Quicksort(left, j);
if (i < right) Quicksort(i, right);
}

void SortArray(int n)
{
if (n > 1) Quicksort(0, n - 1);
}


La funcion srand() de stdlib.h suministra como semilla al generador de
numeros aleatorios, la hora actual para asegurar de esta manera una
secuencia de valores diferentes en cada ejecucion.

En la libreria stdlib.h existe una funcion asort() que se ejecuta mas
rapido probablemente y consume menos memoria que la de este ejemplo.

Para inicializar un arreglo se usa:

int numeros[10] = {0,1,2,3,4,5,6,7,8,9};

o:

int numeros[];

for (i=0; i < 10; i++)
numeros[i] = i;


La declaracion:
---------------

int numeros[] = {0,1,2,3,4,5,6,7,8,9};

Deja al compilador la tarea de dimensionar el arreglo.

Ejemplo:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void Inicializa(void);
long PidaNumLanz(void);
void LanzaDados(long numLanz);
void MuestraResultados(long numLanz);

#define MAX 13

double cuenta[MAX];
double prob[MAX] = {
0.0, 0.0, 1.0 / 36, 1.0 / 18, 1.0 / 12, 1.0 / 9, 5.0 / 36,
1.0 / 6, 5.0 / 36, 1.0 / 9, 1.0 / 12, 1.0 / 18, 1.0 / 36
};

main()
{
long numLanz;

printf("\nLanzamientos de Dados\n\n");
numLanz = PidaNumLanz();
if (numLanz > 0) {
LanzaDados(numLanz);
MuestraResultados(numLanz);
}
return 0;
}

long PidaNumLanz(void)
{
char respuesta[128];

printf("Cuantos lanzamientos ? ");
gets(respuesta);
return atol(respuesta);
}

void LanzaDados(long numLanz)
{
long i;
int k;

randomize();
for (i = 1; i <= numLanz; i++) {
k = (1 + random(6)) + (1 + random(6));
cuenta[k]++;
}
}

void MuestraResultados(long numLanz)
{
int i;

printf("\nValor Proba- Calculado Real \n");
printf("Dados bilidad \n");
printf("=======================================\n");
for (i = 2; i < MAX; i++) {
printf("%5d%10.3f%12.0f%10.0f\n",
i, prob[i], prob[i] * numLanz, cuenta[i]);
}
}


Al ejecutar el programa, es preferible especificar un numero de
lanzamientos entre 10000 y 50000, para asi obtener mejores resultados.

Las lineas 14, 15-18 declaran dos arreglos cuenta y prob capaces, cada
uno, de almacenar 13 valores double.

La constante simbolica MAX definida en la linea 12 permite variar el
limite superior. En este caso, los dados suman entre 2 y 12, asi que los
dos primeros elementos no se usan.

Las lineas 15-18 declaran el arreglo prob y lo inicializan con el valor
correspondiente a la probabilidad de obtener todas las combinaciones de
dos dados. Por ejemplo, para obtener el toal de 4 existen 3 combinaciones
posibles de los dos dados, a saber, 3 + 1, 2 +2 y 1 + 3. Ya que existen
36 (6 x 6) combinaciones posibles, la probabilidad de obtener un 4 es de
3/36. Las lineas 16-17 calculan estas probabilidades cuyos valores se
asignan al arreglo prob. El subindice indica el valor de los datos, es
asi que prob[4] contiene la probabilidad de obtener un 4.

La funcion LanzaDados(), de las lineas 42-52, ejecuta la simulacion. Para
obtener un resultado diferente por cada lanzamiento, se utiliza la
funcion randomize(), de time.h, que suministra una semilla al generador
de numeros aleatorios. Es equivalente a la funcion srand() del ejemplo
anterior.

En la linea 49 se usa la funcion random(N) que regresa al azar un valor
entero positivo modulo N. Es decir que random(6) regresa al azar un valor
entre 0 y 5. Al sumarle uno, se obtiene asi el valor que corresponde al
lanzamiento de un dado.

Las lineas 76-79 producen la tabla que el programa muestra en pantalla.

Para saber que espacio de la memoria ocupa un arreglo se utiliza sizeof();
sizeof(cualquierArreglo) devuelve el numero de bytes ocupados por el
arreglo en la memoria.

Sizeof(cualquierArreglo[0]) devuelve el numero de bytes ocupados por un
elemento del arreglo.

Un error muy frecuente con los arreglos es asignar un valor a un elemento
que no existe. Para evitarlo, es preferible usar el codigo siguiente:

int cualquierArreglo[] = {0,1,2,3,4};
#define MAX (sizeof(cualquierArreglo) / sizeof(cualquierArreglo[0])

La primera linea declara un arreglo de tamaño no especificado y lo
inicializa. El compilador, en este caso, asigna la cantidad de memoria
exactamente necesaria para almacenar los valores. La segunda linea asigna
a la constante simbolica MAX el numero de elementos del arreglo.

Cuando se quiere preservar los valores almacenados en el arreglo, se
utiliza el modificador const en la declaracion:

const int cualquierArreglo[] = {0,1,2,3,4};

Esta declaracion crea un arreglo de cinco elementos. Al usar const se
impide cualquier tentativa de modificacion de los valores de los elementos
del arreglo a traves del codigo. Es asi que, en este caso:

cualquierArreglo[4]++;


2.- Arreglos de Caracteres
ññññññññññññññññññññññ

Las cadenas ce caracteres son arreglos. La declaracion:

char nombre[128];

Declara un arreglo nombre con espacio para 128 elementos del tipo char.

Si c es una variable del tipo char, la sentencia:

c = nombre[3];

Asigna a c el cuarto caracter de nombre. Para inicializar una cadena
se usa:

Char compositor[] = "El Max 5";

Puesto que aqui tampoco se precisa la dimension del arreglo, en este caso,
el compilador tambien asignara el espacio de memoria justo necesario para
almacenar el valor, es decir 14 bytes ya que toda cadena siempre se
termina por un byte invisible nulo (ASCII 0).

Las declaraciones siguientes son equivalentes:

char ABCs[] = "ABC";
char ABCs[] = {'A','B','C',0};

Tambien puede usarse:

char autor[] = "Pablo Neruda";
#define TAMAUTOR (sizeof(autor));

En este caso resulta inutil dividir por sizeof(autor[0]) ya que un
elemento tipo char ocupa 1 byte.

Como siempre puede usarse:

char autor[128] = "Pablo Neruda";

En este caso, los bytes no ocupados se llenaran con 0 si el arreglo es
global y con valores imprevisibles si el arreglo es local.

Para mostrar el contenido de un arreglo de caracteres es preferible usar
puts() de stdio.h, ya que printf() se reserva a menudo para resolver los
problemas complejos de formateo:

char instituto[] = "IUT VALENCIA";
printf(instituto);

char procesador[] = "80486";
puts(procesador);

puts() empieza en una linea nueva. Para no hacerlo, se usa cputs() de
conio.h:

cputs("Me gustaria que mi PC tenga un ");
cputs(procesador);
puts(" como CPU");

Aun cuando lo anterior podria codificarse:

printf("Me gustaria que mi PC tenga un %s como CPU\n",procesador);

Los arreglos de caracteres pueden pasarse a los parametros de las
funciones e inversamente las funciones pueden devolver arreglos de
caracteres a las sentencias. Es asi, que puede escribirse la siguiente
funcion MuestraCadena():

void MuestraCadena(char string[])
{
printf(string);
}

Para luego declarar una variable de cadena en cualquier otra parte del
programa, y pasarla a la funcion:

char titulo[] = "Alicia en el pais de las maravillas";
MuestraCadena(titulo);

Sin embargo, la cadena de caracteres titulo no pasa a MuestraCadena( )
directamente en la pila. En efecto, en un programa largo, con muchas
funciones y parametros de cadenas, pasar una gran cantidad de datos a la
pila, tipicamente limitada a 64 K, provocaria una sobrecarga de esta. Por
esta razon, el Turbo C pasa la direccion de las cadenas y de otros
arreglos a las funciones, en vez de las cadenas u otros elementos del
arreglo.


3.- Arreglos multidimensionales
ñññññññññññññññññññññññññññ

Los arreglos pueden tener mas de una dimension. Por ejemplo, para
representar un punto de la pantalla debe usarse un arreglo bidimensional,
tal como:

char pantalla[25][80];

La sentencia:

puts(pantalla[4]);

Muestra los 80 caracteres de la quinta linea. La expresion pantalla[0] se
refiere a la primera linea y la sentencia:

putc(pantalla[4][2]);

muestra el tercer caracter de la quinta linea. Es importante resaltar que
la sentencia:

c = pantalla[4,2];


La declaracion:
---------------

int multi[7][8];

declara un arreglo de siete arreglos de ocho enteros cada uno, aun cuando
es mas conveniente considerar multi como una matriz de siete lineas y
ocho columnas.

De la misma manera:

int cubico[10][20][4];

declara un arreglo de enteros de altura 10, ancho 20 y profundidad 4, es
decir, un arreglo de arreglos de arreglos. Sin embargo, conceptualmente
es preferible considerar cubico como una matriz tridimensional.

Para mostrar los valores almacenados en cubico por orden de almacenamiento
en memoria, se usara:

for (i = 0; i < 10; i++)
for (j = 0; j < 20; j++)
for (k = 0; k < 4; k++)
printf("%d\n", cubic[i][j][k]);

Es importante resaltar que el tamaño de los arreglos multidimensionales
crece muy rapidamente. Es asi que si es verdad que un arreglo 10 x 10 x 8
de enteros de 2 bytes ocupa 1600 bytes, agregando una cuarta dimension de
10 valores se aumenta el tamaño del arreglo a 16000 bytes.

El siguiente ejemplo muestra como inicializar un arreglo multidimensional.


#include <stdio.h>

#define NUMMES 12

char meses[NUMMES][4] = {
"Ene", "Feb", "Mar", "Abr",
"May", "Jun", "Jul", "Ago",
"Sep", "Oct", "Nov", "Dec"
};

main()
{
int mes;

for (mes = 0; mes < NUMMES; mes++)
puts(meses[mes]);
return 0;


Seria un error considerar mes como un arreglo de una sola dimension, ya
que es un arreglo bidimensional. Mes[1][2], por ejemplo, se refiere a la
b de la cadena Feb.

El siguiente ejemplo utiliza arreglos multidimensionales para mostrar un
juego de ajedrez. (Este programa, en realidad, conoce un solo movimiento
y no juega ajedrez.) AJEDREZ tambien demuestra como el uso de la palabra
clave typedef permite tener un listado mas legible.


#include <stdio.h>

#define NUMPIEZAS 13
typedef enum pieza {
VACIA, BPEON, BTORRE, BCABALLO, BALFIL, BREINA, BREY,
NPEON, NTORRE, NCABALLO, NALFIL, NREINA, NREY
} Pieza;

#define NUMCOLS 8
typedef int Cols;

#define NUMFILAS 8
typedef enum filas {
A, B, C, D, E, F, G, H
} Filas;

/* El tablero 8-por-8 con las piezas en su posiciin inicial */
Pieza tablero[NUMCOLS][NUMFILAS] =
{
{BTORRE, BCABALLO, BALFIL, BREINA, BREY, BALFIL, BCABALLO, BTORRE},
{BPEON, BPEON, BPEON, BPEON, BPEON, BPEON, BPEON, BPEON },
{VACIA, VACIA, VACIA, VACIA, VACIA, VACIA, VACIA, VACIA },
{VACIA, VACIA, VACIA, VACIA, VACIA, VACIA, VACIA, VACIA },
{VACIA, VACIA, VACIA, VACIA, VACIA, VACIA, VACIA, VACIA },
{VACIA, VACIA, VACIA, VACIA, VACIA, VACIA, VACIA, VACIA },
{NPEON, NPEON, NPEON, NPEON, NPEON, NPEON, NPEON, NPEON },
{NTORRE, NCABALLO, NALFIL, NREINA, NREY, NALFIL, NCABALLO, NTORRE},
};

char piezaNombres[NUMPIEZAS][3] =
{
"..", "bP", "bT", "bC", "bA", "bR", "bK",
"nP", "nT", "nC", "nA", "nR", "nK"
};

void MoverPieza(Cols r1, Filas f1, Cols r2, Filas f2);
void MuestraTablero(void);

main( )
{
MuestraTablero();
MoverPieza(2, D, 4, D);
printf("\n(d2-d4)\n");
MuestraTablero();
return 0;
}

void MoverPieza(Cols r1, Filas f1, Cols r2, Filas f2)
{
tablero[r2 - 1][f2] = tablero[r1 - 1][f1];
tablero[r1 - 1][f1] = VACIA;
}

void MuestraTablero(void)
{
Cols r;
Filas f;

for (r = NUMCOLS; r > 0; r--) {
printf("\n%d: ", r);
for (f = A; f <= H; f++)
printf(" %s", piezaNombres[tablero[r - 1][f]]);
}
printf("\n a b c d e f g h\n");
}


Es importante tomar en cuenta que typedef no define un nuevo tipo de
datos. Esta palabra clave asocia una declaracion de tipo de datos a un
nombre mas sencillo. Se usa de la forma siguiente:

typedef declaracion Alias;

Esto crea un simbolo Alias que puede usarse en vez de declaracion.

La linea 12 utiliza typedef para crear un nuevo nombre para int. Su unica
razon es la claridad resultante. Puesto que es mas facil saber lo que
representa Columna que int, la declaracion del prototipo de la funcion
MoverPieza resulta mucho mas entendible usando columna que int.

Las lineas 5-8 declaran un alias Pieza para enum pieza {......}. Depues
de eso declarar:

Pieza cualquierPieza;

es equivalente a declarar:

enum pieza cualquierPieza;


Las lineas 21-31 muestran como preinicializar un arreglo bidimensional
utilizando llaves ({) anidadas y declaran el tablero bidimensional.

Las lineas 34-38 declaran el arreglo de las piezas. La cadena ".."
representa una casilla vacia.

Puede llamarse a las funciones con arreglos. Por ejemplo, si se tiene que
sumar los valores almacenados en un arreglo, puede declararse una funcion
que acepte un arreglo de valores tipo double como parametro:

#define MAX 100
double datos[MAX];
double SumaDeLosDatos(double datos[MAX]);

Otra alternativa consiste en no indicar el numero de elementos y usar
otro parametro para indicar el tamaño del arreglo:

double SumaDeLosDatos(double datos[], int n);

Con la sentencia siguiente se muestra la suma de los valores almacenados
en el arreglo:

printf("Suma == %lf\n", SumaDeLosDatos(datos, Max));


La funcion se escribe:

double SumaDeLosDatos(double datos[], int n)
{
double sum = 0;

while (n > 0)
sum += datos[--n];
return sum;
}

El mismo metodo se utiliza para llamar una funcion con cadenas de
caracteres:

#define MAXLONG 128
void UnaFuncion(char s[], int long);

char cantante[MAXLONG] = "Elton John";
UnaFuncion(cantante, MAXLONG);


Como ya se ha mencionado, el C pasa a las funciones la direccion del
arreglo y no su contenido, lo que permite ahorrar espacio en la pila. En
consecuencia, cuando se cambia el valor de un elemento del arreglo dentro
de la funcion, tambien se cambia el valor del elemento original en el
arreglo al contrario de lo que ocurre con otros tipos de datos donde se
pasa una copia de estos valores a los parametros de la funcion.

El siguiente ejemplo ilustra una tecnica que permite llamar una funcion
con arreglos de caracteres y demuestra que al cambiar el valor de un
elemento de un arreglo dentro de una funcion tambien cambia el valor
original en el arreglo. El programa incluye una funcion que limita la
respuesta del usuario a nueve caracteres.

#include <stdio.h>

void LeaCadena(char s[], unsigned maxlinea);

main()
{
char nombre[10];

printf("Cual es su nombre (9 caracteres maximo): ");
LeaCadena(nombre, 10);
printf("Resultado == %s\n", nombre);
return 0;
}

void LeaCadena(char s[], unsigned maxlinea)
{
char buffer[128];
int i;

gets(buffer);
if (maxlinea != 0)
--maxlinea;
i = buffer[maxlinea] = 0;
while ((s[i] = buffer[i]) != 0)
i++;
}


Cuando se llama a una funcion con un arreglo multidimensional, debe
especificarse la informacion minima que permita al compilador traducir
los subindices en direcciones de memoria. Por ejemplo, en un arreglo
bidimensional el compilador necesita saber cuantas columnas hay para
poder calcular la direccion de los elementos al principio de cada fila.

En consecuencia, puede usarse;

void UnaFuncion( int datos[FILAS][COLUMNAS]);

o:

void UnaFuncion( int datos[COLUMNAS]);

al contrario:

void UnaFuncion( int datos[][]);


La declaracion:
--------------

void UnaFuncion( int datos[][COLUMNAS], int numLineas);

Pasa otro argumento para indicar el numero de lineas, tecnica esta que
permite usar la misma funcion con arreglos que tienen un numero de filas
diferentes.

En el siguiente ejemplo ilustra lo que precede.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define COLS 8

void LlenaArray(int datos[][COLS], int numFilas);
void MuestraTabla(int datos[][COLS], int numFilas);


main()
{
int datos1[7][COLS];
int datos2[4][COLS];

randomize();
LlenaArray(datos1, 7);
MuestraTabla(datos1, 7);
LlenaArray(datos2, 4);
MuestraTabla(datos2, 4);
return 0;
}

void LlenaArray(int datos[][COLS], int numFilas)
{
int r, c;

for (r = 0; r < numFilas; r++)
for (c = 0; c < COLS; c++)
datos[r][c] = rand();
}

void MuestraTabla(int datos[][COLS], int numFilas)
{
int r, c;

for (r = 0; r < numFilas; r++) {
printf("\n");
for (c = 0; c < COLS; c++)
printf("%8d", datos[r][c]);
}
printf("\n");
}


4.- Estructuras
ñññññññññññ

Una estructura es una coleccion de variables que se denomina bajo un
unico nombre:


struct coordenadas {
int x;
int y;
};

Para utilizar una estructura primero debe declararse una variable de su
tipo:

struct coordenadas punto;

Para asignar valores a los miembros de una estructura, se usa el operador
punto:

punto.x = 5;
punto.y = 6;

Los nombres de los miembros de una estructura deben ser unicos dentro de
la misma, sin embargo, no entran en conflicto con los nombres usados en
otro contexto. Es decir que en el ejemplo puede declararse en otro parte
del programa variables con el nombre de x o y.

Para declarar las estructuras y las variables de tipo estructura puede
tambien usarse:

struct coordenadas {
int x;
int y;
} punto;


En C (al contrario del C++):

coordenadas p;

Puede declararse varias variables segun:

struct coordenadas var1, var2, var3;

Para no tener que repetir struct todo el tiempo, se usa typedef:

typedef struct coordenadas {
int x;
int y;
} Coordenadas;

o:

typedef struct {
int x;
int y;
} Coordenadas;

A continuacion, las declaraciones y asignaciones se haran segun:

Coordenadas punto;
punto.x = 5;

Las estructuras pueden almacenar variables de diferentes tipos, arreglos
y hasta otras estructuras:

typedef struct otraStruct {
float unFloat;
int unInt;
char unaCadena[8];
char unChar;
long unLong;
} OtraStruct;

OtraStruct datos;
datos.unFloat = 3.14159;
datos.unChar = 'X';

Puede asignarse una variable tipo estructura a otra variable del mismo
tipo:

Coordenadas var1, var2;

var1 = var2;

No se puede comparar dos estructuras directamente. Es asi que:

if (var1 == var2)
sentencia;

Sin embargo, pueden compararse sus miembros:

if ((var1.x == var2.x) && (var1.y == var2.y))
sentencia;


El siguiente ejemplo ilustra el uso de una estructura para realizar
calculos con fechas.


#include <stdio.h>

typedef struct fechaStruct {
char mes;
char dia;
unsigned anio;
} FechaStruct;

main()
{
FechaStruct fecha;

printf("Prueba de Fecha\n");
fecha.mes = 5;
fecha.dia = 16;
fecha.anio = 1972;
printf("La fecha es: %02d/%02d/%04d\n",
fecha.dia, fecha.mes, fecha.anio);
return 0;
}


En vez de utilizar el operador punto para asignar valores a los miembros
de una estructura, puede usarse:

FechaStruct fecha = {15,7, 2012};

Cuando el miembro de una estructura es otra estructura, se tiene entonces
estructuras anidadas:

typedef struct tiempoStruct {
char hora;
char minuto;
char segundos;
} TiempoStruct;


typedef struct fechaTiempo {
FechaStruct laFecha;
TiempoStruct laHora;
} FechaTiempo;


Despues de declarar:

FechaTiempo dt;

dt.laFecha se refiere al miembro laFecha de estructura dt, dt.lafecha.mes
al miembro mes del miembro laFecha de la estructura dt.


En el siguiente ejemplo se ilustra el uso de estas estructuras.


#include <stdio.h>

typedef struct fechaStruct {
char mes;
char dia;
unsigned anio;
} FechaStruct;

typedef struct tiempoStruct {
char hora;
char minuto;
char segundo;
} TiempoStruct;

typedef struct fechaTiempo {
FechaStruct laFecha;
TiempoStruct laHora;
} FechaTiempo;

main()
{
FechaTiempo dt;

printf("Prueba de fecha y Hora\n");
dt.laFecha.mes = 5;
dt.laFecha.dia = 16;
dt.laFecha.anio = 1972;
dt.laHora.hora = 6;
dt.laHora.minuto = 15;
dt.laHora.segundo = 0;
printf("La fecha es: %02d/%02d/%04d\n",
dt.laFecha.dia, dt.laFecha.mes, dt.laFecha.anio);
printf("La hora es: %02d:%02d:%02d\n",
dt.laHora.hora, dt.laHora.minuto, dt.laHora.segundo);
return 0;
}


En C (al contrario del C++), los miembros de una estructura no pueden ser
funciones. Sin embargo, las funciones pueden llamarse con estructuras y
regresar estructuras como resultados. Por ejemplo, para definir un
rectangulo puede usarse una estructura:

typedef struct rectangulo {
int izq;
int tope;
int der;
int fondo;
} Rectangulo;

En vez de la declaracion y asignaciones siguientes:
Rectangulo r;

r.izq = 5;
r.tope = 8;
r.der = 60;
r.fondo = 18;

puede usarse:

Rectangulo r;
r = RectAsigna(5, 8, 60, 18);

con:

Rectangulo RectAsigna(int l, int t, int r, int b)
{
Rectangulo rtemp;
rtemp.izq = l;
rtemp.tope = t;
rtemp.der = r;
rtemp.fondo = b;
return rtemp;
}


Puede tambien pasarse estructuras a los parametros de una funcion. Por
ejemplo, si se necesita comparar dos rectangulos para saber si son
iguales, puede usarse una funcion del siguiente tipo:

int RectsIguales(Rectangulo r1, Rectangulo r2)
{
return ((r1.izq == r2.izq ) &&
((r1.tope == r2.tope ) &&
((r1.der == r2.der ) &&
((r1.fondo == r2.fondo );
}

Esta funcion puede entonces usarse de la siguiente manera:

if (RectsIguales(var1, var2))
sentencia;


5.- Arreglos y estructuras
ññññññññññññññññññññññ

Combinando arreglos y estructuras se puede organizar la informacion en un
numero casi sin limites de formas.


a.- Arreglos de estructuras
-----------------------

Dos o mas arreglos de informacion relacionada pueden traducirse en un
arreglo unico de estructuras para mejorar eficiencia. Teniendo, por
ejemplo, las coordenadas tridimen-sionales de 100 elementos, pueden
declararse los tres arreglos siguientes:

double X[100];
double Y[100];
double Z[100];

Sin embargo, para graficar un punto con una funcion hipotetica
PlotPunto(), se usaria la sentencia:

PlotPunto(X[9], Y[9], Z[9]);

Es decir que se debe trabajar con tres arreglos al mismo tiempo. Una mejor
manera de proceder es declarar la estructura:

struct punto3D {
double X;
double Y;
double Z;
};

con:

struct punto3D puntos[100];

Al declarar la funcion PlotPunto() para que acepte como parametro la
estructura punto3D, se trabajara con un solo arreglo:

void PlotPunto(struct punto3D p);

PlotPunto(puntos[9]);


b.- Estructuras con arreglos como miembros.
---------------------------------------

El caso tipico son las estructuras que poseen varios arreglos de
caracteres:

struct persona{
char nombre[25];
char direccion[50];
char ciudad[15];
......
}


6.- Uniones
ñññññññ

Una union es una posicion de memoria compartida por varias variables de
diferentes tipos. Su declaracion es muy parecida a la de la estructura,
sin embargo, confundir una union con una estructura resultaria
desastroso.

Union tipo_u {
int i;
char ch;
}

Tambien se declara una variable de tipo tipo_u segun:

union tipo_u cnvt;

Aun cuando i ocupa dos bytes y ch uno solo, estas dos variables comparten
la misma direccion de memoria.

El compilador crea automaticamente una variable suficientemente grande
para almacenar el tipo mas grande de variable de la union.

Para acceder a la variable puede utilizarse el operador punto:

cnvt.i = 10

El uso de una union puede ayudar a la creacion de codigo independiente de
la maquina (portable). No se producen dependencias con la maquina debido
a que el compilador sigue la pista de los tamaños actuales de las
variables unidas. No es necesario preocuparse por el tamaño de un entero,
un caracter, un float o lo que sea.


--EOF--

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT