Modulo ProgramacionI
Modulo ProgramacionI
Daniel Lombardero
Año 2015
Glosario 164
1.DEFINICIÓN
El Foro es una herramienta del campus virtual utilizada como espacio de
discusión, por intermedio de mensajes, de una determinada temática. La
discusión se origina mediante la presentación de un tema, pregunta o actividad
¿Hay alguna bibliografía de consulta que pueda ser utilizada además de este
módulo?
Sí. Los títulos de la bibliografía recomendada se encuentran indicados a
continuación. Además, en el plan de trabajo pueden encontrar un detalle de
qué libros son los más adecuados para cada uno de los temas/unidades
tratados.
¿Para qué sirven las clases y cuándo las recibiré dentro de la plataforma
virtual?
La clase es una instancia sumamente importante en nuestro proceso de
aprendizaje. Es uno de elementos más destacados en esta comunicación
virtual que iniciamos. Cada semana (en particular los días lunes o en su
defecto el primer día hábil de la semana) recibirán una clase (son treinta y dos
en total a lo largo del año) que tratará el tema que corresponda en función de
nuestro avance en el desarrollo de la cursada. La clase consta de ciertos
comentarios sobre la temática puntual, así como algunos tips o preguntas que
tratan de generar una reflexión para situarlos en el porqué de la importancia de
ese tema puntual. A ese tipo de clases las llamamos teóricas.
Por otro lado, hay clases que proponen ejercicios y preguntas que tienen que
ver con la puesta en práctica de esos conocimientos adquiridos. Esas clases
son las que llamamos prácticas y son las que ustedes deberán completar y
responder de manera que desde este lado (docente) podamos medir el avance
y la comprensión sobre los temas tratados. Si bien estas clases no son
obligatorias –desde el punto de vista de que no están obligados a responderlas
para realizar luego las evaluaciones parciales a distancia-, representan una
herramienta importante para que ustedes puedan ir monitoreando si lo que van
estudiando está correctamente orientado o no en función de lo esperado.
¿Cuáles son los íconos que nos ayudarán para referenciar ciertos llamados en
nuestro módulo?
Actividad
Atención o recuerde
Foro
Ayudante de cátedra
¿Cuáles son los pasos que generalmente se siguen para realizar un algoritmo?
En resumen, y para tener una idea que nos sirva para trabajar con seudocódigo
–que ampliaremos más adelante en el módulo-, ¿qué es un algoritmo?: Es una
“fórmula” para resolver un problema. Es una “forma” de resolver un problema.
Es un conjunto de acciones o secuencia de operaciones que ejecutadas en un
determinado orden resuelven el problema. Existen muchos algoritmos para
resolver un problema, normalmente hay que elegir uno, muchas veces es el
más efectivo, otras veces es el que más nos gusta o el que consideramos más
sencillo según nuestra visión.
Características de un algoritmo:
- Tiene que ser preciso. Responder claramente a la necesidad. No puede
ser vago.
- Tiene que estar bien definido. Debe haber una secuencia estipulada.
- Tiene que ser finito. Debe tener un comienzo y un final.
La programación es adaptar el algoritmo a la computadora, al lenguaje de
programación utilizado.
El algoritmo es independiente según donde lo implemente. Esto es algo
fundamental, no se ve influido por el lenguaje de programación en el que será
escrito/implementado. Podríamos decir que es la solución al problema, y que
INICIO
Levante el tubo del teléfono
Espere tono
Marque el número del destinatario
Espere que contesten
Hable con el destinatario de la llamada
Cuelgue
FIN
Otro ejemplo de algoritmo, podría ser la secuencia que se da cada vez que
viajamos en colectivo desde un punto a otro.
INICIO
Vaya a la parada del colectivo
Espere que venga el colectivo
Levante la mano indicando que pare
Suba
Indique el destino al chofer
Acerque la tarjeta para el pago del boleto a la máquina
Permanezca en el colectivo hasta cumplir el trayecto
Cuando se acerque al destino presione el timbre
Cuando pare, descienda
FIN
Secuencia: Continuidad, sucesión ordenada. Serie o
sucesión de cosas que guardan entre sí cierta
relación. En matemática, conjunto de cantidades
u operaciones ordenadas de tal modo que cada
una está determinada por las anteriores.
Tipos de lenguajes:
-Lenguaje binario (otros lo llaman lenguaje natural, también a veces se usa el
término lenguaje máquina para englobar el binario o natural con el
ensamblador): Todo se programa con 1 y 0 que es lo único que entiende el
procesador. Es sencillo porque solamente tiene dos valores, pero es
complicado porque cada instrucción necesita para poder identificarse de varios
0 y 1.
Ventaja: No necesita ser traducido porque las máquinas entienden esos valores
en forma natural.
Inconveniente: La dificultad y la confusión para corregir errores, es propia de
cada máquina (de cada procesador). Hay una dependencia de muchos tipos
diferentes de máquinas.
Ejemplo de codificación en lenguaje binario:
Existen diferentes tipos de datos que tienen, según sea, las siguientes
características:
- Cada tipo se representa o almacena de forma diferente en la computadora.
No es lo mismo almacenar un bit, que puede tener valor 0 ó 1, que almacenar
un byte que puede tomar valores de 0 a 255 (o sea 8 bits).
- Un tipo agrupa a los valores que hacen las mismas operaciones.
- Si tiene definida una relación de orden (es decir, que todo elemento salvo el
primero y el último tienen un predecesor y un sucesor, como puede ocurrir en
los números naturales) es un tipo escalar.
- Cardinalidad de un tipo: Número de valores distintos que puede tomar un tipo
(o cantidad de diferentes valores que puede tomar una variable de ese tipo).
Pueden ser finitos (caracteres), y si son infinitos el ordenador los toma como
finitos porque está limitado por el tamaño de los bytes en el que la cifra es
almacenada. Hay una limitación física que está dada por la cantidad de bits que
cada procesador puede manejar simultáneamente, de modo que los tipos de
datos (por más que sean por ejemplo, números reales –que en matemática
tienen un número infinito de elementos, porque siempre entre dos números
reales hay otro número real-) siempre son finitos.
Los datos pueden ser:
- Simples: Un elemento.
- Compuestos: Varios elementos relacionados.
Operadores lógicos:
A veces queremos preguntar o evaluar por más de una condición al mismo
tiempo y para esto se usan los operadores lógicos: Y (and), O (or), NO (not).
Cada uno de estos operadores lógicos tiene una tabla de verdad que relaciona
los posibles valores a tomar con el resultado de la evaluación:
Y, O son operadores binarios (necesitan 2 operandos de tipo lógico):
Operando 1 Operando 2 AND OR
V V V V
V F F V
F V F V
F F F F
Las dos operaciones básicas de cada proceso con salida de datos son las de
lectura y escritura. La lectura es equivalente a la asignación en cuanto que va a
Son aquellas que contienen un bucle, un lazo (un conjunto de instrucciones que
se repiten un número finito de veces). Cada repetición del bucle se llama
MIENTRAS / HACER
REPETIR / HASTA
Repetir
<acciones>
hasta <condición>
En este caso, se repite el bucle hasta que la condición sea verdadera. Es decir,
se repite mientras la condición sea falsa. La condición se evalúa siempre al
final del bucle, si es falsa volvemos a ejecutar las acciones, si es verdadera se
sale del bucle y se ejecuta la próxima instrucción después del bucle.
Como la condición se evalúa al final, incluso aunque la primera vez ya sea
verdadera, habremos pasado al menos una vez por el bucle. Es decir que las
acciones se ejecutarán al menos una vez.
DESDE HASTA
Bucles anidados: Al anidar bucles hay que tener en cuenta que el bucle más
interno funciona como una sentencia del bloque más externo y por lo tanto, en
cada iteración del bucle más externo se van a ejecutar todas las iteraciones del
bucle más interno. Si el bucle más externo se repite n veces y el más interno se
repite m veces, si por cada iteración del más externo se repite el más interno,
entonces, el número total de iteraciones será m*n. Los bucles que se anidan
pueden ser de igual o distinto tipo.
Desde i=1 hasta 8
Desde j=1 hasta 5
Escribir “Profesor” i ”¡qué buena su asignatura!” “Esto lo escribió
el alumno” j
Fin desde
Fin desde
EDICIÓN EN LA COMPUTADORA
Es hacer entender nuestro algoritmo a la computadora para que lo pueda
ejecutar.
1. Codificamos el algoritmo en un leguaje de programación.
2. Ejecutamos el programa antes compilado.
3. Comprobamos los resultados, y si no funciona lo corregimos.
2.1.- INTRODUCCIÓN
Comenzamos el estudio de esta unidad focalizando nuestros esfuerzos en la
comprensión de algunos conceptos que nos acompañarán no sólo a lo largo
del presente curso, sino que deben ser el punto de partida para poder ampliar
nuestros conocimientos en todo el campo del saber asociado a la
programación.
El lenguaje C se creó en la década de 1970 con el objetivo de disponer de un
lenguaje de programación estructurado, de alto nivel y propósito general
orientado hacia los nuevos conceptos de programación, especialmente para
desarrollar el sistema operativo Unix, fácil de aprender y con la complejidad
suficiente para permitir una correcta preparación de los programadores. Por
eso existe una gran similitud entre la sintaxis del C y el lenguaje coloquial con
el que planteamos el problema.
Para empezar, podemos remitirnos al siguiente ejemplo, ampliamente utilizado
como primer programa por los educadores:
#include <stdio.h>
int main(void)
{
printf("Hola Mundo\n");
return 0;
}
programa:_______________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
programa:_______________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
Sin conocer lo que han escrito como definición de programa podría creer que la
misma se aproxima mucho a la que vamos a utilizar para homogeneizar
criterios en nuestro curso.
Vamos a definir programa como una secuencia de instrucciones ordenadas que
nos permiten resolver un problema. La resolución del problema obviamente
necesita de datos de partida que serán procesados por el programa y devueltos
como datos de salida por el mismo. Esto indica que todo programa está
asociado a un proceso. Este proceso no es ni más ni menos que el algoritmo
que resuelve el problema planteado. Una vez más tenemos una palabra que no
hemos usado nunca antes, la misma es ‘algoritmo’. Nuevamente vamos a
recurrir a nuestro diccionario de cabecera para definir la palabra algoritmo:
2.3.-PROGRAMAS EN C
Un programa en C tiene una forma dada – a grandes rasgos - por:
un encabezado;
una declaración de constantes, tipos y variables;
y un desarrollo de programa.
variables locales
instrucciones C
/* Programa ejemplo */
main()
{
main()
{
printf("0\n.1\n..2\n...3\n");
ASIGNACIÓN
La asignación es la acción de cargarle un valor a una variable (definimos
variable como aquel elemento en el cual es posible almacenar datos en forma
transitoria, es decir que el valor contenido en la misma puede variar a través
del tiempo). La misma se denota a través de “=”, del lado izquierdo del signo se
coloca la variable destino a la cual se le carga el valor, mientras que del lado
derecho se coloca el valor que le queremos cargar a la variable destino.
Podemos utilizar los siguientes ejemplos para comprenderlo:
tipo lista_variables;
int i, j, k;
float x,y,z;
char ch;
int _k,_h,otras,var2;
Por ejemplo:
main()
{
...
}
Las variables num, sum, num2, sum2 y letra1 son globales por la forma en que
fueron definidas, ello implica que podrán utilizarse en cualquier parte del
programa.
main()
{
...
}
float sum;
int sum2;
char letra1;
main()
{
sum = 0.0;
sum2 = 0;
letra1 = 'A';
...
}
a = b = c = 12;
c = 12;
b = 12;
a = 12;
Este último comentario permite vislumbrar una noción básica del lenguaje C. La
definición de variables debe hacerse siempre antes que comencemos a escribir
instrucciones en un bloque de programa. Esto es algo que enunciamos aquí
pero que trabajaremos muy profundamente un poco más adelante.
b = 1;
b queda cargada con el valor 1
c = d = 2;
d y c quedan cargadas con el valor 2
a = b = c = d = a + b – c * 2 + d * 3;
d, c, b y a quedan cargadas con el valor que devuelve la operación a + b – c * 2
+d*3
DELIMITADOR
Para indicar el final de una instrucción se utiliza el delimitador punto y coma. De
esta forma, cada vez que una línea de instrucción esté completa deberá
colocarse este “;” indicando el final de la misma, y que a partir de ahí comienza
una nueva instrucción.
Por ejemplo, si se asigna el valor 7 a la variable y, la instrucción completa
incluyendo el delimitador será:
IRSO – Programación I – 2015 46
Año de creación del módulo: 2011 – Última modificación: 2015
y=7;
El punto y coma al final de la línea indica que esa instrucción está completa y,
que a partir de allí comienza una nueva instrucción.
El delimitador es el ;
INSTRUCCIONES BASICAS EN C
a.- Estructuras condicionales – la sentencia IF
Esta instrucción especifica condiciones para que una acción sea ejecutada.
La forma básica que tiene esta instrucción es la siguiente:
if <condición>
<acción/acciones1>
else
<acción/acciones2>
Si la condición después del “if” es verdadera, las acciones que están después
se ejecutarán. Si en cambio la condición después del “if” es falsa, las acciones
que se ejecutarán son las que están después del “else”.
La parte asociada al “else” puede no existir, haciendo que la instrucción se
reduzca a la forma más usualmente utilizada:
if <condición>
<acción/acciones>
if (p==3)
if (p==3)
{
z=8;
m=1;
}
else
Veamos que las acciones están comprendidas entre los “{” y “}”
correspondientes a la rama del entonces y a la rama del “else”. En cada una
hay dos acciones. Al final de cada acción de las que se encuentran en la
primera posición tenemos un delimitador que indica que la instrucción terminó y
que luego viene otra instrucción. Al final de la segunda instrucción tenemos “;”
indicando que terminó la instrucción pero en muchas versiones de C no es
necesario colocar este segundo delimitador “;” porque “}” actúa por sí sola
como delimitador. De esta manera, en aquellos compiladores que lo admiten,
podemos no escribir “;” antes de un delimitador “}”. Luego del “}” asociado al
“else” se observa que hemos colocado un “;”, el mismo indica que la instrucción
“if” termina en ese “;”.
Las tres formas básicas que admite la instrucción “if” son las siguientes:
if (condición)
acción;
...o
if (condición)
acción1;
else
acción2;
...o
main()
{
int x, y, w;
........
if (x>0)
{
z=w;
.......
}
else
{
z=y;
.......
}
}
Con esto completamos básicamente los primeros conceptos asociados a la
instrucción “if”. De esta manera podremos muy pronto comenzar a escribir
nuestros primeros programas utilizando este lenguaje. Es obvio que el if por su
relación condición/decisión es una de las instrucciones más usadas en
cualquier lenguaje, siempre es necesario tomar decisiones basadas en
condiciones, y eso es exactamente lo que el if permite hacer.
b.- El operador ?
El operador condicional “?” es más eficiente que la sentencia if. El operador “?”
tiene el siguiente formato:
Que es equivalente a:
if (expresión1)
expresión2
else
expresión3;
z = (a>b) ? a : b;
if (a > b)
z = a;
else
z = b;
Esto implica que su forma es muy sencilla, por ello hay que tenerla en cuenta
porque permite reducir fuertemente cantidad de líneas de código. Por eso
también hablamos de mayor eficiencia.
c – scanf y printf
Estas dos instrucciones permiten la lectura y la escritura de variables sobre un
dispositivo determinado. El dispositivo podría ser por ejemplo el teclado, una
pantalla, una impresora, un archivo o cualquier otro de los que conocemos
como de salida.
scanf y printf nos permiten comunicarnos con el
entorno, con el usuario.
La sentencia de formato se encierra entre " ", y luego se enumeran cada una
de las variables que contienen los valores que van a imprimirse. Hay que
asegurarse de que el orden de los formatos coincida con el orden de las
variables de cada uno de los tipos de formato enumerados. Esto es, si una
variable es caracter, hay colocar el formato %c y luego enumerar una variable
de tipo caracter y no una de tipo entero en el lugar donde está el formato %c
sino tendremos inevitablemente alguna diferencia o error. En pocas palabras,
esto es algo muy importante, ya que de otro modo existirán incompatibilidades.
hola
En este caso, la utilización del “printf” hace que el cursor se quede preparado
en la última posición válida una vez que escribió sobre la pantalla. De este
modo si enviamos otra palabra a pantalla utilizando la instrucción “printf”, lo que
conseguimos es que la segunda palabra aparezca al lado de la primera. Esto
es, si la secuencia de instrucciones es la siguiente:
printf (“hola”);
printf (“chau”);
lo que aparecerá en la pantalla es lo que se ve a continuación:
holachau
holachaujaja
hola
chau
jaja
holachau
jaja
#include <stdio.h>
main()
{
printf ("Esta es una línea de texto.");
return 0;
}
<tipo_de_datos> main()
{
<bloque_de_instrucciones>
}
Los paréntesis "()" escritos después de main sirven para indicar que el
identificador main es una función. Es importante comprender que main no es
una palabra reservada de C. Ningún identificador de función lo es.
Finalmente, no podemos pasar por alto que delante de main se debe escribir el
main()
{
<bloque_de_instrucciones>
}
Ejemplo:
Generar un programa que permita imprimir “Programación I” en la pantalla.
Usted está en condiciones de realizarlo solo. Para ello recurra a los conceptos
desarrollados con anterioridad y, utilizando la estructura básica de un programa
trate de hacer este ejemplo a continuación. Luego coteje con el texto.
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
#include <stdio.h>
int main ()
{
d.- Comentarios
En el C original, tienen la forma /* cualquier texto */
Los comentarios se pueden extender varias líneas
No se pueden anidar comentarios (comentarios dentro de otros)
En C++ se usan también comentarios de una sola línea. La sintaxis es
// cualquier texto
Todo lo que se escriba a partir de las dos barras es un comentario. El
comentario termina con el final de la línea.
Ejemplos:
{
/* Esto es un comentario
que ocupa varias líneas
*/
int x;
main ()
{
Si hay más de una variable declarada del mismo tipo, pueden separarse
por comas ej.: int x,y,z;
#include <stdio.h>
#include <stdlib.h>
int x;
main ()
{
Usted está en condiciones de realizarlo sólo. Para ello recurra a los conceptos
desarrollados con anterioridad y, utilizando la estructura básica de un programa
trate de hacer este ejemplo a continuación. Luego coteje con el texto.
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
_______________________________________________________________
#include <stdio.h>
#include <stdlib.h>
int x;
main ()
{
acción;
o { bloque de acciones }
Por ejemplo:
int X;
main()
{
for( X=3; X>0; X--)
{
printf("X=%d\n",X);
}
}
X=3
X=2
X=1
La instrucción “for” hace que las instrucciones que contiene sean ejecutadas
una vez para cada valor en el rango [valor inicial al valor final].
La variable de control y los valores inicial y final deben ser de un tipo ordinal
(discretos con orden) .
Hoy
Hoy
Hoy
Hoy
De esta manera se ha ejecutado tal como se preveía, cuatro veces el lazo que
contiene el “for”, en este caso constituido sólo por una instrucción “printf” que
escribe en pantalla la palabra “Hoy”.
acciones;
o { bloque de acciones }
int main()
{
int indice;
Como vimos, el ciclo for consiste de la palabra reservada for seguida de una
expresión entre paréntesis. Esta expresión se compone de tres elementos,
cada uno separado por un punto y coma. El primero contiene la expresión
"indice = 0" y se le llama campo de inicialización. Cualquier expresión en este
lugar se ejecuta antes del inicio del ciclo. El segundo lugar, que contiene la
expresión "indice < 6 ", corresponde a la evaluación que se hace al principio de
cada ciclo y puede ser cualquier expresión que pueda evaluarse como
verdadero o falso. Sirve para saber si se ha completado el ciclo del for o si
todavía debe continuarse ejecutando. La expresión del tercer lugar se ejecuta
en cada ciclo luego de que se ejecutan las acciones contenidas en el cuerpo
del for. Hay que destacar que esto sucede hasta que se alcance la condición
de corte del ciclo. Esas acciones son lo que conocemos como cuerpo
ejecutable del ciclo for(). Esas acciones pueden ser una o varias. Si son varias,
deben incluirse las llaves “{“ y “}” que denotarán el inicio y fin de las
instrucciones que se ejecutarán en cada ciclo del for().
Luego de la ejecución del programa, la pantalla mostrará:
f.- WHILE
La instrucción “while” tiene la siguiente forma:
while <condición>
<acciones>
Esta estructura tiene una condición que controla la ejecución repetida de las
acciones. En la misma, las acciones se ejecutan mientras que la condición sea
verdadera. En el caso de que la condición sea falsa, la ejecución del ciclo
finaliza. La condición es evaluada siempre antes de que la acción se ejecute,
de modo que si la condición al inicio del ciclo es falsa, la acción no será
ejecutada nunca.
Desde el punto de vista coloquial, la instrucción “while” puede ser pensada
como: “mientras se cumpla la condición ejecuto las acciones”.
main()
{
int x=1;
while ( x < 100 )
{
printf(“Línea número %d\n”,x);
x++;
}
IRSO – Programación I – 2015 73
Año de creación del módulo: 2011 – Última modificación: 2015
}
contador = 0;
while (contador < 6)
{
printf ("El valor de contador es %d\n", contador);
contador = contador + 1;
}
return 0 ;
}
Este programa empieza con un comentario (/* Este es otro ejemplo del ciclo
while. */) y la entrada main (). Luego se define una variable de tipo entero a la
que llamamos contador dentro del cuerpo del programa, esta variable es
inicializada a cero para después entrar en el ciclo while. La sintaxis del ciclo
while es justamente como se muestra en el programa. A la palabra reservada
while le sigue una expresión entre paréntesis que es la condición de entrada
en el ciclo y luego una serie de instrucciones encerradas entre llaves. Mientras
la expresión entre paréntesis –condición de corte del ciclo- sea verdadera,
todos los enunciados entre las llaves se ejecutarán repetidamente. En este
caso, debido a que la variable contador es incrementada en 1 cada vez que
los enunciados entre las llaves son ejecutados, en algún momento se alcanzará
el valor 6. Es a partir de ese momento que contador ya no es menor a 6
finalizando así el ciclo. El programa continuará entonces ejecutando las
instrucciones que siguen a las llaves. Hay algunos comentarios para destacar y
que pueden ser de gran utilidad para terminar de comprender el funcionamiento
del ciclo: Primero, si la variable contador fuera inicializada con un valor mayor
a 5, los enunciados dentro de las llaves podrían no ejecutarse por lo que es
posible tener un ciclo while que jamás se ejecute. Segundo, si la variable de
corte o control (en este caso contador) no se incrementa dentro del ciclo, este
jamás terminaría y por ende el programa tampoco. Finalmente, si el while
do
{
scanf("%d", &num);
} while ( num>100 );
}
Esta estructura tiene una condición que controla la ejecución de las acciones
hasta que se cumpla la condición. Esto es, las acciones se ejecutarán mientras
la condición no sea falsa. Cuando la condición sea falsa, el ciclo finalizará. La
condición es evaluada siempre después de que la acción se ejecute de modo
que las acciones se ejecutarán al menos una vez.
main()
{
int i;
i = 0;
do
{
printf ( "El valor de i es ahora %d\n", i );
i = i + 1;
h.- switch/case
La instrucción switch/case permite a través del valor que puede tomar una
variable, realizar distintas acciones.
Aunque con la estructura if ... else if se pueden realizar comprobaciones
múltiples, en ocasiones no es muy elegante, ya que el código puede ser difícil
IRSO – Programación I – 2015 77
Año de creación del módulo: 2011 – Última modificación: 2015
de seguir y puede confundir incluso al autor transcurrido un tiempo. Por lo
anterior, C tiene incorporada una sentencia de bifurcación múltiple llamada
switch. Con esta sentencia, la computadora comprueba una variable
sucesivamente frente a una lista de constantes enteras o de caracter. Después
de encontrar una coincidencia, la computadora ejecuta la instrucción o bloque
de instrucciones que se asocian con la constante. La forma general de la
instrucción switch es:
switch (variable) {
case constante1:
secuencia de acciones
break;
case constante2:
secuencia de acciones
break;
case constante3:
secuencia de acciones
break;
...
default:
secuencia de acciones
}
donde la computadora ejecuta la secuencia default si no coincide ninguna
constante con la variable, esta última es opcional. Cuando se encuentra una
coincidencia, se ejecutan las acciones asociadas con el case hasta encontrar la
sentencia break con lo que sale de la estructura switch.
Las limitaciones que tiene la sentencia switch ... case respecto a la estructura if
son:
Sólo se tiene posibilidad de revisar una sola variable.
Con switch sólo se puede comprobar por igualdad, mientras que con if
puede ser con cualquier operador relacional.
printf("1. Derivadas\n");
printf("2. Limites\n");
printf("3. Integrales\n");
do
{
printf(" Teclear una opcion: ");
scanf("%d", &opc);
switch(opc)
{
case 1:
printf("\tOpcion 1 seleccionada\n\n");
break;
case 2:
printf("\tOpcion 2 seleccionada\n\n");
break;
case 3:
printf("\tOpcion 3 seleccionada\n\n");
break;
default:
printf("\tOpcion no disponible\n\n");
break;
}
} while( opc != 1 && opc != 2 && opc != 3);
}
# include <stdio.h>
main()
{
int pato;
for (pato = 3 ; pato < 13 ; pato = pato + 1)
{
switch (pato)
{
case 3 : printf("pato vale tres\n"); break;
case 4 : printf("pato vale cuatro\n"); break;
Este programa muestra en pantalla los números del 0 al 10, cuando alcanza el
valor 10 se cumple la condición del if, se ejecuta el break y sale del ciclo.
Por otro lado, continue funciona de manera similar al break. Sin embargo, en
vez de forzar la salida, continue fuerza la siguiente iteración, por lo que salta el
código que falta para llegar a probar la condición. Por ejemplo, el siguiente
programa visualizará sólo los números pares:
main()
{
int x;
main()
{
int valor;
if ( valor>100)
{
printf("Valor no valido\n");
continue;
/* Pasar al principio del ciclo nuevamente */
}
for(xx = 5 ; xx < 15 ; xx = xx + 1)
{
if(xx == 8)
break;
printf("Este bucle se ejecuta cuando xx es menor de 8,"
"ahora xx es %d\n", xx);
}
for(xx = 5 ; xx < 15 ; xx = xx + 1)
{
if(xx == 8)
continue;
printf("Ahora xx es diferente de 8, xx tiene el valor de %d\n", xx);
}
return 0;
}
Si vemos el código del programa, tenemos que en el primer bucle for, existe
una instrucción if que llama a un break si xx es igual a 8. La instrucción break
INTRODUCCIÓN:
Espero que hayan comprendido los conceptos fundamentales tratados en los
puntos anteriores como qué es un algoritmo, cómo se estructura un
programa en C, cuáles son las instrucciones más importantes
Aquí vamos a tratar de entender básicamente cuáles son los tipos de datos que
permite manejar este lenguaje, la forma de definirlos y el rango que cada uno
de ellos abarca. Para esto vamos a presentarlos uno por uno y, luego hacer
TIPOS PREDEFINIDOS
¿Qué son los tipos predefinidos?
Son aquellos que son propios del lenguaje y ya vienen definidos implícitamente
en el mismo.
float 4
double 8
Los tipos de datos básicos tienen varios modificadores que les preceden. Se
usa un modificador para alterar el significado de un tipo base para que encaje
con las diversas necesidades o situaciones. Los modificadores son: signed,
unsigned, long y short.
Ejemplo:
int i, j, k;
float x,y,z;
char ch;
Existen muchos otros tipos de datos definidos por C que iremos ampliando con
el correr de este curso, pero para profundizar necesitamos conocer muchas
estructuras de datos que aún no manejamos.
(nuevo_tipo) expresión
Por ejemplo, para forzar a que una división de enteros se realice en coma
flotante, podemos escribir:
int x=5,y=2;
float f;
f = (float)x/y;
main()
{
b = (int)a; /*En este caso, la variable b queda cargada con el valor 5*/
return 0;
}
B.
int x=7, y=5 ;
float z;
main()
{
z=x/y; /*En muchos compiladores, z queda cargada con el valor 1*/
return 0;
}
main()
{
z = (float)x/(float)y; /*En este caso, z queda cargada con el valor 1.4*/
return 0;
}
if ( disco == diskette )
printf("Es de 1440 Kb\n");
muestra 1 4 en la pantalla.
Se puede especificar el valor de uno o más símbolos usando un inicializador.
Para hacerlo, poner un signo igual y un valor entero después del símbolo.
Por ejemplo, lo siguiente asigna el valor 250 a cd
diskette 0
duro 1
cd 250
dvd 251
cinta 252
main()
{
char hola [5];
hola[0] = ‘h’;
hola[1] = ‘o’;
hola[2] = ‘l’;
hola[3] = ‘a’;
hola[4] = 0;
}
main()
{
/* Construye el nombre completo */
strcpy ( completo, nombre ); /* completo <- "Pedro" */
strcat ( completo, " "); /* completo <- "Pedro " */
strcat ( completo, apellidos ); /* completo <- "Pedro
González Arenas" */
main()
{
puts("Bienvenido a la programación");
puts(" en lenguaje C");
}
main()
{
char cadena[50];
Lo que hará que se lea una cadena de teclado y que luego se imprima. La
declaración char cadena[50]; crea una variable llamada cadena que puede
almacenar hasta 50 caracteres. Este código produce, cuando escribimos con el
teclado el texto “Bienvenido a la programación en lenguaje C”. La forma en la
que se presentará la pantalla una vez terminado de ejecutar todo el programa
será:
Donde la segunda línea es la leída por teclado gracias al ingreso de datos que
realiza el usuario, y la cuarta es la impresión de esa cadena completa leída.
Para leer caracteres hasta un límite máximo de posiciones, hay que usar fgets:
fgets ( nombre, n, cadena_fuente );
Esta función lee como máximo uno menos que el número de caracteres
indicado por n desde la fuente indicada cadena_fuente (por ejemplo el teclado
(stdin), un archivo (file) o de otra cadena de caracteres (string)). Ningún
caracter adicional es leído después del caracter de nueva línea (el cual es
retenido) o después de un final de archivo (EOF). Un carácter nulo es escrito
main()
{
putchar('H');
putchar('o');
putchar('l');
putchar('a');
putchar(32);
putchar('m');
putchar('u');
putchar('n');
putchar('d');
putchar('o');
putchar('\n');
}
main()
{
int c;
c = getchar(); /* Nótese que getchar() no devuelve nada
hasta que se presiona ENTER */
putchar(c);
main()
{
gotoxy( 20, 10 );
printf( "Hola" );
}
Obsérvese que primero se indica la columna (x) y luego la fila (y). La esquina
superior izquierda es la posición (1, 1).
Luego de la corrida del programa, la pantalla de salida mostrará:
main()
{
clrscr();
printf( "Hola" );
}
Luego del clrscr() la pantalla queda limpia (vacía) y con el printf( "Hola" ); se
imprime la palabra “Hola” en la posición (1,1) de la misma. La pantalla, una vez
ejecutado el programa quedará como se muestra a continuación:
const a = 1;
int a = 2;
Notas:
Se puede usar const antes o después del tipo.
Es usual inicializar una constante con un valor, ya que no puede ser
cambiada de alguna otra forma.
La directiva #define es un método más flexible para definir constantes en un
programa.
main()
{
x=( ( ++z ) - ( y-- ) ) % 100;
}
Es equivalente a:
int x,y,z;
main()
{
z++;
x = ( z-y ) % 100;
y--;
}
Operadores de Comparación
El operador para probar la igualdad es ==, por lo que se deberá tener cuidado
de no escribir accidentalmente sólo =, ya que:
if ( i = j ) ...
Es una sentencia legal de C (sintácticamente hablando aunque el compilador
avisa cuando se emplea), la cual copia el valor de ``j'' en ``i'', lo cual será
interpretado como VERDADERO.
Diferente es !=, otros operadores son: < menor que, > mayor que, <= menor
que o igual a y >= (mayor que o igual a).
Lo correcto es entonces: if ( i == j ) ...
Operadores lógicos
Los operadores lógicos son usualmente usados con sentencias condicionales o
relacionales, los operadores báscios lógicos son:
&& Y lógico, || O lógico y ! negación.
Orden de precedencia
Es necesario ser cuidadosos con el significado de expresiones tales como a +
b * c, dependiendo de lo que se desee hacer
(a + b) * c
o
a + (b * c)
Todos los operadores tienen una prioridad, los operadores de mayor prioridad
son evaluados antes que los que tienen menor prioridad. Los operadores que
tienen la misma prioridad son evaluados de izquierda a derecha, por lo que:
a-b-c
es evaluado como
Prioridad Operador(es)
*/%
+-
<< >>
== !=
&
&&
||
= += -= *= /=
Más baja ,
V1
1 14
2 43
3 –3
4 0
5 11
6 –45
7 7
En C, todos los arreglos usan cero como índice para el primer elemento. Por lo
tanto, el ejemplo anterior declara un arreglo de enteros con diez elementos
desde listanum[0] hasta listanum[9].
De esta forma hemos definido el vector.
Ahora nos interesa ver de qué manera podemos acceder a los valores que
contiene el vector, esto es relativamente sencillo y se realiza de la siguiente
forma: se coloca el nombre de la variable vector considerada y entre corchetes
la posición a la cual se quiere acceder. Por ejemplo, en el vector listanum[2] =
15; /* Asigna 15 al 3er elemento del arreglo listanum*/, num = listanum[2]; /*
Asigna el contenido del 3er elemento a la variable num */.
2.8. MATRICES
Del mismo modo que hemos trabajado sobre vectores (teniendo sólo un índice
para recorrer el mismo), es posible llevar este concepto a dos dimensiones (es
decir, utilizar dos índices para recorrer una estructura que tiene ahora dos
coordenadas para identificar una posición de la misma). La matriz es una
estructura estática al igual que el vector (esto es, que no varía su tamaño
durante la ejecución del programa –lo que si varía es el contenido de las
IRSO – Programación I – 2015 107
Año de creación del módulo: 2011 – Última modificación: 2015
posiciones que tiene el vector o la matriz pero no varía la cantidad de
elementos que ellos tienen). Es decir, que una vez que se define la cantidad de
elementos que tiene una matriz, esa cantidad no varía durante el tiempo de
corrida del programa. Los elementos de la matriz son todos del mismo tipo. Los
índices son de un tipo discreto ordinal. Estas básicamente son las
características de la matriz y la estructura física de la misma puede ser
representada como se ve a continuación:
M1
1 2 3 4 5 6
1 8 0 -6 11 7 -5
2 4 7 0 -1 -1 6
3 10 10 10 9 6 9
4 88 98 66 1 0 -2
Observar que para declarar cada dimensión lleva sus propios paréntesis
cuadrados.
Para acceder los elementos se procede de forma similar al ejemplo del arreglo
unidimensional, esto es,
tabladenums[2][3] = 15; /* Asigna 15 al elemento de la 3ª fila y la 4ª columna*/
num = tabladenums[25][16];
Aquí se puede ver que el nombre es elegido por el programador. Los límites
para los índices se definen utilizando los corchetes y definiendo el rango para
cada uno de ellos (el rango para las filas y el de las columnas). El tipo_base es
el tipo de los elementos de la matriz.
int main()
{
int i, j;
int multiplica[11][11];
Nota: Los valores de las matrices y los vectores deben ser cargados desde
teclado y siempre impresos sobre la pantalla.
¿Qué es un registro?
Se pueden declarar una o más variables cuando se define una estructura. Por
ejemplo:
struct direc
{
char nombre[30];
char calle[40];
char ciudad[20];
char estado[3];
unsigned int codigo;
} info_direc, binfo, cinfo;
observar que direc es una etiqueta para la estructura que sirve como una forma
breve para futuras declaraciones. Como en esta última declaración se indican
las variables con esta estructura, se puede omitir el nombre de la estructura
tipo.
int main()
{
alumno.inicial = 'R';
alumno.edad = 15;
alumno.calificacion = 75;
alumna.edad = alumno.edad - 1; /* Ella es un año menor que él */
alumna.calificacion = 82;
alumna.inicial = 'H';
return 0;
}
El programa empieza definiendo una estructura utilizando la palabra reservada
struct seguida de tres variables sencillas encerradas entre llaves, las cuales
son los componentes de la estructura, después de la llave de cierre tenemos
declaradas dos variables llamadas alumno y alumna. De acuerdo a la
definición de una estructura, alumno es una variable compuesta de tres
elementos, inicial, edad y, calificación. Cada uno de los tres campos están
Es evidente que una variable de tipo registro aislada y por sí sola no nos
permite el manejo de una gran cantidad de datos. Es por esto, que podemos
recurrir a una estructura quizás un poco más compleja, pero que admite un
manejo bastante importante en lo que a cantidad de datos se refiere. Esta
estructura no es ni más ni menos que un vector donde cada una de las
posiciones del mismo en lugar de ser enteros, reales o caracteres son
registros. Esto confiere a la nueva estructura de posibilidades concretas para el
manejo de una determinada cantidad limitada de datos, asociada obviamente al
tamaño del vector de registros. Podemos ejemplificar esta estructura tomando
en consideración el gráfico que se ve a continuación:
1 [
2 1287
4 Alberto
10
n
...
Persona p;
...
p.edad = 44;
info_direc artistas[1000];
por lo anterior, artistas tiene 1000 elementos del tipo info_direc. Lo anterior
podría ser accedido de la siguiente forma:
artistas[50].codigo=22222;
-La definición de los tipos se realiza siempre desde la estructura más sencilla a
la más compleja. Es decir que si el programador debe definir algún tipo (por
ejemplo un tipo cadena de caracteres) que luego será utilizado para definir un
campo en un registro, debe comenzar definiendo este tipo base y luego el tipo
registro. Siempre, por último, se define el tipo vector de registros que involucra
las demás estructuras definidas con anterioridad.
-El acceso a cada una de las posiciones del vector se realiza utilizando el
índice correspondiente.
-El acceso a cada uno de los campos se realiza utilizando el punto “.”
-El tamaño de una variable de tipo registro sólo es modificable en tiempo de
edición. No es posible modificarse en tiempo de corrida.
struct
{
char inicial;
int edad;
int calificacion;
}
alumnos[12];
main()
{
int indice;
return 0;
}
Para asignar un valor a cada uno de los campos utilizamos un bucle for, en
cada ciclo del bucle se asignan todos los valores para uno de los alumnos, en
una situación real ésta podría no ser la mejor manera de asignar datos, pero un
bucle puede leer los datos de un archivo o de teclado y almacenarlos en la
correcta ubicación en un programa real, este es solamente un ejemplo sencillo
para comprender el manejo básico de la estructura. Como vemos, en la línea
IRSO – Programación I – 2015 121
Año de creación del módulo: 2011 – Última modificación: 2015
que dice alumnos[10] = alumnos[4]; los tres campos de alumnos[4] son
copiados en alumnos[10], esto no siempre está permitido en Lenguaje C en
todos los compiladores, pero es algo que debemos entender como posible
porque se respetan las formas de las estructuras, es decir, hay un único tipo
struct y eso hace que dicha operación de asignación sea posible.
El resultado de la ejecución del programa mostrado en una pantalla es el
siguiente:
INTRODUCCIÓN
FUNCIONES
Una función es un conjunto de declaraciones, definiciones, expresiones y
sentencias que realizan una tarea específica.
El formato general de una función en C es
main()
{
int a=7, b=10;
float resultado;
Funciones void
Las funciones void dan una forma de emular, lo que en otros lenguajes se
conocen como procedimientos (por ejemplo, en PASCAL). Se usan cuando no
se requiere regresar un valor. Se muestra un ejemplo que imprime los
cuadrados de ciertos números.
void cuadrados()
{
int contador;
main()
{
cuadrados();
}
Funciones y arreglos
Cuando se usa un arreglo como un argumento a la función, se pasa sólo la
dirección del arreglo y no la copia del arreglo entero. Para fines prácticos
podemos considerar el nombre del arreglo sin ningún índice como la dirección
del arreglo.
Considerar el siguiente ejemplo en donde se pasa un arreglo a la función
imp_rev, observar que no es necesario especificar la dimensión del arreglo
cuando es un parámetro de la función.
void imp_rev(char s[])
{
int t;
main()
{
float numeros[]={2.3, 8.0, 15.0, 20.2, 44.01, -3.0, -2.9};
printf("El promedio de la lista es %f\n", enconprom(7,numeros) );
}
Para el caso de que se tenga que pasar un arreglo con más de una dimensión,
no se indica la primera dimensión pero, el resto de las dimensiones deben
señalarse. Se muestra a continuación un ejemplo:
void imprtabla(int tamx,int tamy, float tabla[][5])
{
Prototipos de funciones
Antes de usar una función C, se debe tener conocimiento acerca del tipo de
dato que regresará y el tipo de los parámetros que la función espera.
Básicamente si una función ha sido definida antes de que sea usada (o
llamada), entonces se puede usar la función sin problemas.
Si no es así, entonces la función se debe declarar. La declaración simplemente
maneja el tipo de dato que la función regresa y el tipo de parámetros usados
por la función.
Es una práctica usual y conveniente escribir el prototipo de todas las funciones
al principio del programa, sin embargo esto no es estrictamente necesario.
Para declarar un prototipo de una función se indicará el tipo de dato que
regresará la función, el nombre de la función y entre paréntesis la lista del tipo
de los parámetros de acuerdo al orden que aparecen en la definición de la
función. Por ejemplo:
int longcad(char []);
Lo anterior declara una función llamada longcad que regresa un valor entero y
acepta una cadena como parámetro.
Entonces,
Las funciones son siempre globales, esto es, no se permite declarar una
función dentro de otra.
Las funciones son visibles sólo después de que se han declarado.
Se pueden declarar funciones, especificando sólo su formato, pero no su
cuerpo:
con lo anterior se define una unión llamada numero y una instancia de esta
llamada unumero. numero es la etiqueta de la unión y tiene el mismo
comportamiento que la etiqueta en la estructura.
Los campos pueden ser direccionados de la siguiente forma:
printf("%ld\n",unumero.longnumero);
typedef struct
{
int capac_elev;
} helicoptero;
typedef struct
{
int maxcarga;
} avioncarga;
typedef union
{
jet jetu;
helicoptero helicopterou;
avioncarga avioncargau;
} transporteaereo;
typedef struct
{
int tipo;
en el ejemplo se define una unión base de transporte aéreo el cual puede ser
un jet, un helicóptero o un avion de carga.
En la estructura un_transporeaereo hay un campo para el tipo, que indica cual
es la estructura manejada en ese momento.
3.3. ARCHIVOS
Ustedes ya han tenido contacto con la definición de archivo en la asignatura Estructura
de un Computador.
Aquí vamos a refrescarla, un archivo es una estructura dinámica (puede variar su
tamaño en tiempo de ejecución) utilizada para almacenar datos. En principio, en los
archivos que vamos a utilizar, todos los datos van a ser del mismo tipo. Esto significa
que si creamos un archivo de enteros, sólo servirá para trabajar con números enteros.
El tamaño de un archivo no es fijo (como en el caso de un vector) y puede variar a
medida que se agregan o quitan datos en tiempo de corrida de un programa. El
archivo ocupa un espacio determinado del disco de almacenaje (sea este un disco
duro, un diskette, un CD o cualquier otro tipo de elemento que permita
resguardar este tipo de estructuras), se lo identifica con un nombre formado de
la siguiente manera: <nombre>.<extensión> donde el <nombre> es elegido por
el programador y la extensión tendrá que ver normalmente con el tipo de
utilitario que se use para su manejo. Cuando el archivo es utilizado en un
programa, se establece una relación directa entre el archivo que tenemos
almacenado en el disco, y la variable de tipo archivo que será generada en el
programa. De esta forma, los datos contenidos por el mismo pueden ser
manejados por el programa. Otro elemento importante en un archivo es la
identificación concreta del principio y fin de archivo (begin of file – BOF y end of
file – EOF).
ARCHIVO1
BOF
EOF
Aquí vemos la estructura básica de un archivo con sus partes componentes tal
como hemos descripto precedentemente.
Vamos ahora a trabajar sobre las distintas instrucciones que permiten manejar
los datos en esta estructura.
Modelo de uso:
...
Muchas de las funciones de STDIO para trabajar con archivos comienzan con
la letra "f" (fopen, fclose, fprintf, fwrite, etc.)
t archivo de texto
Ejemplo:
Hay un archivo muy especial, el archivo vacío, que tiene la siguiente forma:
BOF
EOF
¿Cómo cerramos el archivo una vez que hemos realizado todas las
operaciones?
fclose ( fd );
fputs ( cadena, fd );
Ejemplo
FILE* fich;
char cadena [16];
/* lee los últimos 15 caracteres del archivo */
fich = fopen ( "archivo.txt", "rt" );
fseek ( fd, -15L, SEEK_END);
fgets ( texto, 15, fich );
fclose (fich);
¿Qué es un stream?
Los archivos de donde se lee o escribe información con las rutinas de STDIO
se llaman flujos o streams. Un flujo puede ser un archivo, pero también puede
ser el teclado (se puede leer de él) o la pantalla (se puede escribir en ella).
Los llamados flujos estándar son los siguientes:
EJERCITACIÓN
Práctica 2: Estructuras
Nota: Los vectores y registros deben ser cargados desde teclado e impresos en
pantalla.
Práctica 3: Archivos
4.1. RECURSIVIDAD
Existen muchas funciones matemáticas cuyos argumentos son números
naturales, que pueden definirse de manera recursiva. Esto quiere decir que el
valor de la función para el argumento n puede definirse en términos del
argumento n-1 (o alguno anterior). En este tipo de definiciones siempre existirá
un caso base a partir del cual parte la definición, el cual normalmente es el
valor de la función en cero o en uno, aunque no necesariamente debe ser así.
Por ejemplo, el factorial puede definirse de manera recursiva de la siguiente
manera:
EJERCITACIÓN
Práctica 4: Recursividad
Ejercicio 8: Calcular el producto a*b con a entero y menor que cero, y b real.
int x = 1, y = 2;
int *ap;
ap = &x;
x 1 y 2 ap 100
x 1 y 1 ap 100
x 100 y 1 ap 100
x 3 y 1 ap 100
Con los punteros se puede realizar también aritmética entera, por ejemplo:
main()
{
float *flp, *flq;
*flp = *flp + 10;
++*flp;
(*flp)++;
flq = flp;
}
5.2. PUNTEROS Y FUNCIONES
Cuando C pasa argumentos a funciones, los pasa por valor, es decir, si el
parámetro es modificado dentro de la función, una vez que termina de
ejecutarse la función, el valor pasado de la variable permanece inalterado.
Hay muchos casos que se quiere alterar el argumento pasado a la función y
recibir el nuevo valor una vez que la función ha terminado. Para hacer lo
anterior se debe usar una llamada por referencia, en C se puede simular
pasando un puntero al argumento. Con esto se provoca que la computadora
pase la dirección del argumento a la función.
Para entender mejor lo anterior consideremos la función swap() que
intercambia el valor de dos argumentos enteros:
void swap(int *px, int *py);
IRSO – Programación I – 2015 149
Año de creación del módulo: 2011 – Última modificación: 2015
main()
{
int x, y;
x = 10;
y = 20;
printf("x=%d\ty=%d\n",x,y);
swap(&x, &y);
printf("x=%d\ty=%d\n",x,y);
}
n1.sig = &n2;
#include <stdio.h>
main ()
{
/* Una variable entero y un puntero de tipo int */
IRSO – Programación I – 2015 154
Año de creación del módulo: 2011 – Última modificación: 2015
int almacen, *puntero;
Con este ejemplo sencillo es posible ver cuál es la diferencia fundamental que
existe entre un puntero (o dirección de memoria) y el contenido del mismo.
El primer campo del registro (struct) es un campo entero (int) llamado info. El
segundo campo es un puntero llamado sig que apunta a un registro con la
misma forma del registro del que forma parte. Esto parece un trabalenguas o
una definición cíclica, pero es de gran ayuda servirse del dibujo que representa
la lista simplemente enlazada para darse cuenta de que el puntero del primer
registro apunta a un segundo registro que tiene la misma forma que el primer
registro. El campo puntero del último registro de la lista apunta a NULL.
Si quisiéramos representar una lista vacía, su estructura se definiría de la
siguiente manera:
Para insertar un primer registro a esa estructura lista que se encuentra vacía,
se debe codificar de la siguiente forma:
aux=lista;
lista=malloc(sizeof(struct Nodo));
lista->info=3
lista->sig=aux
¿Cuáles son las acciones que requerimos más usualmente para trabajar con
esta estructura?
Por ejemplo, un procedimiento para borrar un elemento en la posición p en una
lista doblemente enlazada es:
void borrar (posicion p)
{
if (p->anterior != NULL)
p->anterior->siguiente = p->siguiente;
if (p->siguiente != NULL)
p->siguiente->anterior = p->anterior;
free(p);
}
Esto muestra lo sencillo y complejo a la vez que es el direccionamiento sobre
cada una de las celdas de lista si queremos hacer referencia a un elemento
posterior o anterior desde una celda cualquiera hacia otra celda cualquiera.
Materia: Programación I
Docente: Daniel Lombardero
Alumno:
DNI:
Algunas recomendaciones:
Para la realización del trabajo, enumeramos algunas recomendaciones que le
pueden ser de utilidad:
Desarrollo de la evaluación
Apellido y Nombre:
…………………………………………………………………………………………
D.N.I:
………………………………………………………………………………………………………………
Consideraciones Generales
Intente responder en forma completa y sintética a lo solicitado.
Se estima un máximo de 1 (una) hora y 40 minutos reloj para su realización.
El examen se realizará sin material de apoyo o consulta.
Se recomienda la lectura completa del examen antes de comenzar a responder.
No se considerarán los borradores.
Calificación
Se califica el examen de 1 (uno) a 10 (diez).
Se aprueba con un puntaje mínimo de 4 (cuatro) puntos
Deben responderse todas las preguntas, es decir, no se puede aprobar el examen con
alguna pregunta sin responder aunque con las resueltas se llegara a la calificación de 4
(cuatro) o más puntos.
En cada pregunta se indica la puntuación de la misma entre paréntesis.
Criterios de evaluación
Correcta interpretación de los enunciados.
Pertinencia de las respuestas.
Aplicación de conceptos teóricos y prácticos trabajados.
Coherencia en la respuesta de los enunciados.
Comprensión de los núcleos esenciales de los contenidos.
Utilización correcta de las instrucciones en C.
Manejo adecuado de la programación estructurada.
Conocimiento de los diferentes tipos y estructuras de datos con los que cuenta el
lenguaje.
2 (1,5 punto): Indique qué son los parámetros, para qué sirven.
3 (3,5 puntos): Dado un vector de 1040 posiciones donde sus índices son enteros y sus datos
reales (que se leen de teclado), se quiere generar un archivo de reales donde se copian los
datos del vector. Para ello deberá hacer un programa que contenga al menos tres
procedimientos: uno para leer los datos de teclado y cargarlos en el vector, otro para tomar los
elementos del vector y copiarlos en el archivo, y un tercero para imprimir los valores
almacenados en el archivo e imprimirlos en pantalla.
5 (0,5 punto): Defina qué es un archivo y cuáles son sus características/propiedades más
importantes. ¿Para qué sirven en la práctica? ¿qué diferencia hay en la definición de un archivo
de texto y uno de enteros? Defina un ejemplo de cada uno de ellos.
6 (0,5 punto): ¿Para qué sirve el prototipo de una función? Dar un ejemplo.
7 (2 puntos): Realizar una función que devuelva el mayor de dos números reales que se pasan
por teclado.
CPU.- Siglas para "Central Process Unit" (Unidad Central de Proceso, UCP).
Declaración.-
Símbolo Significado
() Paréntesis
^ Exponenciación
DIV División entera
MOD Módulo
* Multiplicación
/ División
+ Suma
- Resta
= Asignación
Lista doblemente enlazada.- Una lista cuyos nodos utilizan punteros para
permitir el movimiento hacia delante y hacia atrás de un nodo perteneciente a
la estructura lista.
Operadores Lógicos.-
Operadores Relacionales.-
A NO A
Falso Verdadero
Verdadero Falso
A B (A) O (B)
Falso Falso Falso
Falso Verdadero Verdadero
Verdadero Falso Verdadero
Verdadero Verdadero Verdadero
A B (A) Y (B)
Falso Falso Falso
Falso Verdadero Falso
Tipo de datos ordinales.- Los tipos de datos ordinales son todos aquellos
tipos que no sean reales (integer, longint, shortint, byte, word, char,
enumeraciones y subrangos).
Probablemente, el tipo de datos más útil es longint (abreviatura en inglés de
long integer o entero largo), este tipo de datos maneja valores de hasta
2,147,483,647 en vez de 32,767 del tipo integer. Por ejemplo, para almacenar
el producto de 2,000 * 2,000 (donde el resultado es cuatro millones) se debe
utilizar una variable de tipo longint en vez de una de tipo integer.
Usualmente es recomendable utilizar integer en vez de longint debido a que
este último tipo utiliza más memoria, además de reducir significativamente la
velocidad de procesamiento. Por lo tanto, cuando se está seguro de que el uso
de un integer será suficiente, es mejor que este sea utilizado.
Tipos de constantes.-
Tipo Ejemplo
a) Entera: -1, 0, 25
b) Reales: 0.002, 3.14159, -2.34567, 5432.
c) Carácter: 'a', 'A', '+', ',', '9'
d) Cadena de
'A1', 'Hola', 'PRIMER ALGORITMO'
caracteres:
e) Lógicas: falso, verdadero; 0, 1; Si, No
Tipos de memoria.-
Validar.- Verificar que los datos arrojados por el programa sean correctos.