Sei sulla pagina 1di 3

Casos especiales a tener en cuenta

Tablas
En lenguaje algortmico se permite hacer asignaciones de una tabla a otra (siempre que sean
del mismo tipo base y coincida el nmero de elementos), devolver una mesa como valor de
retorno de una funcin e, incluso, se podra comparar directamente dos tablas (aunque nuestro
lenguaje algortmico no lo permite). En C no podemos hacer ninguna de estas cosas. El hecho
de utilizar el lenguaje de programacin C para la codificacin de los ejercicios prcticos
conlleva una serie de problemas que hay que resolver. Por ejemplo:
const
NMAX: entero = 3;
fconst
tipo
tNxN = tabla [NMAX, NMAX] de real;
ftipo
funcion transponerMatriz(m: tNxN, n: entero): tNxN
var
i, j: entero;
mT: tNxN;
fvar
para i := 1 hasta n hacer
mT[i,i] := m[i,i];
para j := i+1 hasta n hacer {Observad que cuando i=n en este bucle no entramos}
mT[i,j] := m[j,i];
mT[j,i] := m[i,j];
fpara
fpara
devuelve mT;
ffuncion
funcion sonIguales(a: tNxN, b: tNxN, n: entero): booleano
var
i, j: entero;
resultado: booleano;
fiar
{No podemos hacer sencillamente "devuelve a=b"; la comparacin entre tablas no est
permitida}
{Suponemos inicialmente que son iguales, hacemos una doble bsqueda de algn
elemento diferente}
resultado := cierto;
i := 1;
mientras (i n) y resultado hacer
j := 1;
mientras (j n) y resultado hacer
si (a[i,j] <> b[i,j]) entonces
resultado := falso;
sino
j := j + 1;
fsi
fmientras
si resultado entonces
i := i + 1;
fsi
fmientras

devuelve resultado;
ffuncion
funcion esSimetrica(m: tNxN, n: entero): booleano
var
t : tNxN;
fvar
t := transponerMatriz(m, n); {Aqu asignamos una tabla devuelta por una funcin a otra}
devuelve sonIguales(t, m, n);
ffuncion
Aunque no es la manera ms adecuada de comprobar si una matriz es simtrica o no, estas
funciones ilustran todos los problemas mencionados anteriormente: se hacen asignaciones de
tablas a tablas, se devuelven tablas como valor de retorno de una funcin y se hacen
comparaciones de tablas.
El primero que haremos es no hacer nunca una funcin que devuelva una tabla: utilizaremos
siempre una accin con un parmetro adicional de salida que ser donde devolveremos la
tabla. El resto de parmetros sern de entrada. As pues:
accion transponerMatriz(ent m: tNxN, ent n: entero, sal mT: tNxN)
var
i, j: entero;
fvar
para i:=1 hasta n-1 hacer
mT[i,i] := m[i,i];
para j:=i+1 hasta n hacer
mT[i,j] := m[j,i];
mT[j,i] := m[i,j];
fpara
fpara
mT[n,n] := m[n,n];
faccio
funcio esSimetrica(m: tNxN, n: entero): booleano
var
t : tNxN;
fvar
transponerMatriz(m, n, t); {Ahora ya no hacemos asignacin de una tabla en otra}
devuelve sonIguales(t, m, n);
ffuncion
No obstante, suponemos que queremos hacer una asignacin de una tabla en otra. Para
traducirlo a C podemos hacer dos cosas: la primera consiste en copiar elemento a elemento
utilizando un bucle parafpara, y la segunda consiste en utilizar una funcin de la librera
estndar de C para realizar la copia. Por ejemplo:
const
NMAX: entero = 3;
fconst
tipo
vectorN = tabla [NMAX] de real;
ftipo
var
a, b: vectorN;
fvar
a := b; {Queremos copiar la tabla b a la tabla a}

Lo que definitivamente no podemos hacer en C es lo siguiente:


#define NMAX 3
typedef float vectorN[NMAX];
vectorN a, b;
...
a=b; /* ERROR */
...
La primera opcin es copiar elemento a elemento. Hay que declarar una variable auxiliar de
tipo entero para recorrer toda la mesa:
...
int y;
...
...
para (i=0; i<NMAX; i++) { a[i]=b[i]; }
...
La segunda opcin consiste al utilizar la funcin memcpy():
...
#include <string.h>
...

/* para memcpy() */

...
memcpy(a, b, NMAX*sizeof(float));
...
La sintaxis es memcpy(destino, origen, tamao en bytes), dnde este ltimo
parmetro se calcula utilizando sizeof(), que permite conocer la medida en bytes del tipo
base de la tabla. Entonces el nmero de elementos de la tabla por la medida en bytes de cada
uno nos da la medida de la tabla en bytes.
Estas dos opciones tienen un problema, y es que slo funcionan si el tipo base de los
elementos de la tabla no es o no contiene ninguna tabla. Si volvemos al ejemplo inicial, en C
sera lo siguiente:
typedef float matNxN[NMAX][NMAX];
matNxN a, b;
int i, j; /* variables auxiliares */
precio (i=0; i<NMAX; i++) { /* un bucle para cada "nivel" de tabla */
precio (j=0; j<NMAX; j++) {
a[i][j]=b[i][j];
}
}
mientras que si utilizamos memcpy() es:
memcpy(a, b, NMAX*NMAX*sizeof(float));
Es decir, hay que aplicar el concepto para cada nivel de la asignacin donde aparece una
tabla.

Potrebbero piacerti anche