E. VECTORES, MATRICES Y CADENAS


E.0. Introducción
E.1. Definición de array
E.2. Procesamiento de un array
E.3. Paso de arrays a funciones
E.4. Arrays multidimensionales
E.5. Arrays y cadenas de caracteres
E.6. Funciones de librería para arrays y cadenas
E.7. Bibliografia




E.0. ➙ARRAYS

Muchas aplicaciones requieren procesar múltiples datos con características comunes en esta situación es conveniente colocar los datos en un array donde todos comparten el mismo nombre. Los datos individuales pueden ser caracteres, enteros, números en coma flotante etc. sin embargo todos deben ser del mismo tipo y con el mismo tipo de almacenamiento.

Cada elemento del array (cada dato individual) es referido especificando el nombre del array seguido de uno o más índices, con cada índice encerrado entre corchetes. Cada índice debe ser expresado como un entero no negativo. Así en un array x de n elementos, los elementos del array son x[0], x[1], x[2],........ x[n-1], como se muestra en la figura. El valor de cada índice puede expresarse como una constante entera, una variable entera o una expresión entera más compleja.









x[0]
x[1]
x[2]


---

x[n-1]


El número de índices representa la dimensión del array por ejemplo x[1] refiere a un elemento del array unidimensional o vector x, similarmente y[i][j] refiere un elemento del array bidimensional o matriz y (se puede pensar que un array bidimensional es una tabla donde y[i][j] es el elemento j de la fila i.) se pueden formar arrays de mayor dimensión, añadiendo índices adicionales de la misma manera (por ejemplo z[i][j][k], un cubo).











E.1.➙DEFINICIÓN DE UN ARRAY


Los arrays se definen en gran parte como las variables ordinarias, excepto en que cada array debe acompañarse de una especificación de tamaño (número de elementos). Para un array unidimensional el tamaño se especifica como una expresión entera positiva encerrada entre corchetes. La expresión es generalmente una constante entera positiva.

En términos generales un array unidimensional se expresa como:


tipo-almacenamiento tipo-dato array [expresión]


donde tipo-almacenamiento se refiere al tipo de almacenamiento del array (extern, static, auto), tipo-dato es el tipo de dato, array es el nombre del array y expresión una expresión entera positiva que indica el número de elementos del array. El tipo-almacenamiento es opcional; los valores por defecto son auto para arrays definidos dentro de una función o bloque y extern para los arrays definidos fuera de una función.


  • Ejemplos:

int x[100];

char texto[80];

static char mensaje[25];

static float n[12];

A veces es conveniente definir el tamaño de un array en términos de una constante simbólica en vez de una cantidad entera fija. Esto hace más fácil modificar un programa que utiliza un array, ya que todas las referencias al tamaño máximo del array (por ejemplo dentro de bucles for como en definiciones de arrays) puede ser alterado cambiando simplemente el valor de la constante simbólica.

  • Ejemplo:

Convertir texto en minúsculas a mayúsculas


  1. include <stdio.h>

#define TAMANO 80

int main()

/* leer una línea de texto en minúsculas y escribirlo en mayúsculas */
{
char letra[TAMANO];
int cont;


/* leer la línea*/

for (cont=0; cont<TAMANO; ++cont)
letra[cont]=getchar();

/*Escribir la línea con mayúsculas*/
for (cont=0; cont<TAMANO; ++cont)
putchar(toupper(letra[cont]));
}

Los arrays auto, a diferencia de la variables static y extern, no se inicializan al definirlas. Sin embargo, las definiciones de arrays static y extern, pueden incluir también, si se desea, la asignación de valores iniciales. Los valores iniciales deben aparecer en el orden en que serán asignados a los elementos individuales del array, encerrados entre llaves y separados por comas. La forma general es:

tipo-almacenamiento tipo-dato array [expresión]={valor1,valor2, ....,valor n};

donde valor1 se refiere al valor de primer elemento del array, valor2 del segundo elemento y así sucesivamente, la presencia de la expresión que indica el número de elementos del array, es opcional cuando los valores iniciales están presentes.

  • Ejemplos:

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

char color[3]={’R’,’E’,’D’};

static float x[6]= {0,0.25,0,-0.50,0,0};


Todos los elementos del array que no tengan asignados valores iniciales explícitos serán puestos automáticamente a cero. Esto incluye al resto de los elementos de un array en que un cierto número de elementos tienen asignado un valor distinto de cero.

  • Ejemplos:

int digitos[10]={3,3,3};

static float x[6] ={-0.3,0,0.25};


Los tres primeros elementos serán iniciados a 3, el resto iniciados a 0.


El tamaño del array no necesita ser especificado explícitamente cuando se incluyen los valores iniciales como una parte de la definición del array. Con un array numérico, el tamaño del array será fijado automáticamente igual que el número de valores incluidos dentro de la definición.


  • int digitos[ ]={1,2,3,4,5,6};

  • static float x[ ] ={0,0.25,0,-0.50};


La asignación será:

  • digitos[0]= 1 x[0]= 0
  • digitos[1]= 2 x[1]= 0.25
  • digitos[2]= 3 x[2]= 0
  • digitos[3]= 4 x[3]= -0.5
  • digitos[4]= 5
  • digitos[5]= 6


Las cadenas se manejan de forma un poco diferente. En particular, cuando se le asigna una cadena constante a un array static o extern como parte de la definición, el tamaño del array normalmente se omite. El tamaño adecuado será asignado automáticamente. Esto incluirá la previsión del carácter nulo '\0', que se añade automáticamente al final de cada cadena.

  • char color[3] = “RED”;
  • char color[ ] = “RED”;


Diferencias:

  • La primera asignación define un array de caracteres de tres elementos cuyos elementos individuales son:

color[0] = ‘R’;
color[1] = ‘E’;
color[2] = ‘D’;

  • La segunda línea define el siguiente array de caracteres de cuatro elementos



color[0] = ‘R’;
color[1] = ‘E’;
color[2] = ‘D’;
color[3] = ‘\0’;


Por tanto la primera forma es incorrecta ya que la definición del carácter nulo no se incluye en el array.

La definición del array podría haberse escrito como:

char color[4] = “RED”;


Si el programa requiere una declaración de un array unidimensional (porque el array está definido en otra parte del programa), la declaración se escribe de la misma manera que la definición con las siguientes excepciones:



1.- Los corchetes pueden estar vacíos, ya que el tamaño puede haber sido especificado como parte de la definición. Las declaraciones de arrays se escriben habitualmente de esta manera.

2.- No se pueden incluir valores iniciales en la declaración.


Ejemplo de un programa en C con dos archivos que hace uso de arrays extern.

Primer archivo:

int c[ ]={1,2,3}; /* DEFINICION de array extern */
char mensaje[ ]=”¡Hola!”; /* DEFINICION de array extern */
extern void func1(void); /* DEFINICION de función extern */
main()
{
...
}


Segundo archivo:

extern int c[ ]; /* DECLARACIÓN de array extern */
extern char mensaje[ ]; /* DECLARACIÓN de array extern */
extern void func1(void); /* DEFINICION de función extern */

int main ()
{
...
}









E.2.➙PROCESAMIENTO DE UN ARRAY


En C no se permiten operaciones que impliquen arrays completos. Así si a y b son dos arrays similares (mismo tipo de datos, misma dimensionalidad y mismo tamaño), las operaciones de asignación, de comparación,..., deben realizarse elemento por elemento. Esto se hace normalmente dentro de un bucle donde cada paso del bucle se usa para procesar un elemento del array. El número de pasos del bucle será igual al número de elementos del array.

Ejemplo: Desviación respecto a la media.

Calcular la media de n números, después computar la desviación
de cada número respecto a la media.


#include <stdio.h>
int main()
{
int n, cont;
float media,d,suma=0;
float lista [100];

/*leer el valor de n*/

printf(“¿Cuantos numeros para calcular la media?”);

scanf(“%d”, &n);
printf(“\n”);

/*leer los números y calcular su suma*/
for (cont=0; cont<n; ++cont)
{
printf(“i=%d x= “, contador+1);
scanf(“%f”, &lista[cont]);
suma+=lista[cont];
}

/*Calcular la media y escribir la respuesta*/
media=suma/n;

printf(“La media es %5.2f\n\n”, media);

/*Calcular y escribir las desviaciones respecto a la media */
for(cont=0; cont<n; ++cont)
{
d=lista[cont]-media;
printf(“i= %d x= %5.2f d= %5.2f\n”, cont+1,lista[cont],d);
}

}


Para algunas aplicaciones puede desearse asignarle valores iniciales a los elementos de un array. Esto requiere que el array sea definido como global o localmente (dentro de una función) como un array static. El siguiente ejemplo ilustra el uso de una definición global de array.


Ejemplo: Desviación respecto a la media (Revisión).

Calcular la media de n números, después computar la desviación
de cada número respecto a la media.


#include <stdio.h>

int n=5;
float lista [ ]= {3, -2, 12, 4.4, 3.5} ;

int main()
{
int cont;
float media, d, suma=0;

/*Calcular la media y escribir la respuesta*/

for (cont=0; cont<n; ++cont)

suma+=lista[cont];

media=suma/n;

printf(“La media es %5.2f\n\n, media);


/*Calcular y escribir las desviaciones respecto a la media */
for(cont=0; cont<n; ++cont)
{
d=lista[cont]-media;
printf(“i= %d x= %5.2f d= %5.2f\n”, cont+1,lista[cont],d);
}

}











E.3.➙PASO DE ARRAYS A FUNCIONES


El nombre de un array se puede usar como argumento de una función, permitiendo así que el array completo sea pasado a la función. Sin embargo, la manera de la que se pasa difiere mucho de la de una variable ordinaria.

Para pasar un array a una función , el nombre del array debe aparecer sólo, sin corchetes o índices, como un argumento actual dentro de la llamada a la función. El correspondiente argumento formal se escribe de la misma manera, pero debe ser declarado como un array dentro de la declaración de argumentos formales. Cuando se declara un array unidimensional como un argumento formal, el array se escribe con un par de corchetes vacíos. El tamaño del array no se especifica dentro de la declaración formal de argumentos.


Ejemplo:

Paso de un array desde una porción del programa principal hasta una función.

#include <stdio.h>

float media(int, float []); /* DECLARACIÓN de la función */

int main()
{
int n; /* DECLARACIÓN de variable */
float med; /* DECLARACIÓN de variable */
float lista [100]; /* DEFINICIÓN del array */
....
med=media(n,lista);
...
}

float media(int a,float x[]) /*DEFINICIÓN de función */
{
...
}


Se precisa tener algún cuidado cuando se escriben declaraciones de funciones que incluyen especificaciones de tipo de argumento. Si alguno de los argumentos es un array, el tipo de datos de cada array debe estar seguido por un par de corchetes, indicando así que el argumento es un array. En el caso de prototipos de funciones, un par de corchetes vacíos deben seguir al nombre del array.


Cuando se pasa un array a una función, los valores de los elementos del array no son pasados a la función. En vez de esto, el nombre del array se interpreta como la dirección de memoria del primer elemento del array. Esta dirección se asigna al correspondiente argumento formal cuando se llama a la función. El argumento formal se convierte por tanto en un puntero al primer elemento del array. Los argumentos pasados de esta manera se dice que son pasados por referencia en vez de por valor.


Cuando se hace una referencia a un elemento del array dentro de la función, el índice del elemento se añade al valor del puntero para indicar la dirección del elemento especificado. Por tanto, cualquier elemento del array puede ser accedido dentro de la función. Además si un elemento del array es alterado dentro de la función , esta alteración será reconocida en la porción del programa desde la que ha sido llamada (en realidad en todo el ámbito de la definición del array).


Ejemplo:
Programa que pasa un array de tres elementos enteros a una función donde
estos elementos son alterados y se visualiza el resultado de esta alteración.


#include <stdio.h>
int main()
{

int cont, a[3]; /* definición de array */

void modificar(int a[ ]); /* declaración de función */

printf(“\nDesde main, antes de llamar a la funcion: \n”);

for (cont=0;cont<=2;++cont)
{
a[cont]=cont+1;
printf(“a[%d] = %d \n”, cont, a[cont]);
}

modificar (a);

printf(“\nDesde main, despues de llamar a la funcion: \n”);

for (cont=0;cont<=2;++cont)

printf(“a[%d] = %d \n”, cont, a[cont]);

}

void modificar (int a[]); /* Definición de función */
{
int cont;

printf(“\nDesde la funcion despues de modificar los valores: \n”);

for (cont=0;cont<=2;++cont)
{
a[cont]=-9;
printf(“a[%d] = %d \n”, cont, a[cont]);
}

return;
}


El hecho de que un array pueda ser modificado globalmente dentro de una función proporciona un mecanismo adecuado para mover múltiples datos de o desde una función a la porción llamante del programa. Simplemente se pasa el array a la función y se alteran los elementos dentro de ella. O, si el array debe ser preservado, se copia el array (elemento por elemento) dentro de la porción llamante del programa se pasa la copia a la función y se realizan alteraciones. El programador debe tener cierto cuidado al alterar un array dentro de una función ya que es muy fácil alterarlo de modo no intencionado.






E.4.➙ARRAYS MULTIDIMENSIONALES

Los arrays multidimensionales son definidos prácticamente de la misma manera que los arrays unidimensionales, excepto que se requiere un par de corchetes para cada índice. Así un array bidimensional requerirá dos pares de corchetes, un array tridimensional requerirá tres pares de corchetes , y así sucesivamente.

En términos generales, la definición de un array multidimensional puede escribirse como:

tipo-almacenamiento tipo-dato array[expresion 1][expresion 2 ]...[expresion n]

donde tipo-almacenamiento se refiere al tipo de almacenamiento del array (extern, static, auto), tipo-dato es el tipo de dato, array es el nombre del array y expresion 1, expresion 2,...,expresion n expresiones enteras positivas que indican el número de elementos del array asociados con cada índice. El tipo-almacenamiento es opcional; los valores por defecto son auto para arrays definidos dentro de una función o bloque y extern para los arrays definidos fuera de una función.

Hemos visto como un array unidimensional de n elementos puede ser visto como una lista de n valores. Similarmente un array bidimensional de m x n puede ser visto como una tabla de valores que tiene m filas y n columnas. Extendiendo esta idea, un array tridimensional puede verse como un conjunto de tablas (por ejemplo un libro en el cual cada página es una tabla), y así sucesivamente.





col 1
col 2
col 3
.....
col n-1
col n
fila 1







x[0][0]
x[0][1]
x[0][2]

x[0][n-2]
x[0][n-1]
fila 2







x[1][0]
x[1][1]
x[1][2]

x[1][n-2]
x[1][n-1]
.......
........
........
........
.......
.......
.......
fila m







x[m-1][0]
x[m-1][1]
x[m-1][2]

x[m-1][n-2]
x[m-1][n-1]


Varias definiciones típicas de arrays multidimensionales:

  • float tabla[50][50];
  • char pagina[24][80];
  • static double registros[100][66][255];
  • static double registros[L][M][N];


La última definición es similar a la definición precedente excepto que las constantes simbólicas L,M,N definen el tamaño del array. Así los valores asignados a estas constantes simbólicas determinaran el tamaño actual del array.


Si la definición de un array multidimensional incluye la asignación de valores iniciales, se debe tener cuidado en el orden en que los valores iniciales son asignados a los elementos del array. La regla es que el último índice (el de más a la derecha) es el que se incrementa más rápidamente, y el primer índice (el de más a la izquierda) es el que se incrementa más lentamente. Así, los elementos de un array bidimensional deben ser asignados por filas, esto es, primero serán asignados los elementos de la primera fila, luego los elementos de la segunda, y así sucesivamente.


Ejemplo


int valores[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};


Estas serán las asignaciones:


valores[0][0] = 1 valores[0][1] = 2 valores[0][2] = 3 valores[0][3] = 4

valores[1][0] = 5 valores[1][1] = 6 valores[1][2] = 7 valores[1][3] = 8

valores[2][0] = 9 valores[2][1] = 10 valores[2][2] = 11 valores[2][3] = 12


El orden natural en el que los valores iniciales son asignados se puede alterar formando grupos de valores iniciales encerrados entre llaves ({...}). Los valores dentro de cada par interno de llaves serán asignados a los elementos del array cuyo índice varíe más rápidamente. Por ejemplo en un array bidimensional, los valores almacenados dentro del par interno de llaves serán asignados a los elementos de una fila, ya que el segundo índice (columna) se incrementa más rápidamente. Si hay pocos elementos dentro de cada par de llaves, al resto de los elementos de cada fila se le asignarán ceros. Por otra parte, el número de valores dentro de cada par de llaves no puede exceder del tamaño de fila definido.


Ejemplo:

Esta definición produce las mismas asignaciones que en el ejemplo anterior.

int valores[3][4] = {

{1,2,3,4},

{5,6,7,8},

{9,10,11,12}

};


O esta asignación:


int valores[3][4] = {

{1,2,3},

{5,6,7},

{9,10,11}

};


valores[0][0] = 1 valores[0][1] = 2 valores[0][2] = 3 valores[0][3] = 0

valores[1][0] = 5 valores[1][1] = 6 valores[1][2] = 7 valores[1][3] = 0

valores[2][0] = 9 valores[2][1] = 10 valores[2][2] = 11 valores[2][3] = 0


Y esta:


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


valores[0][0] = 1 valores[0][1] = 2 valores[0][2] = 3 valores[0][3] = 4

valores[1][0] = 5 valores[1][1] = 6 valores[1][2] = 7 valores[1][3] = 8

valores[2][0] = 9 valores[2][1] = 0 valores[2][2] = 0 valores[2][3] = 0


Esta última producirá error de compilación:


int valores[3][4] = {

{1,2,3,4,5},

{6,7,8,9,10},

{11,12,13,14,15}

};


El uso de grupos internos de valores puede generalizarse para arrays de mayor dimensión.


int t[10][20][30] = { tabla 1

{1,2,3,4}, fila 1
{5,6,7,8}, fila 2

{9,10,11,12} fila 3
}

{ tabla 2

{21,22,23,24}, fila 1
{25,26,27,28}, fila 2

{29,30,31,32} fila 3
};


El grupo de valores iniciales producirá la asignación de los siguientes valores no nulos en las dos primeras tablas:


t[0][0][0] = 1 t[0][0][1] = 2 t[0][0][2] = 3 t[0][0][3] = 4

t[0][1][0] = 5 t[0][1][1] = 6 t[0][1][2] = 7 t[0][1][3] = 8

t[0][2][0] = 9 t[0][2][1] = 10 t[0][2][2] = 11 t[0][2][3] = 12


t[1][0][0] = 21 t[1][0][1] = 22 t[1][0][2] = 23 t[1][0][3] = 24

t[1][1][0] = 25 t[1][1][1] = 26 t[1][1][2] = 27 t[1][1][3] = 28

t[1][2][0] = 29 t[1][2][1] = 30 t[1][2][2] = 31 t[1][2][3] = 32


El resto de los elementos del array tendrán asignados ceros.



Los arrays multidimensionales se procesan de la misma manera que los arrays unidimensionales, sobre la base de elemento a elemento. Sin embargo, se requiere algún cuidado cuando se pasan arrays multidimensionales a una función. En particular, las declaraciones de argumentos formales dentro de la definición de una función debe incluir especificaciones explícitas de tamaño en todos los índices excepto en el primero. Estas especificaciones deben ser consistentes con las correspondientes especificaciones de tamaño en el programa llamante. El primer índice puede ser escrito como un par de corchetes vacíos, como en un array unidimensional. Los prototipos correspondientes de función deben escribirse de la misma manera.


Ejemplo:


/* Sumar dos tablas de números ; c[i][j]= a[i][j]+ b[i][j]
Haremos uso de las siguientes definiciones de arrays y variables.
a,b,c = arrays bidimensionales con el mismo número de filas y el mismo número de columnas
sin exceder de 20 filas y 30 columnas.
nfilas = variable entera que indica el número real de filas en cada tabla
ncols = variable entera que indica el número real de columnas en cada tabla
fila = contador entero que indica el número de fila
col = contador entero que indica el número de columna
El programa se modularizará escribiendo funciones separadas para leer el array, calcular la suma
de los elementos del array y escribir el array. Llamaremos a estas funciones leer entrada, calcular suma
y sacar salida respectivamente.*/



#include <stdio.h>


#define MAXFIL 20

#define MAXCOL 30


/* Calcular la suma de los elementos en dos tablas de enteros */

int main ()

{
int nfilas, ncols;


/*definiciones de arrays*/

int a[MAXFIL][MAXCOL], b[MAXFIL][MAXCOL], c[MAXFIL][MAXCOL];

/* Prototipos de función*/

void leerentrada (int a[ ][MAXCOL], int nfilas, int ncols);

void calculasuma (int a[ ][MAXCOL], int b[ ][MAXCOL],

int c[ ][MAXCOL], int nfilas, int ncols);

void sacarsalida (int c[ ][MAXCOL], int nfilas, int ncols);


printf (“¿Cuantas filas?”);
scanf (“ %d “ , &nfilas);

printf (“¿Cuantas columnas?”);
scanf (“ %d “ , &ncols);


printf (“\n\n Primera tabla\n”);
leerentrada (a, nfilas, ncols);


printf (“\n\n Segunda tabla\n”);
leerentrada (b, nfilas, ncols);


calcularsuma(a, b, c, nfilas, ncols);


printf (“\n\n Sumas de los elementos\n”);
sacarsalida (c, nfilas, ncols);

}


void leerentrada (int a[ ][MAXCOL], int m, int n)

/*Leer una tabla de enteros */

{
int fila, col;
for (fila=0; fila<m; ++m)
{
prinf(“ Introducir datos de la fila nº. %2d\n, fila+1);
for (col=0; col<n; ++col)

scanf (“%d”, &a[fila][col];

}
return;

}

void calcularsuma (int a[ ][MAXCOL], int b[ ][MAXCOL],

int c[ ][MAXCOL], int m, int n)

/*Sumar los elementos de las dos tablas de enteros*/

{
int fila, col;

for (fila=0; fila<m; ++m)

for (col=0; col<n; ++col)

c[fila][col] = a[fila][col] + a[fila][col];

return;
}


void sacarsalida (int a[][MAXCOL], int m, int n)

/*Escribir una tabla de enteros */

{
int fila, col;

for (fila=0; fila<m; ++m)
{
for (col=0; col<n; ++col)

printf(“%4d”, a[fila][col]);

printf(“\n”);
}
return;
}







E.5.➙ARRAYS Y CADENAS DE CARACTERES.


Ya se ha visto que una cadena de caracteres puede ser representada como un array unidimensional de caracteres, con un carácter final de cadena indicado por '\0'. Cada carácter de la cadena será almacenado en un elemento del array. Algunos problemas requieren que los caracteres de la cadena sean procesados individualmente . No obstante hay muchos otros problemas en los que se requiere que las cadenas se procesen como entidades completas. Tales problemas pueden simplificarse considerablemente usando funciones especiales de biblioteca orientadas a cadenas.


Por ejemplo, la mayoría de los compiladores de C incluyen funciones de biblioteca que permiten comparar cadenas, copiarlas o concatenarlas (combinadas una detrás de otra). Otras funciones de biblioteca permiten operaciones sobre caracteres individuales dentro de cadenas, por ejemplo permiten encontrar caracteres individuales dentro de una cadena.



Ejemplo:


/* Reordenar una lista de cadenas de caracteres. Para simplificar el proceso se usan las funciones de biblioteca strcmpi y strcpy. Estas funciones se usan para comparar dos cadenas y para copiar una cadena en otra, respectivamente (notar que strcmpi es una variación de la función más común strcmp, que compara cadenas pero diferenciando entre caracteres en mayúscula y minúscula. La función strcmpi no distingue entre caracteres en mayúscula o minúscula). La función strcmpi acepta dos cadenas como argumentos y devuelve un valor entero dependiendo del orden relativo de las dos cadenas como sigue:

1.- Se devuelve un valor negativo si la primera cadena precede alfabéticamente a la segunda.

2.- Se devuelve el valor cero si las dos cadenas son idénticas (caso no considerado)

3.- Se devuelve un valor positivo si la segunda cadena precede alfabéticamente a la primera.

La función strcpy acepta también dos cadenas como argumentos. Generalmente su primer argumento es un identificador que representa una cadena. El segundo argumento puede ser una cadena constante o un identificador que represente una cadena. La función copia el valor de cadena 2 en cadena 1. Esto produce que una cadena sea asignada a otra. */


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


/*ordenar alfabéticamente una lista de cadenas
este programa usa un array bidimensional de caracteres*/

int main()
{

int i, n=0;
char x[10][12];

void reordenar (int n, char [10][12]);

/*prototipo de función*/

printf(“Introducir debajo cada cadena en una línea separada\n\n”);

printf(“Escribir \’FIN\’ para terminar\n\n”);

/*leer la lista de cadenas*/

do
{
printf(“cadena %d : ”,n+1);
scanf(“%s”, x[n]);
}
while (strcmpi(x[n++], “FIN”));

/*reordenar la lista de cadenas*/

reordenar(--n,x);

/*mostrar la lista reordenada de cadenas*/

printf(“\n\nLista reordenada de cadenas: \n”);

for (i=0; i<n; ++i)

printf(“\ncadena %d: %s”, i+1, x[i]);

}

void reordenar (int n, char x[ ][12])

/*reordenar la lista de cadenas*/

{
char temp[12];
int i, elem;

for (elem=0; elem<n-1; ++elem)

/*encontrar la menor de las cadenas*/

for (i=elem+1; i<n; ++i)

if (strcmpi(x[elem], x[i])>0)
{

/*intercambiar cadenas*/

strcpy (temp, x[elem]);

strcpy (x[elem], x[i]);

strcpy (x[i], temp);

}

return;

}







E.6.➙ FICHERO DE CABECERA <string.h>


Librería con funciones para el manejo de cadenas.

- strlen (cadena): longitud de la cadena
long = strlen (v);
long = strlen (“HOLA”);

- strcpy (CAD1, CAD2): copia CAD2 en CAD1.
strcpy (CAD1, “HOLA”);
CAD1→
H
O
L
A
\O

- strcat (CAD1, CAD2): concatena CAD2 después de CAD1.
strcat (CAD1, CAD2);


CAD1∙→
L
U
N
E
S
\O


|























>

L
U
N
E
S
M
A
R
T
E
S
\O
CAD2∙→
M
A
R
T
E
S
\O

|
















COMPARACIÓN LEXICOGRÁFICA:
Se compara carácter a carácter hasta el primer carácter distinto, y entonces el carácter con ASCII más pequeño decide cuál es la cadena lexicográficamente menor.


-strcmp (CAD1, CAD2)
· 1 si CAD1 > CAD2
· 0 si CAD1 = CAD2
· -1 si CAD1< CAD2





E.7.➙ BIBLIOGRAFIA
-Programación en C Autor: Byron S. Gottfried
-Fuentes de internet: www.elrincondelc.com
-Apuntes tomados en clase