sábado, 11 de febrero de 2017

Enunciados de algoritmo



      Ingrese el valor de una compra , hecha por una persona en un almacén y calcule e imprima el total a pagar, teniendo en cuenta que si el valor de la compra es inferior a bs 100.000, no se obtiene ningún descuento, si esta entre  bs 100.000 y 500.000, el descuento será del 5% y si la compra es mayor del descuento será del 10%. Se debe imprimir, valor de la compra, descuento obtenido y total a pagar.


Realice un algoritmo que permita calcular y dar como salida el promedio general de una sección, tomando en cuenta que esta compuesta por 25 estudiantes y que se tiene la nota definitiva de cada uno de ellos.
Respuesta: Se utilizará una variable suma que irá acumulando las notas cada vez que se lea. Al final se calcula el promedio dividiendo el valor de la suma entre 25 estudiantes.


 Sean N estudiantes. Hacer un algoritmo que lea las cuatro notas de cada estudiante e imprima la nota definitiva de cada uno, sabiendo que la nota definitiva es igual a la suma de cuatro notas multiplicada por cien, divididas entre 4 y al resultado se le suma uno.Datos de entrada: Qué me dan (o que voy a leer): N estudiantes. Cada uno con cuatro notas N1, N2, N3 y N4.

Datos de Salida: Qué me piden (o que voy a escribir): La nota definitiva de cada uno NotaDProcedimiento: NotaD = ((N1 + N2 + N3 + N4)*100/4) + 1). Hay que hacerlo para casa estudiante. 

Dado un grupo de 75 Números (Diferentes a Cero), realice un algoritmo que permita determinar y dar como salida lo siguiente:* Número Mayor y número menor encontrado en el grupo* Cantidad de Números Mayores a 150* Cantidad de Números Negativos Encontrados* Promedio de los Positivos Encontrados. 

Dada La C.I., Nombre y la Nota Definitiva de 5 Materias de cada estudiante pertenecientes a un grupo de 35; realice un algoritmo que permita calcular y dar como salida el promedio de notas de cada estudiante. 

Realice un Algoritmo que permita calcular y dar como salida el promedio de bateo (PB) de cada jugador perteneciente a un equipo de 40 jugadores, tomando en cuenta que se tienen los siguientes datos:* Nombre del Jugador* Veces al Bate (VB)* Hit Conectados (HIT)* Extrabases Conectadas (EXT)* Cantidad de Sacrificios (S)* Cantidad de Bases por Bolas Recibidas (BB)

CANTV Posee dos tipos de clientes: Residencial y Empresarial, realice un algoritmo que permita procesar “n” cantidad de clientes teniendo como datos por C/U. de ellos: Código del Cliente, Tipo de Cliente, Lectura Actual, Lectura Anterior; Calculando y dando como salida la cantidad de Impulsos consumidos y el neto a pagar por cada cliente.

Una Ferretería vende dos tipos de Cables, Cable Tipo A (200 Bs. MT) y Cable Tipo B (300 Bs. MT ); realice un algoritmo que teniendo como datos por cada cliente su nombre, tipo de cable a comprar y cantidad de metros requeridos, calcule y de cómo salida el nombre y el neto a pagar por cada cliente, tomando en cuenta que existe un grupo indeterminado de ellos y que la empresa da una rebaja del 10% por cada compra que exceda de los 100 MT de cable de cualquier tipo

 Se toman los Mismos datos del 7 con la diferencia que se da la rebaja del 10% si se compran mas de 100 Mts de Cable tipo A y el 20 % si se compran mas de 100 Mts de Cable Tipo B. Un Tecnológico, ofrece un curso “x” y desea realizar un algoritmo que permita determinar y dar como salida la cantidad de dinero recaudado por concepto del curso; teniendo en cuenta que se tiene por cada participante la siguiente información:* Cédula de Identidad* Nombre del Participante* Procedencia (At = Alumno del Tecnológico, Dt = Docente del Tecnológico, Pg = Publico en General).

 Realice un Algoritmo que permita procesar a “n” cantidad de alumnos, tomando en cuenta que se tienen los siguientes datos:* Nombre del Alumno* Especialidad (I, R, A, B, P, D, T)* Turno (M, T, N)


Data la Nota de Matemática, Estadística e Informática de un grupo de 25 alumnos, realice un algoritmo que permita calcular y dar como salida lo siguiente:* Promedio de Informática* Cantidad de aprobados en matemática* Nota mayor de estadística
* Nota menos de Informática y Nombre del Br. Que la Obtuvo.



arreglos array

1. Arreglos

Los arreglos son estructuras de datos consistentes en un conjunto de datos  del mismo tipo. Los arreglos tienen un tamaño que es la cantidad de objetos del mismo tipo que pueden almacenar. Los arreglos son entidades estáticas debido  a que se declaran de un cierto tamaño y conservan este todo a lo largo de la ejecución del programa en el cual fue declarado.

Decimos arreglo o array indistintamente.

1.1. Declaración

Ejemplo de declaración:

int arreglo1[30]

//declara que arreglo1 es un arreglo que puede contener 30 enteros.

#define TAMANIO 100

int arreglo2[TAMANIO]

//declara que arreglo2 es un arreglo que puede contener TAMANIO enteros.

La ventaja de esta ultima declaración es que todos los programas que manipulen arreglo2 utilizaran como tamaño TAMANIO y si quiero cambiar el tamaño del array alcanza con cambiar la dentición de TAMANIO. Observar que en la declaración se especiada: tipo de los elementos, número
de elementos y nombre del arreglo. Un arreglo consta de posiciones de memoria contiguas. La dirección más baja corresponde al primer elemento y la más alta al ultimo. Para acceder a un elemento en particular se utiliza un índice.
En C, todos los arreglos usan cero como índice para el primer elemento y si el tamaño es n, el índice del ultimo elemento es n-1.

Ejemplo de programa que utiliza un array:

main ()


f

int arreglo2[TAMANIO];

1

/* cargo array con valor igual al índice mas 10*/

for (int i=0;i<TAMANIO;i++)



arreglo2[i]=i+10;

/* imprimo contenido del arreglo */

for (int i=0;i<TAMANIO;i++)

printf(\Elemento%d del array es%dnn",i+1,arreglo2[i]);


g



Del programa anterior podemos extraer que :

1. para cargar un elemento de un array coloco el nombre de array seguido de un índice entre paréntesis rectos y asocio el valor que desee.

2. para acceder al valor de un elemento del array coloco el nombre de array seguido de un índice entre paréntesis rectos.

3. los indices con los que accedo al array var¶³an entre 0 y la cantidad de lementos menos 1.

Los nombres de arrays siguen la misma convención que los nombres de va-variable.

Ejemplos de declaraciones:

int notas[8] /* almacena ocho notas */
char nombre[21] /* almacena nombres de largo menor o igual a 20 */
int multiplos[n] /* donde n tiene un valor, declara un arreglo de tamaño n*/

Los indices pueden ser cualquier expresi¶on entera. Si un programa utiliza una

expresion como subindice esta se evalua para determinar el indice. 

Por ejemplo

si a=5 y b=10, el enunciado arreglo2[a+b] +=2, suma 2 al elemento del arreglo

numero 15.

Puedo utilizar un elemento del arreglo en las mismas expresiones que varia-bles del tipo correspondiente. En el caso de arreglo2, puedo utilizar cualquiera de sus elementos en expresiones donde pueda utilizar una variable entera, por ejemplo

printf(" %d", arreglo2[0]+arreglo2[15]+arreglo2[30]);

Los arreglos pueden ser declarados para que contengan distintos tipos de datos. 
Por ejemplo un arreglo del tipo char puede ser utilizado para almacenar una cadena de caracteres.

21.2. Inicializacion

Los elementos de un arreglo pueden ser inicializados en la declaracion del arreglo haciendo seguir a la declaracion un signo de igual y una lista entre llaves de valores separados por comas.

Por ejemplo

int n[10]=f32, 27, 64, 18, 95, 24, 90, 70, 8, 3g;



Si en la declaracion hay menos inicializadores que el tama~no del array, los elementos son inicializados a cero. Puedo entonces inicializar todo un array en

0 con la declaracion:

int n[10]=f0g;



Declarar mas inicializadores que el tama~no del arreglo es un error de sintaxis.
Si en una declaracion con una lista inicializadora se omite el tamaño del arreglo el numero de elementos del arreglo sera el numero de elementos incluidos en la lista inicializadora.

Por ejemplo

int a1 [] = f1,2,3,4,5g;



crea un arreglo de 5 elementos.

No se puede asignar un arreglo en otro, se tiene que copiar posicion a posicion.

1.3. Operaciones frecuentes:

Recorrido de un arreglo de tama~no n:

El indice puede ir del primero al ultimo elemento:

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



f



proceso


g



El indice puede ir del ultimo al primer elemento:

for (i=n-1;i >= 0;i{)



f



proceso


g



3

1.4. Como pasar arreglos a funciones, ejemplos: funciones

en arreglos de enteros upongamos quiero definir funciones para modularizar el manejo de arreglos

de enteros. Denigremos funciones que leen datos y los almacenan en arreglos,

de¯niremos funciones que imprimen los datos almacenados en un arreglo, de¯ni-

remos una funci¶on que halla el m¶aximo en un arreglo, de¯niremos una funci¶on

que suma los elementos en un arreglo y usando ¶esta ¶ultima una funci¶on que

calcula el promedio de un arreglo.

/* Funcion leo arreglo, lectura de un arreglo de enteros */

void leo arreglo(int a[],int n)


f



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



f



printf(\Ingrese elemento :");

scanf (\ %d",&a[i]);

printf(\nn");



g


g



invocamos la funci¶on anterior pasando como argumento el nombre del arreglo

y su tama~no, por ejemplo:

leo arreglo(array2,TAMANIO)

Estudiemos la funci¶on. Recibe como parametros un arreglo (par¶ametro a) y

un entero (par¶ametro n) que representa el tama~no del arreglo.

C pasa de forma autom¶atica los arreglos a las funciones utilizando simulaci¶on

de llamadas por referencia (cualquier modi¯caci¶on que realice en la funci¶on al

array tendra efecto en el array que se pasa como par¶ametro). Esto es asi porque

el nombre del arreglo coincide con la direcci¶on del primer elemento del arreglo.

A pesar de que se pasan arreglos completos simulando llamadas por referen-

cia, los elementos individuales de arreglo se pasan en llamadas por valor.

Para que una funci¶on reciba un arreglo en una llamada de funci¶on la lista de

parametros de funci¶on debe especi¯car que se va a recibir un arreglo (lo hacemos

colocando tipo, nombre y los parentesis rectos). No es obligatorio (pero es ¶util)

pasar como argumento el tama~no del array.

Si se indica el tama~no del arreglo dentro de los par¶entesis rectos el compilador

lo ignorar¶a.

Como el pasaje del array es por referencia, cuando la funci¶on utiliza el nom-

bre del arreglo a se estar¶a re¯riendo al arreglo real en el llamador.



Veamos las otras funciones:

/* Funcion imprimo arreglo, impresion de un arreglo de enteros */

4

void imprimo arreglo(int a[],int n)


f



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



f



printf(\Elemento numero%d =%d", i+1, a[i]);

printf(\nn");



g


g



/* funcion buscar maximo: halla el maximo en un arreglo */

int buscar maximo(double valores[], int n)


f



int maximo pos = 0;

for (int i = 1; i n; i++) f

if (valores[i] valores[maximo pos]) f


maximo pos = i;


g


g



return maximo pos;


g



/* Funcion sumo arreglo, devuelve la suma de un arreglo de enteros */

int sumo arreglo(int a[],int n)


f



int suma=0;

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



suma += a[i];

return suma;


g



/* Funcion promedio: devuelve el promedio de un arreglo */

°oat promedio(int a[],int n)


f



return sumo arreglo(a,n)/n;


g



1.5. Ejemplos

1. De funciones y programas que computan arreglos:

Funci¶on que inicializa un arreglo de n lugares con los valores del 1 al

n:

void inicializo(int a[],int n)

5


f



for(int i=0;i<n;i++) a[i]=i+1;



g



Funci¶on que calcula la suma de dos arreglos de n elementos reales:

void sumo(°oat a[],°oat b[],°oat c[],int n)


f



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



c[i]=a[i]+b[i];


g



Funci¶on que calcule los primeros n n¶umeros de Fibonacci:

void Fibonacci(int a[],int n)


f



a[0]=0;

a[1]=1;

for (int i=2;i<n;i++)



a[i]=a[i-1]+a[i-2];


g



Funci¶on que invierte un arreglo :

void invierto(int b[],int n)


f



int temp;

for (int i=0;i n/2;i++)



f



temp = b[i];

b[i]=b[n-i-1];

b[n-i-1] = temp;


g


g



De otra manera:

void invierto(int b[],int n)


f



int i,j,temp;

for (i=0,j=n;i j;i++,j{)



f



temp = b[i];

b[i]=b[j];

b[j] = temp;


g


g



6

Programa que cuenta n¶umero de d¶³gitos, espacios y otros.

void main()


f



int c, i, nblancos, notros;

int ndigitos[10];

nblancos = notros = 0;

for (i = 0; i 10; ++i) ndigitos[i] = 0;



while ((c = getchar()) != EOF)

if (c >= '0' && c <= '9')



++ndigitos[c - '0'];

else if (c == ' ' jj c == 'nn' jj c == 'nt')



++nblancos;

else

++notros;

printf("digitos = ");

for (i = 0; i 10; ++i) printf("%d ", ndigitos[i]);

printf("blancos =%d, otros =%dnn", nblancos, notros);



system("PAUSE");


g



Programa que cuenta n¶umero de vocales y otros en la entrada.

main ()


f



int c, i, notros;

int nvocales[6];

notros = 0;

for (i = 0; i 5; ++i) nvocales[i] = 0;



while ((c = getchar()) != EOF)

switch (c) f


case 'a' : case 'A': ++nvocales[0];break;

case 'e' : case 'E': ++nvocales[1];break;

case 'i' : case 'I': ++nvocales[2];break;

case 'o' : case 'O': ++nvocales[3];break;

case 'u' : case 'U': ++nvocales[4];break;

default: ++notros; g


printf("vocales = ");

for (i = 0; i 5; ++i)

printf("%dÄ", nvocales[i]);

printf(\otros =%dnn", notros);



system("PAUSE");


g



7

2. De uso de funciones sobre arreglos:

Programa que lee e imprime notas ¯nales de 10 estudiantes (utilizan-

do las funciones anteriores) :

main ()


f



int notas[10];

printf(\Ingrese las notas ¯nales de los 10 estudiantesnn");



leo arreglo(notas,10);

printf(\Las notas de los estudiantes son: nn");



imprimo arreglo(notas,10);

system("PAUSE");

Programa que lee notas ¯nales de 10 estudiantes e imprime su pro-

medio (utilizando las funciones anteriores) :

main ()


f



int notas[10];

printf(\Ingrese las notas ¯nales de los 10 estudiantesnn");



leo arreglo(notas,10);

printf(\El promedio de las notas de los estudiantes es: %f", promedio(notas,10));

system("PAUSE");

Programa que lee un valor n, almacena los primeros n n¶umeros de

Fibonacci y los imprime:

main ()


f



int n;

printf(\Ingrese numero :");

scanf(" %d", &n);

putchar('nn');



int ¯b[n];

Fibonacci(¯b,n);

printf("Primeros%d numeros de Fibonacci son :nn");



imprimo arreglo(¯b,n);

system("PAUSE");

1.6. Arreglos constantes

Podr³'an existir situaciones en las cuales no queremos permitir que una fun-

ci¶on modi¯que un arreglo.

8

C proporciona un cali¯cador llamado const que se puede utilizar para evitar



la modi¯caci¶on de variables en particular de arreglos.

Cuando en un parametro de una funci¶on que representa un arreglo se an-

tecede la declaraci¶on del parametro con la palabra clave const, los elementos



del arreglo se convierten en constantes y cualquier intento de modi¯car un ele-

mento del arreglo dentro de la funci¶on da como resultado un error en tiempo de

compilaci¶on.

Ejemplo:

void trato de modi¯car(const int b [])


f



b[0] = 1;


g



dar¶a error de sintaxis.

1.7. Arreglos de caracteres o strings

Hasta ahora solo nos hemos ocupado de arreglos de enteros. Sin embargo

los arreglos son capaces de contener datos de cualquier tipo. Estudiaremos el

almacenamiento de strings o cadenas en arreglos de caracteres.



Un arreglo de caracteres puede ser inicializado utilizando una cadena, por

ejemplo, la siguiente declaraci¶on:

char string1[] = "primero";

inicializa los elementos del arreglo string1 con las letras de la palabra pri-

mero. El tama~no del arreglo queda determinado por la cantidad de letras de

primero.

Es importante notar que la cadena \primero»contiene 7 caracteres m¶as un

caracter especial que indica la terminaci¶on de la cadena que es el 'n0' o caracter



nulo. Entonces primero realmente consta de 8 caracteres y este es el tama~no del

array string1.

La declaraci¶on anterior es equivalente a :

char string1 [] = f'p', 'r', 'i', 'm', 'e', 'r', 'o', 'n0'g


Dado que una cadena es un arreglo de caracteres podemos tener acceso a

los caracteres individuales de una cadena utilizando la notaci¶on de nombre de

arreglos con subindices.

1.7.1. Lectura e impresion de cadenas

Podemos imprimir y leer una cadena con el especi¯cador de conversi¶on " %s".

Los enunciados

printf(" %s","Hola");

printf(" %s",string1);

9

imprimiran Hola y primero. El enunciado:

char string2[20];

scanf(" %s", string2);

lee una cadena del teclado y la coloca en string2. Notar que el nombre del

arreglo se pasa a scanf sin colocar el & que en otros casos se usa. El & es utilizado

por lo regular para darle a scanf la localizaci¶on de una variable en la memoria.

Como el nombre de un arreglo es la direcci¶on de inicio del arreglo el & no es

necesario.

Es responsabilidad del programador asegurarse que el arreglo al cual se lee

la cadena sea capaz de contener cualquier cadena que el usuario escriba en el

teclado. La funci¶on scanf lee caracteres del teclado hasta encontrarse con el

primer caracter de espacio en blanco. Se almacenar¶a la cadena ingresada y el

caracter nulo.

printf imprime hasta que encuentra el caracter nulo.

Si leemos una cadena con getchar(), es nuestra responsabilidad colocar el

'n0' al ¯nal del arreglo.


Ejemplo:

/* leo cadena con getchar() */

main ()


f



char ca[15];

int i=0;

while ((ca[i]=getchar())!=EOF) i++ ;

ca[i]='n0';



g



1.8. Casos de Estudio, funciones con arreglos de caracte-

res

Ejemplo 1

Escribamos un programa que lee un conjunto de lineas e imprime la m¶as

larga. Un esquema del programa es:

mientras haya otra linea

si es mas larga que la anterior mas larga

salvar la linea y su largo

imprimir linea mas larga

Este esquema muestra que el programa se puede dividir naturalmente en

funciones. Una pieza lee una nueva linea, main testea si es m¶as larga, otra

funci¶on salva la linea y main realiza el resto.

10

Empezemos escribiendo una funci¶on getline que lee una linea de la entrada.



Esta funci¶on lee hasta que encuentra EOF o nueva linea.Retorna el largo de

la linea leida y coloca el 'n0' al ¯nal del string leido. Como el EOF se ingresa



en una linea nueva, cuando se ingrese EOF se devolver¶a largo cero y el string

consistir¶a solo en el 'n0'.



Para salvar la linea utilizamos la funci¶on copiar.

Las funciones son las siguientes:

/* funcion getline */

int getline(char s[],int n)


f



int c, i=0;

while (¡¡0 && (c=getchar())!=EOF && c!='nn')



s[i++] = c;

if (c == 'nn') s[i++]=c;

s[i]='n0';



return i;


g



/* funcion copiar, reliza una copia del array que se ingresa */

void copiar(char s1[], char s2[])


f



int i=0;

while ((s2[i]=s1[i])!='n0') i++;



g



la funci¶on main es:

#de¯ne MAX 1000

main ()


f



int largo,maximo=0;

char linea[MAX];

char copia[MAX];

while ((largo=getline(linea,MAX))>0)

if (largo maximo)



f



maximo=largo;

copiar(linea,copia);


g



if (maximo 0) printf(" %s", copia); g


Ejemplo 2

11

Veamos un programa que lee un conjunto de lineas e imprime cada linea de

la entrada que contiene un patron particular. Por ejemplo

Es el tiempo

para todo el bien

el hombre va en busca

de nuevas sensaciones.

Si buscamos el patr¶on el, lo encontramos en las primeras tres lineas.



La estructura b¶asica del programa que resuelve el problema es:

mientras haya otra linea

si la linea contiene el patron

imprimo la linea

Si bien es posible poner todo el c¶odigo del programa en la instrucci¶on main,

una manera mejor de de¯nir el programa es hacer de cada operaci¶on una funci¶on

separada.

Utilizaremos la funci¶on getline del ejemplo anterior.

De¯niremos una funci¶on indice que regresa la posici¶on en la linea de entrada



en la cual se encontr¶o el patr¶on, retorna -1 si el patr¶on no se encontr¶o.

Por ¶ultimo main imprime cada linea que contiene el patr¶on.

/* funcion indice, retorna indice de t en s, -1 si no se encuentra */

int indice(char s[], char t[],int n)


f



int i,j,k;

for (i=0;s[i]!='n0';i++)



f



for (j=i,k=0; t[k]!='n0' && s[j]==t[k]; j++, k++) ;

if (t[k] == 'n0') return i;



g



return -1;


g



la funci¶on main que llama estas funciones es la siguiente:

#de¯ne MAX 1000

#de¯ne largo 10

main ()


f



char linea[MAX];

char patron[largo];

printf(\Ingrese patron");

scanf(" %s", patron);

while (getline(linea,MAX) 0)



12

if (indice(linea,patron) >= 0)



printf(" %s",linea);


g



2. Arreglos con m¶ultiples subindices

En C los arreglos pueden tener m¶ultiples subindices. Podemos utilizarlos

por ejemplo en tablas de valores que almacena informaci¶on arreglada en ¯las

y columnas. Para identi¯car un elemento de la tabla debemos especi¯car dos

subindices, el primero especi¯ca el rengl¶on del argumento y el segundo identi¯ca

la columna.

Podemos especi¯car arreglos con m¶as de 2 subindices.

Un arreglo de multiple subindice puede ser inicializado en su declaraci¶on en

forma similar a los de un subindice. Por ejemplo un arreglo de doble subindice

puede ser declarado e inicializado con:

int b[2][3] = f f1,2,3gf3,4,5gg


si para un rengl¶on dado no se proporcionan su¯cientes inicializadores los

elementos restantes de dicho inicializador se setar¶an en cero.

Veamos una funci¶on imprimo arreglo que imprima los valores de un array

de dos dimensiones por ¯la.

/* imprimo array de dos dimensiones por ¯la */

void imprimo arreglo(int a [][3],int n)


f



int i,j;

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



f



printf(\Fila%dnn", i);

for (j=0;j 3;j++)



printf("%d ", a[i][j]);

printf(\nn");



g


g



Notar que la de¯nici¶on de la funci¶on especi¯ca el par¶ametro del arreglo como

int a[][3]. El primer subindice de un arreglo de multiples subindices no se requie-

re pero todos los dem¶as subindices son requeridos. El compilador utiliza estos

subindices para determinar las localizaciones en memoria de los elementos en

los arreglos de multiples subindices. Los elementos del arreglo son almacenados

en memoria de forma consecutiva rengl¶on despues de rengl¶on.

13

Si queremos generalizar el programa, podemos de¯nir la cantidad de colum-

nas en una constante del siguiente modo:

/* imprimo array de dos dimensiones por ¯la */

#de¯ne nro columnas 3

void imprimo arreglo(int a [][nro columnas],int n)


f



int i,j;

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



f



printf(\Fila%dnn", i);

for (j=0;j nro columnas;j++)



printf("%d ", a[i][j]);

printf(\nn");



g


g



Ejemplo

Consideremos un arreglo donde cada renglon representa un alumno y ca-

da columna representa una cali¯caci¶on en uno de los cuatro examenes que los

alumnos pasaron durante el semestre.

Utilizaremos las siguientes funciones: minimo determina la cali¯caci¶on m¶as

baja de entre las cali¯caciones de todos los estudiantes. maximo determina la

cali¯caci¶on m¶as alta de entre las cali¯caciones de todos los estudiantes. pro-

medio determina el promedio para el semestre de un alumno en particular.

imprimo arreglo es la funci¶on que ya vimos.



Las funciones minimo y maximo reciben tres argumentos: el arreglo llamado

notas, el n¶umero de alumnos (renglones) y el n¶umero de examenes (colum-



nas). Las funciones iteran a trav¶es del arreglo notas utilizando estructuras for

anidadas.

Las funciones se presentan a continuaci¶on:

/* funcion minimo */

int minimo(int notas[][nro examenes],int n,int m)


f



int i,j,menorgrado=notas[0][0];

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

for (j=0; j m; j++)

if (notas[i][j] menorgrado) menorgrado = notas[i][j];



return menorgrado;


g



/* funcion maximo */

14

int maximo(int notas[][nro examenes],int n,int m)


f



int i,j,mayorgrado=notas[0][0];

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

for (j=0; j m; j++)

if (notas[i][j] mayorgrado) mayorgrado = notas[i][j];



return mayorgrado;


g



/* funcion promedio */

int promedio(int notas de alumno [],int n)


f



int i,total=0;

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



total += notas de alumno[i];

return (°oat) total/n;


g



la funci¶on promedio se invoca con una ¯la del arreglo notas del siguiente


modo:

promedio(notas[alumno],cant examenes);





Arreglos

Los arreglos (arrays) permiten almacenar vectores y matrices. Los arreglos unidimensionales


sirven para manejar vectores y los arreglos bidimensionales para matrices. Sin embargo, las matrices



tambi´en se pueden almacenar mediante arreglos unidimensionales y por medio de apuntadores a


apuntadores, temas que se ver´an en el cap´ıtulo siguiente.


La palabra unidimensional no indica que se trata de vectores en espacios de dimensi´on uno; indica


que su manejo se hace mediante un sub´ındice. El manejo de los arreglos bidimensionales se hace mediante


dos sub´ındices.

5.1 Arreglos unidimensionales

El siguiente ejemplo muestra la definici´on de tres arreglos, uno de 80 elementos doble precisi´on, otro


de 30 elementos enteros y uno de 20 elementos tipo car´acter.

double x[80];


int factores[30];


char codSexo[20];

Los nombres deben cumplir con las normas para los identificadores. La primera l´ınea indica que se han


reservado 80 posiciones para n´umeros doble precisi´on. Estas posiciones son contiguas. Es importante

recalcar que en C, a diferencia de otros lenguajes, el primer elemento es x[0], el segundo es x[1], el


tercero es x[2], y as´ı sucesivamente; el ´ultimo elemento es x[79].


En x hay espacio reservado para 80 elementos, pero esto no obliga a trabajar con los 80; el programa



puede utilizar menos de 80 elementos.


C no controla si los sub´ındices est´an fuera del rango previsto; esto es responsabilidad del programador.

Por ejemplo, si en alg´un momento el programa debe utilizar x[90], lo usa sin importar si los resultados



son catastr´oficos.


Cuando un par´ametro de una funci´on es un arreglo, se considera impl´ıcitamente que es un par´ametro


por referencia. O sea, si en la funci´on se modifica alg´un elemento del arreglo, entonces se modific´o realmente


el valor original y no una copia. Pasar un arreglo como par´ametro de una funci´on y llamar esta


funci´on es muy sencillo. Se hace como en el esquema siguiente.

... funcion(..., double x[], ...); // prototipo


//------------------------------------------------


int main(void)


{


double v[30];


...


... funcion(..., v, ...); // llamado a la funcion

59

5. ARREGLOS

...


}


//------------------------------------------------


... funcion(..., double x[],...)// definicion de la funcion


{


// cuerpo de la funcion


...


}

En el esquema anterior, el llamado a la funci´on se hizo desde la funci´on main. Esto no es ninguna



obligaci´on; el llamado se puede hacer desde cualquier funci´on donde se define un arreglo o donde a su


vez llega un arreglo como par´ametro.


Tambi´en se puede hacer el paso de un arreglo como par´ametro de la siguiente manera. Es la forma


m´as usual. Tiene involucrada la noci´on de apuntador que se ver´a en el siguiente cap´ıtulo.

... funcion(..., double *x, ...); // prototipo


//------------------------------------------------


int main(void)


{


double v[30];


...


... funcion(..., v, ...); // llamado a la funcion


...


}


//------------------------------------------------


... funcion(..., double *x, ...)// definicion de la funcion


{


// cuerpo de la funcion


...


}

El programa del siguiente ejemplo lee el tama˜no de un vector, lee los elementos del vector, los escribe y


halla el promedio. Para esto utiliza funciones. Observe la manera como un arreglo se pasa como par´ametro.

// Arreglos unidimensionales


// Lectura y escritura de un vector y calculo del promedio


//------------------------------------------------


#include <math.h>


#include <stdio.h>


#include <stdlib.h>


//------------------------------------------------


void lectX(double *x, int n, char c );


void escrX(double *x, int n );


double promX( double *x, int n);


//================================================


int main()


{


double v[40];


int n;


printf("\n Promedio de elementos de un vector.\n\n");

60

5.1. ARREGLOS UNIDIMENSIONALES

printf(" numero de elementos : ");


scanf( "%d", &n);


if( n > 40 ){


printf("\n Numero demasiado grande\n\n");


exit(1);


}


lectX(v, n, 'v');


printf(" v : \n");


escrX(v, n);


printf(" promedio = %lf\n", promX(v, n));


return 0;


}


//================================================


void lectX(double *x, int n, char c )


{


// lectura de los elementos de un "vector".


int i;


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


printf(" %c(%d) = ", c, i+1);


scanf("%lf", &x[i] );


}


}


//------------------------------------------------


void escrX(double *x, int n )


{


// escritura de los elementos de un "vector".


int i;


int nEltosLin = 5; // numero de elementos por linea


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


printf("%15.8lf", x[i]);


if( (i+1)%nEltosLin == 0 || i == n-1) printf("\n");


}


}


//------------------------------------------------


double promX( double *x, int n)


{


// promedio de los elementos del 'vector' x


int i;


double s = 0.0;


if( n <= 0 ){


printf(" promX: n = %d inadecuado\n", n);


return 0.0;


}


for( i = 0; i < n; i++) s += x[i];


return s/n;


}

61

5. ARREGLOS

La funci´on lectX tiene tres par´ametros: el arreglo, el n´umero de elementos y una letra. Esta letra sirve



para el peque˜no aviso que sale antes de la lectura de cada elemento. En el ejemplo, cuando se “llama” la

funci´on, el tercer par´ametro es 'v'; entonces en la ejecuci´on aparecer´an los avisos:



v(1) =


v(2) =


...

Observe que en el printf de la funci´on lectX aparece i+1; entonces para el usuario el “vector” empieza


en 1 y acaba en n. Internamente empieza en 0 y acaba en n ¡ 1.



Es importante anotar que si durante la entrada de datos hay errores, es necesario volver a empezar

para corregir. Suponga que = 50, que el usuario ha entrado correctamente 40 datos, que en el dato



cuadrag´esimo primero el usuario digit´o mal algo y despu´es oprimi´o la tecla Enter. Ya no puede corregir.


S´olo le queda acabar de entrar datos o abortar el programa (parada forzada del programa desde el sistema


operativo) y volver a empezar. Esto sugiere que es m´as seguro hacer que el programa lea los datos en un


archivo. La entrada y salida con archivos se ver´a en un cap´ıtulo posterior.


Cuando un arreglo unidimensional es par´ametro de una funci´on, no importa que el arreglo haya sido


declarado de 1000 elementos y se trabaje con 20 o que haya sido declarado de 10 y se trabaje con 10. La


funci´on es de uso general siempre y cuando se controle que no va a ser llamada para usarla con sub´ındices


mayores que los previstos. En la siguiente secci´on se trata el tema de los arreglos bidimensionales. All´ı,


el paso de par´ametros no permite que la funci´on sea completamente general.

En el siguiente ejemplo, dado un entero n ¸ 2 (pero no demasiado grande), el programa imprime los


factores primos. El algoritmo es muy sencillo. Se busca d > 1, el divisor m´as peque˜no de n. Este divisor


es necesariamente un primo. Se divide por y se contin´ua el proceso con el ´ultimo cociente. El proceso


termina cuando el cociente es 1. Si = 45, el primer divisor es 3. El cociente es 15. El primer divisor de



15 es 3. El cociente es 5. El primer divisor de 5 es 5 y el cociente es 1.

// Arreglos unidimensionales


// Factores primos de un entero >= 2


//------------------------------------------------


#include <math.h>


#include <stdio.h>


#include <stdlib.h>


//------------------------------------------------


int primerDiv( int n);


int factoresPrimos( int n, int *fp, int &nf, int nfMax);


//================================================


int main()


{


int vFactPrim[40]; // vector con los factores primos


int n;


int nFact; // numero de factore primos


int i;


printf("\n Factores primos de un entero >= 2.\n\n");


printf(" n = ");


scanf( "%d", &n);


if( factoresPrimos(n, vFactPrim, nFact, 40) ){


for(i = 0; i < nFact; i++) printf(" %d",


vFactPrim[i]);


printf("\n");

62

5.1. ARREGLOS UNIDIMENSIONALES

}


else printf(" ERROR\n");


return 0;


}


//================================================


int primerDiv( int n)


{


// n debe ser mayor o igual a 2.


// Calcula el primer divisor, mayor que 1, de n


// Si n es primo, devuelve n.


// Si hay error, devuelve 0.


int i;


if( n < 2 ){


printf(" primerDiv: %d inadecuado.\n", n);


return 0;


}


for( i = 2; i*i <= n; i++) if( n%i == 0 ) return i;


return n;


}


//================================================


int factoresPrimos( int n, int *fp, int &nf, int nfMax)


{


// factores primos de n


// devuelve 0 si hay error.


// devuelve 1 si todo esta bien.


// fp : vector con los factores primos


// nf : numero de factores primos


// nfMax : tamano del vector fp


int d, indic;


if( n < 2 ){


printf(" factoresPrimos: %d inadecuado.\n", n);


return 0;


}


nf = 0;


do{


if( nf >= nfMax ){


printf("factoresPrimos: demasiados factores.\n");


return 0;


}


d = primerDiv(n);


fp[nf] = d;


nf++;


n /= d;


} while( n > 1);


return 1;


}

63

5. ARREGLOS

5.2 Arreglos multidimensionales

La declaraci´on de los arreglos bidimensionales, caso particular de los arreglos multidimensionales, se


hace como en el siguiente ejemplo:

double a[3][4];


int pos[10][40];


char list[25][25];

En la primera l´ınea se reserva espacio para 3 £ 4 = 12 elementos doble precisi´on. El primer sub´ındice



var´ıa entre 0 y 2, y el segundo var´ıa entre 0 y 3. Usualmente, de manera an´aloga a las matrices, se dice


que el primer sub´ındice indica la fila y el segundo sub´ındice indica la columna.


Un arreglo tridimensional se declarar´ıa as´ı:

double c[20][30][10];

Los sitios para los elementos de est´an contiguos en el orden fila por fila, o sea, a[0][0], a[0][1],


a[0][2], a[0][3], a[1][0], a[1][1], a[1][2], a[1][3], a[2][0], a[2][1], a[2][2], a[2][3].



En el siguiente ejemplo, el programa sirve para leer matrices, escribirlas y calcular el producto. Lo


hace mediante la utilizaci´on de funciones que tienen como par´ametros arreglos bidimensionales.

// prog14


// Arreglos bidimensionales


// Lectura y escritura de 2 matrices y calculo del producto


//------------------------------------------------


#include <math.h>


#include <stdio.h>


#include <stdlib.h>


//------------------------------------------------


void lectA0(double a[][40], int m, int n, char c );


void escrA0(double a[][40], int m, int n );


int prodAB0(double a[][40], int m, int n, double b[][40],


int p, int q, double c[][40]);


//================================================


int main()


{


double a[50][40], b[20][40], c[60][40];


int m, n, p, q;


printf("\n Producto de dos matrices.\n\n");


printf(" num. de filas de A : ");


scanf( "%d", &m);


printf(" num. de columnas de A : ");


scanf( "%d", &n);


// es necesario controlar que m, n no son muy grandes


// ni negativos


printf(" num. de filas de B : ");


scanf( "%d", &p);


printf(" num. de columnas de B : ");


scanf( "%d", &q);


// es necesario controlar que p, q no son muy grandes

64

5.2. ARREGLOS MULTIDIMENSIONALES

// ni negativos


if( n != p ){


printf(" Producto imposible\n");


exit(1);


}


lectA0(a, m, n, 'A');


printf(" A : \n");


escrA0(a, m, n);


lectA0(b, n, q, 'B');


printf(" B : \n");


escrA0(b, n, q);


if( prodAB0(a,m,n, b,p,q, c) ){


printf(" C : \n");


escrA0(c, m, q);


}


else printf("\ ERROR\n");


return 0;


}


//================================================


void lectA0(double a[][40], int m, int n, char c )


{


// lectura de los elementos de una matriz.


int i, j;


for( i = 0; i < m; i++){


for( j=0; j < n; j++){


printf(" %c[%d][%d] = ", c, i+1, j+1);


scanf("%lf", &a[i][j] );


}


}


}


//------------------------------------------------


void escrA0(double a[][40], int m, int n )


{


// escritura de los elementos de una matriz


int i, j;


int nEltosLin = 5; // numero de elementos por linea


for( i = 0; i < m; i++){


for( j = 0; j < n; j++){


printf("%15.8lf", a[i][j]);


if((j+1)%nEltosLin == 0 || j==n-1)printf("\n");


}


}


}


//------------------------------------------------


int prodAB0(double a[][40], int m, int n, double b[][40],

65

5. ARREGLOS

int p, int q, double c[][40])


{


// producto de dos matrices, a mxn, b pxq


// devuelve 1 si se puede hacer el producto


// devuelve 0 si no se puede


int i, j, k;


double s;


if(m<0||n<0||p<0||q<0 || n!= p ) return 0;


for( i=0; i < m; i++){


for( j=0; j < q; j++){


s = 0.0;


for( k=0; k<n; k++) s += a[i][k]*b[k][j];


c[i][j] = s;


}


}


return 1;


}

Cuando en una funci´on un par´ametro es un arreglo bidimensional, la funci´on debe saber, en su definici´on,

el n´umero de columnas del arreglo bidimensional. Por eso en la definici´on de las funciones est´a a[][40].



Esto hace que las funciones del ejemplo sirvan ´unicamente para arreglos bidimensionales definidos con 40


columnas. Entonces estas funciones no son de uso general. Este inconveniente se puede resolver de dos


maneras:


Mediante apuntadores y apuntadores dobles. Este tema se ver´a en el siguiente cap´ıtulo.


Almacenando las matrices en arreglos unidimensionales con la convenci´on de que los primeros


elementos del arreglo corresponden a la primera fila de la matriz, los que siguen corresponden a


la segunda fila, y as´ı sucesivamente. Esta modalidad es muy usada, tiene algunas ventajas muy


importantes. Se ver´a con m´as detalle m´as adelante.


En resumen, los arreglos bidimensionales no son muy adecuados para pasarlos como par´ametros a


funciones. Su uso deber´ıa restringirse a casos en que el arreglo bidimensional se usa ´unicamente en la


funci´on donde se define.

En el ejemplo anterior, en la funci´on lectA0, antes de la lectura del elemento a[i][j], el programa


escribe los valores i+1 y j+1, entonces para el usuario el primer sub´ındice empieza en 1 y acaba en m; el


segundo empieza en 1 y acaba en n.



5.3 Cadenas

Los arreglos unidimensionales de caracteres, adem´as de su manejo est´andar como arreglo, pueden ser


utilizados como cadenas de caracteres, siempre y cuando uno de los elementos del arreglo indique el fin


de la cadena. Esto se hace mediante el car´acter especial

'\0'

En el ejemplo

// Arreglo de caracteres como tal.


#include <math.h>


#include <stdio.h>

66

5.3. CADENAS

#include <stdlib.h>


int main()


{


char aviso[30];


int i;


aviso[0] = 'C';


aviso[1] = 'o';


aviso[2] = 'm';


aviso[3] = 'o';


aviso[4] = ' ';


aviso[5] = 'e';


aviso[6] = 's';


aviso[7] = 't';


aviso[8] = 'a';


aviso[9] = '?';


for(i=0; i<= 9; i++) printf("%c", aviso[i]);


return 0;


}

el arreglo aviso se consider´o como un simple arreglo de caracteres. El programa escribe



Como esta?

En el siguiente ejemplo, el arreglo aviso es (o contiene) una cadena, string, pues hay un fin de cadena.


Para la escritura se usa el formato %s. El resultado es el mismo.



// prog15b


// Cadena de caracteres


#include <math.h>


#include <stdio.h>


#include <stdlib.h>


int main()


{


char aviso[30];


aviso[0] = 'C';


aviso[1] = 'o';


aviso[2] = 'm';


aviso[3] = 'o';


aviso[4] = ' ';


aviso[5] = 'e';


aviso[6] = 's';


aviso[7] = 't';


aviso[8] = 'a';


aviso[9] = '?';


aviso[10] ='\0';


printf("%s", aviso);


return 0;


}

Si se modifica ligeramente de la siguiente manera:

char aviso[30];

67

5. ARREGLOS

aviso[0] = 'C';


aviso[1] = 'o';


aviso[2] = 'm';


aviso[3] = 'o';


aviso[4] = '\0';


aviso[5] = 'e';


aviso[6] = 's';


aviso[7] = 't';


aviso[8] = 'a';


aviso[9] = '?';


aviso[10] ='\0';


printf("%s", aviso);

entonces ´unicamente escribe Como, ya que encuentra el fin de cadena (el primero) despu´es de la segunda


letra o.


La lectura de cadenas de hace mediante la funci´on gets( ). Su archivo de cabecera es stdio.h. Su



´unico par´ametro es precisamente la cadena que se desea leer.

char nombre[81];


printf(" Por favor, escriba su nombre : ");


gets(nombre);


printf("\n Buenos dias %s\n", nombre);

En C++ se puede utilizar cin para leer cadenas que no contengan espacios. Cuando hay un espacio, es



reemplazado por fin de cadena.

char nombre[81];


cout<<" Por favor, escriba su nombre : ";


cin>>nombre;


cout<<endl<<" Buenos dias "<<nombre<<endl;

Si el usuario escribe Juanito, el programa (la parte de programa) anterior escribir´a Buenos dias


Juanito. Pero si el usuario escribe el nombre de dos palabras Juan Manuel, el programa escribir´a Buenos


dias Juan.


En C++ es posible leer cadenas de caracteres con espacios mediante cin.getline(). Este tema no



se trata en este libro.


Para tener acceso a las funciones para el manejo de cadenas, se necesita el archivo de cabecera

string.h. Las funciones m´as usuales son:



strcpy( , )


strcat( , )


strlen( )

El primer par´ametro de strcpy (string copy) debe ser un arreglo de caracteres. El segundo par´ametro



debe ser una cadena constante o una cadena en un arreglo de caracteres. La funci´on copia en el arreglo


(primer par´ametro) la cadena (el segundo par´ametro). Se presentan problemas si el segundo par´ametro


no cabe en el primero. En un manual de referencia de C puede encontrarse informaci´on m´as detallada


sobre estas y otras funciones relacionadas con las cadenas.

La funci´on strlen (string length) da como resultado la longitud de la cadena sin incluir el fin de



cadena.


68

5.3. CADENAS

Una cadena constante es una sucesi´on de caracteres delimitada por dos comillas dobles; por ejemplo:

"Hola". No necesita expl´ıcitamente el signo de fin de cadena, ya que C lo coloca impl´ıcitamente. La


cadena constante m´as sencilla es la cadena vac´ıa: "". La cadena constante de un solo car´acter es diferente


del car´acter. Por ejemplo, "x" es diferente de 'x'.


El programa prog15b se puede escribir m´as r´apidamente as´ı:



#include <math.h>


#include <stdio.h>


#include <stdlib.h>


#include <string.h>


int main()


{


char aviso[30];


strcpy(aviso, "Como esta?");


printf("%s", aviso);


printf("\n longitud = %d\n", strlen(aviso));


return 0;


}

Como era de esperarse, el programa anterior escribe Como esta? y en la l´ınea siguiente longitud = 10.


Efectivamente las diez primeras posiciones del arreglo aviso, de la 0 a la 9, est´an ocupadas. La posici´on


10 est´a ocupada con el fin de cadena. El arreglo aviso puede contener cadenas de longitud menor o igual



a 29, pues se necesita un elemento para el signo de fin de cadena.

La funci´on strcat sirve para concatenar dos cadenas. El primer par´ametro de strcat debe ser una



cadena en un arreglo de caracteres. El segundo par´ametro debe ser una cadena constante o una cadena


en un arreglo de caracteres. La funci´on pega la segunda cadena a la derecha de la primera cadena.


Aparecen problemas si en el primer arreglo no cabe la concatenaci´on de la primera y la segunda cadenas.


La concatenaci´on se hace de manera limpia: la funci´on quita el fin de cadena en el primer arreglo y pega


la segunda incluyendo su fin de cadena.

// funcion strcat


#include <stdio.h>


#include <stdlib.h>


#include <string.h>


int main()


{


char nombre[41], apell[41], Nombre[81];


printf(" Por favor, escriba su nombre : ");


gets(nombre);


printf(" Por favor, escriba su apellido : ");


gets(apell);


strcpy(Nombre, nombre);


strcat(Nombre, " ");


strcat(Nombre, apell);


printf("Buenos dias %s\n", Nombre);


return 0;


}

69

5. ARREGLOS

5.4 Inicializaci´on de arreglos

Los arreglos peque˜nos se pueden inicializar de la siguiente manera:

double x[4] = { 1.1, 1.2, 1.3, 1.4};

Esto es lo mismo que escribir:

double x[4];


x[0] = 1.1;


x[1] = 1.2;


x[2] = 1.3;


x[3] = 1.4;

Si dentro de los corchetes hay menos valores que el tama˜no del arreglo, generalmente C asigna 0.0 a los



faltantes. El ejemplo

double x[4] = { 1.1, 1.2};

produce el mismo resultado que

double x[4];


x[0] = 1.1;


x[1] = 1.2;


x[2] = 0.0;


x[3] = 0.0;

Si no se precisa el tama˜no del arreglo en una inicializaci´on, C le asigna el tama˜no dado por el n´umero de


elementos. El ejemplo

double x[] = { 1.1, 1.2, 1.3};

es equivalente a

double x[3];


x[0] = 1.1;


x[1] = 1.2;


x[2] = 1.3;

En este otro ejemplo, con una cadena en un arreglo de caracteres,

char saludo[]= "Buenos dias";

resulta lo mismo que escribir

char saludo[12]= {'B', 'u', 'e', 'n', 'o', 's', ' ',


'd', 'i', 'a', 's', '\0'};

o igual que escribir


70

5.4. INICIALIZACI ON DE ARREGLOS

char saludo[12];


saludo[0] = 'B';


saludo[1] = 'u';


saludo[2] = 'e';


saludo[3] = 'n';


saludo[4] = 'o';


saludo[5] = 's';


saludo[6] = ' ';


saludo[7] = 'd';


saludo[8] = 'i';


saludo[9] = 'a';


saludo[10] = 's';


saludo[11] = '\0';

Para arreglos bidimensionales, basta con recordar que primero est´an los elementos de la fila 0, enseguida


los de la fila 1, y as´ı sucesivamente. La inicializaci´on

double a[2][3] = { 1.1, 1.2, 1.3, 1.4, 1.5, 1.6};

produce el mismo resultado que

double a[2][3];


a[0][0] = 1.1;


a[0][1] = 1.2;


a[0][2] = 1.3;


a[1][0] = 1.4;


a[1][1] = 1.5;


a[1][2] = 1.6;

La siguiente inicializaci´on tambi´en hubiera producido el mismo resultado anterior:

double a[][3] = { 1.1, 1.2, 1.3, 1.4, 1.5, 1.6};

En el ejemplo anterior, C sabe que las filas tienen tres elementos, entonces en el arreglo a debe haber



dos filas. En el ejemplo que sigue, C asigna ceros a lo que queda faltando hasta obtener filas completas.

double a[][3] = { 1.1, 1.2, 1.3, 1.4};

Lo anterior es equivalente a

double a[2][3];


a[0][0] = 1.1;


a[0][1] = 1.2;


a[0][2] = 1.3;


a[1][0] = 1.4;


a[1][1] = 0.0;


a[1][2] = 0.0;

En las siguientes inicializaciones hay errores. Para los arreglos bidimensionales, C necesita conocer el


tama˜no de las filas (el n´umero de columnas).


71

5. ARREGLOS

double a[][] = { 1.1, 1.2, 1.3, 1.4, 1.5, 1.6};


double b[2][] = { 1.1, 1.2, 1.3, 1.4, 1.5, 1.6};

Ejercicios

Para cada uno de los enunciados siguientes, defina cuales son los datos necesarios. Elabore un programa que lea los datos, llame la funcion (o las funciones) que realiza los calculos y devuelve los resultados, y finalmente, haga que el programa principal (la funcion main) muestre los resultados.


5.1 Intercambie los elementos de un vector: el primero pasa a la ´ultima posicion y el ´ultimo a la primera



posicion, el segundo pasa a la penultima posicion y viceversa...

5.2 Obtenga la expresi´on binaria de un entero no negativo.


5.3 Obtenga la expresi´on en base (entero, 2 · p · 9), de un entero no negativo.


5.4 Obtenga la expresi´on hexadecimal de un entero no negativo.


5.5 Averig¨ue si una lista de n´umeros est´a ordenada de menor a mayor.


5.6 Averig¨ue si una lista de n´umeros est´a ordenada de manera estrictamente creciente.


5.7 Averig¨ue si una lista tiene n´umeros repetidos.


5.8 Ordenar, de menor a mayor, los elementos de una lista.


5.9 Averig¨ue si una lista ordenada de menor a mayor tiene n´umeros repetidos.


5.10 Dada una lista de n´umeros, averig¨ue si el n´umero est´a en la lista.


5.11 Dada una lista de n´umeros, ordenada de menor a mayor, averig¨ue si el n´umero est´a en la lista.


5.12 Halle el promedio de los elementos de un vector.


5.13 Halle la desviaci´on est´andar de los elementos de un vector.


5.14 Dado un vector con componentes (coordenadas) no negativas, halle el promedio geom´etrico.


5.15 Halle la moda de los elementos de un vector.


5.16 Halle la mediana de los elementos de un vector.


5.17 Dados un vector de componentes y una lista, v1, v2, ..., vm estrictamente creciente, averig¨ue cuantos


elementos de hay en cada uno de los m+ 1 intervalos (1; v1], (v1; v2], (v2; v3], ..., (vm¡1; vm],


(vm;1).


5.18 Dado un vector de enteros positivos, halle el m.c.d.


5.19 Dado un vector de enteros positivos, halle el m.c.m. (m´ınimo com´un m´ultiplo).


5.20 Dado un polinomio definido por el grado y los + 1 coeficientes, calcule el verdadero grado. Por


ejemplo, si = 4 y p(x) = 5 + 0+ 6x2 + 0x3 + 0x4, su verdadero grado es 2.


5.21 Dado un polinomio halle su derivada.


5.22 Dado un polinomio y un punto (a; b) halle su antiderivada tal que q(a) = b.


5.23 Dados dos polinomios (pueden ser de grado diferente), halle su suma.



72

5.4. INICIALIZACI ON DE ARREGLOS

5.24 Dados dos polinomios, halle su producto.


5.25 Dados dos polinomios, halle el cociente y el residuo de la divisi´on.


5.26 Dados puntos en R2, P1, P2, ..., Pn. Verifique que la l´ınea poligonal cerrada P1P2:::PnP1 sea de



Jordan (no tiene “cruces”).

5.27 Dados puntos en R2, P1, P2, ..., Pn, tal que la l´ınea poligonal cerrada P1P2:::PnP1 es de Jordan,



averig¨ue si el pol´ıgono determinado es convexo.

5.28 Dados puntos en R2, P1, P2, ..., Pn, tal que la l´ınea poligonal cerrada P1P2:::PnP1 es de Jordan,



halle el ´area del pol´ıgono determinado.

5.29 Sea un vector en Ry A una matriz de tama˜no m £ n definida por una lista de triplas de la


forma (ik; jk; vk) para indicar que aikjk vk y que las dem´as componentes de son nulas; calcule


Ax.


5.30 Considere un conjunto de elementos enteros almacenados en un arreglo a. Considere un lista


de parejas en A £ A. Esta lista define una relaci´on sobre A. Averig¨ue si la lista est´a realmente



bien definida, si la relaci´on es sim´etrica, antisim´etrica, reflexiva, transitiva y de equivalencia.

5.31 Considere un conjunto de elementos y una matriz de tama˜no n £ n que representa una


operaci´on binaria sobre A. Averig¨ue si la operaci´on binaria est´a bien definida, si es conmutativa, si

es asociativa, si existe elemento identidad, si existe inverso para cada elemento de A.

 
VARIABLES CON INDICE O LOCALIZADOR. ARRAYS (ARREGLOS) EN C

El concepto de array en el lenguaje C coincide con el que se expone en el curso Bases de la programación nivel I de aprenderaprogramar.com cuando se habla de pseudocódigo. Veremos ahora cómo declarar arrays estáticos de una dimensión. La gestión de arrays multidimensionales la veremos más adelante.
logo lenguaje programacion C

Los arrays dinámicos no están permitidos en C, aunque hay formas para conseguir almacenar información simulando un array dinámico.


ARRAYS (ARREGLOS) UNIDIMENSIONALES
La sintaxis a emplear es la siguiente:
tipoDeElementosDelArray  nombreDelArray  [numeroElementos];
Ejemplo: int vectorEnteros [4];
Esto declara que se crea un vector de enteros que contendrá 4 valores de tipo int. Fíjate que el número en la declaración es 4, pero el elemento vectorEnteros[4] no existirá. ¿Por qué? Porque en C, al igual que en otros lenguajes de programación, la numeración de elementos empieza en cero y no en uno. De esta manera al indicar un 4, los índices de elementos en el array serán 0, 1, 2, 3. Es decir, si indicamos 4 el array tendrá 4 elementos (índices 0 a 3). Si indicamos 10 el array tendrá 10 elementos (índices 0 a 9) y así sucesivamente para cualquier número declarado.
Ejemplos de declaración de arrays serían:
int vectorVez [9];              char vectorAmigo [1000];              double decimalNum [24];
int vectorInt [23]];              int vectorLong[8];             int personasPorHabitacion[300];
Crea un proyecto y escribe el siguiente código:
#include <stdio.h>
#include <stdlib.h>
// Ejemplo aprenderaprogramar.com
int main() {
int numeroDeCoches [4];
numeroDeCoches[0] = 32;
printf ("El numero de coches en la hora cero fue %d \n", numeroDeCoches[0]);
printf ("El numero de coches en la hora uno fue %d \n", numeroDeCoches[1]);
printf ("El numero de coches en la hora dos fue %d \n", numeroDeCoches[2]);
printf ("El numero de coches en la hora tres fue %d \n", numeroDeCoches[3]);
return 0;
}
El resultado de ejecución puede ser similar a este:
El numero de coches en la hora cero fue 32
El numero de coches en la hora uno fue 8
El numero de coches en la hora dos fue 100
El numero de coches en la hora tres fue 100
¿Por qué ocurre esto? Realmente no siempre ocurrirá esto, podríamos decir que el resultado puede cambiar dependiendo del compilador. Lo que es cierto que es numeroDeCoches[0] vale 32 porque así lo hemos declarado. Sin embargo, es posible que nos aparezcan valores aparentemente aleatorios para el resto de elementos del array porque no los hemos inicializado. El compilador al no tener definido un valor específico para la inicialización les ha asignado unos valores aparentemente aleatorios. Para evitar esta circunstancia tendremos que inicializar todos los elementos de un array.

De momento lo haremos manualmente como indicamos a continuación, más adelante veremos cómo hacerlo usando un bucle que nos permitirá inicializar los elementos de un array de decenas o cientos de elementos a un valor por defecto. En el caso de enteros lo más normal es inicializar los elementos que no tienen un valor definido a cero.
En el programa anterior añadiríamos la siguiente línea:
numeroDeCoches[1]=0; numeroDeCoches[2]=0; numeroDeCoches[3]=0;
Con esto quedan inicializados todos los elementos del array y al ejecutar el programa obtenemos un resultado “seguro”.
Es posible que en un momento dado necesitemos borrar el contenido de los elementos de un array, digamos que resetear o borrar su contenido. Para ello en algunos lenguajes existen instrucciones específicas, pero en C tendremos que volver a asignar los valores por defecto a los elementos del array realizando lo que podríamos denominar una “reinicialización”. Más adelante veremos cómo se puede realizar este proceso de forma cómoda.
¿Cómo elegir los nombres de los arrays? Los nombres de variables deben ser lo más descriptivos posibles para hacer el programa fácil de leer y de entender. Piensa que es válido tanto declarar int vectorInt; como int VI;. Sin embargo es más correcto usar vectorInt que VI porque resulta más descriptivo de la función y cometido de la variable vectorInt que dos letras cuyo significado no entenderá una persona que lea el programa (y quizás tú mismo no entenderás cuando hayan pasado unos días después de haber escrito el programa).
Nota: C no realiza una comprobación de índices de arrays. Por ejemplo si hemos declarado int numeroCoches[4] e incluimos en nuestro código el uso de numeroCoches[5] el comportamiento es imprevisible. Es responsabilidad del programador el controlar y hacer uso exclusivamente de los índices válidos para cada array.


EJERCICIO RESUELTO
Crea el código de dos programas que cumplan las siguientes premisas:
a) Programa 1: Declara un array de enteros denominado numeroDeCoches que contenga 24 variables. Declara una variable tipo int que se llame R. Establece el valor de R en 2 y el valor de numeroDeCoches para un localizador de valor R en 57. Procede a mostrar en pantalla un mensaje que indique cuál es la hora R y el número de coches para la hora R. Finalmente, modifica únicamente la asignación de valor a R de modo que en vez de 2 sea 21 y ejecuta de nuevo el programa.
b) Programa 2: Sobre el programa anterior realiza los siguientes cambios. Declara dos variables A y B de tipo int. Establece A con valor 8, B con valor 4 y R con valor A dividido entre B. Ejecuta el programa.


SOLUCIÓN
El programa 1 será el siguiente. Si lo ejecutamos obtendremos "La hora R es 2. El número de coches en la hora 2 fue de 57 coches". Si cambiamos R = 2 por R = 21 obtendremos "La hora R es 21. El número de coches en la hora 21 fue de 57 coches". Es importante prestar atención a que los índices del array comienzan en cero, de modo que la primera hora es la hora cero y la última hora la hora 23, existiendo un total de 24 horas. Las horas van de 0 a 23.
#include <stdio.h>
#include <stdlib.h>
// Ejemplo aprenderaprogramar.com
int main() {
int numeroDeCoches[24];
int R;
R = 2;
numeroDeCoches[R] = 57;
printf("La hora R es %d\n", R);
printf("El numero de coches en la hora %d fue de %d coches\n", R, numeroDeCoches[R]);
return 0;
}
El programa 2 será el siguiente. Recuerda que para que el array numeroDeCoches tenga 24 elementos siendo el primero el de localizador cero, tenemos que establecerlo como numeroDeCoches[24]. En estos programas estamos usando printf, %d, \n, etc. sin haber dado una explicación al respecto. No te preocupes por esto pues lo explicaremos más adelante. Ahora es suficiente con que comprendas la lógica general de estos programas.
#include <stdio.h>
#include <stdlib.h>
// Ejemplo aprenderaprogramar.com
int main() {
int numeroDeCoches[24];
int A = 8;
int B = 4;
int R = A / B;
numeroDeCoches[R] = 57;
printf("La hora R es %d\n", R);
printf("El numero de coches en la hora %d fue de %d coches\n", R, numeroDeCoches[R]);
return 0;
}



Nota: hay una cosa “formalmente” incorrecta en estos programas. Hemos declarado un array con 24 elementos pero dichos elementos no los hemos inicializado. De hecho, hemos dejado la mayor parte sin inicializar. Idealmente es conveniente inicializar siempre los elementos de los arrays a un valor por defecto que consideremos adecuado. En este caso resultaría un tanto costoso escribir todos los términos a inicializar uno por uno. Más adelante veremos cómo hacer este tipo de inicialización de forma cómoda.


EJERCICIO
Crea el código de un programa que cumpla las siguientes premisas. Declara un array de enteros denominado numeroDeHijos que contenga 10 elementos. Declara una variable tipo int que se llame T. Establece el valor de T en 8 y el valor de numeroDeHijos para un localizador de valor T en 3. Procede a mostrar en pantalla un mensaje que indique cuál es el valor T y el número de hijos para el valor T. Finalmente, modifica únicamente la asignación de valor a T de modo que en vez de 3 sea 5 y ejecuta de nuevo el programa. Responde a estas preguntas:
a) ¿Qué significado podríamos atribuir a los índices del array? (Supón que se trata de un programa donde debes atribuirle un significado, si no tuvieran un significado en un programa, ¿para qué nos servirían?).
b) ¿Cuál será el primer índice del array?
c) ¿Cuál será el último índice del array?