Data Link (APAC)
APRENDIENDO A PROGRAMAR . APRENDIENDO CREAR
Páginas
- El lenguaje C arreglos array
- Ejemplos de enunciados para realizar en C#
- Mi Canal Data Link (APAC)
- Estructuras iterativas (Bucles)
- Sentencias de selección simple & múltiple en C#
- Lenguaje C#
- Códigos ASCII
- Gotoxy en lenguaje #C
- ESTRUCTURAS DE SELECCION SIMPLE Y MULTIPLES
- ESTRUCTURA ITERATIVAS
- CUERPO DEL PROGRAMA.
- TIPO DE DATOS & OPERADORES
- ALGORITMO TEORÍA
sábado, 11 de febrero de 2017
Enunciados de algoritmo
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).
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
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.
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 (¡¡n > 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,3g, f3,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 n = 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 n por d y se contin´ua el proceso con el ´ultimo cociente. El proceso
termina cuando el cociente es 1. Si n = 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 a 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 p (p 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 n´umeros, averig¨ue si el n´umero t est´a en la lista.
5.11 Dada una lista de n n´umeros, ordenada de menor a mayor, averig¨ue si el n´umero t 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 x de n componentes y una lista, v1, v2, ..., vm estrictamente creciente, averig¨ue cuantos
elementos de x 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 n y los n + 1 coeficientes, calcule el verdadero grado. Por
ejemplo, si n = 4 y p(x) = 5 + 0x + 6x2 + 0x3 + 0x4, su verdadero grado es 2.
5.21 Dado un polinomio halle su derivada.
5.22 Dado un polinomio p y un punto (a; b) halle su antiderivada q 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 n puntos en R2, P1, P2, ..., Pn. Verifique que la l´ınea poligonal cerrada P1P2:::PnP1 sea de
Jordan (no tiene “cruces”).
5.27 Dados n 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 n 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 x un vector en Rn y A una matriz de tama˜no m £ n definida por una lista de p triplas de la
forma (ik; jk; vk) para indicar que aikjk = vk y que las dem´as componentes de A son nulas; calcule
Ax.
5.30 Considere un conjunto A de n elementos enteros almacenados en un arreglo a. Considere un lista
de m 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 A de n elementos y una matriz M 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.
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]; |
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];
#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 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.
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?
Suscribirse a:
Entradas (Atom)