Documentos de Académico
Documentos de Profesional
Documentos de Cultura
CURSOLP
CURSOLP
Captulo 1
Programacin estructurada
La programacin estructurada signica escribir un programa de acuerdo a las siguientes reglas:
Cada modulo se codica utilizando las tres estructuras de control bsicas: secuencial, alternativa y repet-
itiva.
El termino programacin estructurada se reere a un conjunto de tcnicas que aumentan considerablemente
la productividad del programa reduciendo en elevado grado el tiempo requerido para escribir, vericar, depurar
y mantener los programas. La programacin estructurada utiliza un nmero limitado de estructuras de control
que minimizan la complejidad de los programas y por consiguiente reducen los errores.
La programacin estructurada es el conjunto de tcnicas que incorporan:
Recursos abstractos.
Recursos abstractos
Descomponer un programa en trminos de recursos abstractos segn Dijkstra consiste en descomponer
una determinada accin compleja en trminos de un nmero de acciones ms simples.
Diseo descendente
El diseo descendente es el proceso mediante el cual un problema se descompone en una serie de niveles o
pasos sucesivos de renamiento. La metodologa descendente consiste en efectuar una relacin entre las sucesivas
etapas de estructuracin, de modo que se relacionen unas con otras mediante entradas y salidas de informacin.
Es decir, se descompone el problema en etapas o estructuras jerrquicas de forma que se puede considerar cada
estructura desde dos puntos de vista: Qu hace? Y Cmo lo hace?.
Si se considera un nivel n de renamiento, las estructuras se consideran de la siguiente manera:
Estructuras bsicas
Cualquier programa con un solo punto de entrada y un solo punto de salida puede resolverse con tres tipos
de estructuras bsicas de control: Secuencial, alternativa y repetitiva.
- Secuencial
Es aquella que ejecuta las acciones sucesivamente unas a continuacin de otras sin posibilidad
de omitir ninguna, y naturalmente sin bifurcaciones (saltos a subrutinas). Todas estas estructuras tendrn una
entrada y una salida.
- Alternativa
Es aquella en la que nicamente se realiza una alternativa dependiendo del valor de una
determinada condicin o predicado. Las estructuras alternativas tambin llamadas condicionales pueden ser de
tres tipos: Simple, doble o mltiple
Alternativa simple: Son aquellas en donde la existencia o cumplimiento de la condicin implica la ruptura
de la secuencia y la ejecucin de una determinada accin.
Alternativa doble
Es aquella que permite la eleccin entre dos acciones o tratamientos en funcin de que se cumpla o no
determinada condicin
Alternativa mltiple
Se adopta cuando la condicin puede tomar n valores enteros distintos. Segn se elija uno de estos valores
en la condicin se realizara una de las n acciones. Esta estructura propuesta por Hoare, es la case del lenguaje
Pascal o case de los Basic estructurados (Case = estructura de casos).
Repetitiva o iterativa
Son aquellas en las que las acciones se ejecutan un nmero determinado de veces y dependen de un valor
predenido o el cumplimiento de una determinada expresin lgica. Un bucle o lazo es el conjunto de acciones
a repetir. En consecuencia es preciso disponer de estructuras algortmicas que permitan describir una iteracin
de forma cmoda. Las tres estructuras mas usuales dependiendo de que la condicin se encuentre al principio o
al nal de la iteracin son: Estructura mientras, repetir hasta y estructura para.
veces hasta que la condicin no se cumpla. Esta condicin se ejecuta al menos una vez. A esta estructura tambin
se le conoce como Do While.
Estructura Para
esta se cumple se ejecuta el cuerpo del ciclo y posteriormente se incrementa la variable de control, lo anterior
se repite hasta que la condicin no se cumpla.
Secuencia
Programa
Se le llama programa a la serie de instrucciones escritas en alguno de los lenguajes, por medio de los
cuales se logra que la computadora realice todas las operaciones o decisiones sealadas en dichas instrucciones.
Podemos distinguir dos tipos de programa:
Programa fuente: es el conjunto de instrucciones escritas en algn lenguaje de computadora, las cuales han
sido transcritos para ser interpretadas por algn dispositivo de lectura.
Programa objeto: es el conjunto de instrucciones que componen un programa fuente y que han sido traducidas
al lenguaje maquina por medio del compilador correspondiente.
Un compilador es un programa que traduce el programa fuente a programa objeto. Un compilador independiente se requiere para cada lenguaje de programacin. ste efecta slo la traduccin, no ejecuta el programa.
Una vez compilado el programa, el resultado en forma de programa objeto ser directamente ejecutable.
Pseudocdigo
pseudocdigo no es realmente un cdigo sino una imitacin y una versin abreviada de instrucciones reales para
las computadoras.
Programa
Mayor2Numeros;
Entorno
Entero
numero1,numero2;
Inicio
Escribe
Lee
numero1;
Escribe
Lee
Si
numero2;
Escribe
Escribe
Sino
Fin
si;
Fin;
Ahora procederemos a resolver utilizando un software de diagramas de ujo de Datos
10
11
CompararNumero;
Entero numero;
Inicio
Escribe
Lee
Si
Introduce un nmero: ;
numero;
Escribe
Fin
Si
si;
Escribe
Fin
si;
Fin;
Algoritmo que lea dos nmeros por teclado y muestre un mensaje por pantalla indicando si el
cuadrado el primero es mayor que el cubo del segundo.
Programa
CoparaConOperaciones;
Entorno
Entero
Entero
Inicio
Escribe
Lee
num1;
Escribe
Lee
num2;
cuadrado
cubo
Si
= n1 * n1;
= n2 * n2 * n2;
Escribe
Fin
Fin;
si;
12
Algoritmo que lean un nmero entero entre 1 y 10, y nos muestre por pantalla el nmero en letra
(el literal). Si el nmero ledo no esta comprendido entre 1 y 10 mostrar dicha incidencia.
Programa
NumeroALiteral;
Entorno
Entero
Inicio
n;
Lee n;
/* Aunque se cumpla una condicin el ordenador debe evaluarlas todas, con el coste de rendimiento que
esto representa */
Si
n = 1 entonces
Escribe
Uno ;
Fin si;
Si n = 2 entonces
Escribe Dos ;
Fin si;
Si n = 3 entonces
Escribe Tres ;
Fin si;
Si n = 4 entonces
Escribe Cuatro ;
Fin si;
Si n = 5 entonces
Escribe Cinco ;
Fin si;
Si n = 6 entonces
Escribe Seis ;
Fin si;
Si n = 7 entonces
Escribe Siete ;
Fin si;
Si n = 8 entonces
Escribe Ocho ;
Fin si;
Si n = 9 entonces
Escribe Nueve ;
Fin si;
Si n = 10 entonces
Escribe Diez ;
Fin si;
/* Comprobamos si el nmero no est entre 1 y 10 para mostrar mensaje */
Si n < 1 o n> 10 entonces
Escribe El nmero no est entre 1 y 10 ;
Fin si;
Fin;
13
Realizar un algoritmo que lea tres nmeros por teclado y nos indique cual de ellos es el mayor.
Programa
Entorno
NumerosOrdenados;
Inicio
Escribe Introduce 3 nmeros ;
Lee n1, n2, n3;
Si n1 > n2 entonces
// El mayor ser n1 o n3
Si n1 > n3 entonces
Escribe El mayor es , n1;
Sino // n1 <= n3
Escribe El mayor es , n3;
Fin si;
Sino
// n1 <= n2, debemos comparar n2 y n3. El mayor ser n2 o n3
Si n2 > n3 entonces
Escribe El mayor es , n2;
Sino
Escribe El mayor es , n3;
Fin si;
Fin si
Fin
Algoritmo que lee tres nmeros cualesquiera y los escribe ordenados de forma ascendente.
Programa
NumerosOrdenAscendente;
Entorno
Entero
Inicio
Escribe Introduce tres nmeros: ;
Lee n1, n2, n3;
Si n1 > n2 entonces
Si n2 > n3 entonces
Escribe n3, n2, n1;
Sino // n2 <= n3
Si n1 > n3 entonces
Escribe n2, n3, n1;
Sino
Escribe n2, n1, n3;
Fin si;
Fin si;
Sino // n1 <= n2
Si n2 < n3 entonces
Escribe n1, n2, n3;
14
si
Fin;
Algoritmo que lee una calicacin numrica entre 0 y 10 y la transforma en calicacin alfabtica,
escribiendo el resultado
0<=Nota<3
MD
3<=Nota<5
INS
5<=Nota<6
SUF
6<=Nota<7
BIE
7<=Nota<9
NOT
9<=Nota<=10
SOB
Programa
NumeroALiteral;
Entorno
Entero
n;
Inicio
Escribe Introduce un nmero: ;
Lee n; /* No sangraremos todas las sentencias incluidas dentro del Sino pues no hay espacio en el papel
y adems est forma es ms clara. No hay que olvidar poner tantos Fin si como Si hayamos abierto
*/
Si
n = 1 entonces
Escribe
Sino
Si n = 2 entonces
Escribe
Sino
Siete ;
Si n = 8 entonces
Escribe
Sino
Seis ;
Si n = 7 entonces
Escribe
Sino
Cinco ;
Si n = 6 entonces
Escribe
Sino
Cuatro ;
Si n = 5 entonces
Escribe
Sino
Tres ;
Si n = 4 entonces
Escribe
Sino
Dos ;
Si n = 3 entonces
Escribe
Sino
Uno ;
Ocho ;
Si n = 9 entonces
Escribe
Nueve ;
15
Si n = 10 entonces
Escribe
Diez ;
Sino
/* El nmero no est entre 1 y 10 para mostrar mensaje */
Escribe El nmero no est entre 1 y 10 ;
Fin si;
Fin Si;
Fin Si;
. . . Fin Si;
/* A diferencia de la implementacin del ejercicio 3 este algoritmo
Fin;
Algoritmo que lee tres nmeros cualesquiera y nos indica todas sus relaciones de igualdad
Programa
RelacionesIgualdad;
Entorno
Entero
Inicio
Escribe Introduce tres nmeros: ;
Lee n1, n2, n3;
Si n1 = n2 y n1 = n3 entonces
Escribe Los tres nmeros son iguales ;
Sino
Si n1 = n3 entonces
Escribe El 1 y el 2 son iguales ;
Sino
Si n2 = n3 entonces
Escribe El 2 y el 3 son iguales ;
Sino
Escribe Todos son distintos ;
Fin si;
Fin si;
Fin si;
Fin;
Algoritmo que recibe como datos de entrada una hora expresada en horas, minutos y segundos
que nos calcula y escribe la hora, minutos y segundos que sern transcurrido un segundo.
Programa
UnSegundoDespues;
Entorno
Entero
Inicio
Escribe Introduce hora: ;
Lee hora;
16
Entorno
Entero
Inicio
anyo;
Lee anyo;
Si (anyo % 4 = 0) y No ( anyo % 100 = 0 y no ( anyo % 400 =0) ) entonces
Escribe El ao , anyo , es bisiesto ;
Sino
Escribe El ao , anyo , NO es bisiesto ;
Fin si;
Fin;
En un determinado comercio se realiza un descuento dependiendo del precio de cada producto.
Si el precio es inferior a S/. 6 , no se hace descuento; si es mayor o igual a S/. 6 y menor que
S/.60 se hace un 5 % de desceunto, y si es mayor o igual a S/. 60 se hace un 10 % de descuento.
Realizar el algoritmo que lee el precio de un producto y nos calcula y escribe su precio nal.
Programa
Calculo_Precio_Final;
Entorno
Entero
PrecioInicial, Dto;
Inicio
Escribe Introduce precio Inicial: ;
Lee PrecioInicial;
17
Dto
= 0;
Sino
Si PresioInical < 60 entonces
Dto = 5;
Sino
Dto = 10;
Fin si;
Escibe
Fin;
Algoritmo que lee el precio nal pagado por un producto y su precio de tarifa y nos calcula el
porcentaje de descuento que le ha sido aplicado.
Programa
Entorno
Calculo_Descuento;
Inicio
Escribe Introduce precio Tarifa: ;
Lee PrecioTarifa;
Escribe Introduce precio Final: ;
Lee PrecioFinal;
/* La dicultad de este problema es
plejidad algortmica */
Dto = (1-PrecioFinal/PrecioTarifa)*100;
Escibe Descuento = , Dto, % ;
Fin;
Algoritmo que lee 3 nmeros distintos y nos dice cual de ellos es el menor.
Programa
Entorno
NumeroMenor;
Inicio
Escribe Introduce 3 nmeros ;
Lee n1, n2, n3;
Si n1=n2 o n1=n3 o n2=n3 entonces
Escribe Los nmeros no son distintos ;
Sino
Si n1 < n2 entonces
// El menor ser n1 o n3
Si n1 < n3 entonces
Escribe El menor es , n1;
Sino
// n1 >= n3
Escribe El menor es , n3;
Fin si;
18
Sino
// n1 >= n2, debemos comparar n2 y n3. El menor ser n2 o n3
Si n2 < n3 entonces
Escribe El menor es , n2;
Sino
Escribe El menor es , n3;
Fin si;
Fin si;
Fin
si;
Fin
12.4 Algoritmo que lee como datos de entrada una fecha expresada en da (1..31), mes (1..12, y
ao y nos dice la fecha que ser el da siguiente. Se supondr que febrero tiene siempre 28 das.
Programa
UnDiaDespues;
Entorno
Entero
Entero
numDiasMes;
Inicio
Escribe Introduce Dia: ;
Lee dia;
Escribe Introduce Mes: ;
Lee mes;
Escribe Introduce Ao: ;
Lee Ao;
Si mes = 2 entonces
numDiasMes = 28;
Sino
Si mes=4 o mes=6 o mes=9 o mes=11 entonces
// Meses de 30 das: Abrir, Junio, Sept. Nov.
NumDiasMes = 30;
Sino
// El resto tiene 31 das
NumDiasMes = 31;
Fin si;
Fin si;
Si dia > numDiasMes entonces
mes = mes + 1; dia = 1;
Si mes > 12 entonces
anyo = anyo + 1;
mes = 1;
Fin si;
Fin si;
Escribe Un da despus es: , dia, / , mes, / , anyo;
Fin;
19
UnDiaDespues;
numDiasMes;
Inicio
Escribe Introduce Dia: ;
Lee dia;
Escribe Introduce Mes: ;
Lee mes;
Escribe Introduce Ao: ;
Lee Ao;
Si mes = 2 entonces
Si
// Es bisiesto
numDiasMes
Sino
numDiasMes
Fin Si;
= 29;
= 28;
Sino
Si
NumDiasMes = 30;
Sino
// El resto tiene 31 das
NumDiasMes = 31;
Fin si;
Fin si;
// Filtramos si la fecha es correcta
Si dia>=1 y dia<=numDiasMes y Mes >= 1 y mes <= 12 entonces
Si
mes = mes + 1;
dia = 1;
Si mes > 12 entonces
anyo = anyo + 1;
mes = 1;
Fin si;
Fin si;
Escribe
Escribe
La fecha es incorrecta ;
Sino
Fin
Fin;
Si;
20
Algoritmo que lee dos nmeros enteros, positivos y distintos y nos dice si el mayor es mltiplo
del menor o, lo que es lo mismo, si el menor es divisor del mayor.
Programa
EsDivisorElMenor;
Entorno
Entero
Entero
Inicio
Escribe Introduce 2 nmeros ;
Lee n1, n2;
// Buscamos el mayor y el menor
Si n1 > n2 entonces
mayor = n1;
menor = n2;
Sino
mayor = n2;
menor = n1;
Fin si;
Si mayor % menor = 0 entonces
Escribe Mayor, es mltiplo de , menor;
Sino
Escribe No existe ninguna relacin entre los nmeros ;
Fin si;
Fin
Algoritmo que calcula la edad de una persona recibiendo como datos de entrada la fecha de
nacimiento, y la fecha actual, ambas en tres variables.
Programa
EdadEnAnyos;
Entorno
Entero
Entero
Entero
Inicio
Escribe Introduce Fecha nacimiento: ;
Lee d_n, m_n, a_n;
Escribe Fecha actual: ;
Lee d_a, m_a, a_a;
/* La edad de una persona ser igual al ao
21
Realizar un algoritmo que muestre por pantalla los nmeros pares menores de 100.
Programa ParesMenoresQue100;
Entorno
Entero
n;
Inicio
n = 2;
Mientras
n<100 hacer
Escribe n;
n = n + 2;
Fin
Mientras;
Fin
Otra forma
Programa
ParesMenoresQue100;
Entorno
Entero
n;
Inicio
n = 1;
Mientras
Si
n<100 hacer
n % 2 = 0 entonces
Escribe
n;
Fin si;
n = n + 1;
Fin
Mientras;
Fin
Realizar un algoritmo que muestre por pantalla los nmeros mltiplos de 5 menores que 10000.
Programa
MultDe5Menor1000;
Entorno
Entero
n;
Inicio
n = 5;
Mientras
n<1000 hacer
Escribe n;
n = n + 5;
Fin
Fin
Mientras;
22
16.3 Algoritmo que lea un nmero por teclado e imprima por pantalla todos los nmeros positivos
menores que N
Programa
ListaNumeros;
Entorno
Entero
n;
Entero
i; // Contador
Inicio
Escribe Introduce un nmero: ;
Lee n;
i = 1;
Mientras i < n hacer
Escribe i;
i = i + 1;
Fin Mientras;
Fin
Otra forma
Programa
Entorno
ListaNumeros;
Entero n;
Inicio
Escribe Introduce un nmero: ;
Lee n;
Mientras n>1 hacer
n = n - 1;
Escribe n;
Fin Mientras;
Fin
Algoritmo que lee una secuencia de 10 nmeros y obtiene e imprime cuantos hay positivos,
negativos y nulos.
Programa
CuentaNumeros;
Entorno
Entero
n;
Entero
Entero
Inicio
nPos=0;
nNeg=0;
nNulos=0;
i = 0;
Mientras i<10 hacer
23
CuentaNumeros;
Entorno
Entero
n;
Entero
Booleano
hayNegativos; // switch
Inicio
hayNegativos = false; // suponemos que no hay negativos
/* El menor de los posibles, cualquier nmero de los ledos por teclado ser mayor que este */
mayor = -9999999;
hacer
Escribe Introduce un nmero: ;
Lee n;
Si n <> 0 entonces // Procesamos el nmero ledo
Si n < 0 entonces
hayNegativos = true;
// Se ha encontrado un negativo
FinSi;
Si n > mayor entonces
/* Se ha encontrado un nmero mayor que el actual, lo seleccionamos como mayor */
mayor = n
Fin si;
Fin si;
Mientras n <> 0;
Escribe El mayor es : , mayor;
Si hay Negativos entones
24
Escribe
Fin
Si;
Fin
Otra forma, no presuponemos ningn nmero como mayor
Programa
CuentaNumeros;
Entorno
Entero
n;
Entero
Booleano
hayNegativos; // switch
Booleano
esPrimeraVez;
Inicio
hayNegativos = false;
esPrimeraVez = true;
hacer
Escribe Introduce un nmero: ;
Lee n;
Si n <> 0 entonces
// Procesamos el nmero ledo
Si n < 0 entonces
hayNegativos = true;
// Se ha encontrado un negativo
FinSi;
Si esPrimeraVez o n > mayor entonces
/* Se ha encontrado un nmero mayor
mayor = n;
esPrimeraVez
Fin
Fin
= false;
si;
si;
Mientras n <> 0;
Si esPrimeraVez entonces
Escribe
Escribe
El mayor es : , mayor;
Sino
Fin si;
Si hay Negativos entones
Escribe
Fin
Fin
Si;
25
Algoritmo que lee un nmero entero positivo N y calcula e imprime el factorial de N!. Si lee un
nmero negativo indica con un mensaje que no es posible la operacin.
Programa
Factorial;
Entorno
Entero
Entero
Entero
n;
i; // Contador
resultado;
Inicio
Escribe Introduce un nmero: ;
Lee n;
Si n < 0 entonces
Escribe No existe factorial de un nmero negativo ;
Sino resultado = 1;
// Inicializamos el acumulador
i = 1;
Mientras i < n hacer
resultado = resultado * i;
Fin Mientras;
Escribe El factorial de , n, es , resultado;
Fin si;
Fin
Algoritmo que lee un nmero X y otro entero positivo N y calcula la N-sima potencia de X (sin
utilizar el operador de potencia).
Programa
Potencia;
Entorno
Entero
Entero
Entero
x, n;
i; // Contador
resultado;
Inicio
Escribe Introduce un nmero: ;
Lee x;
Escribe Introduce la potencia: ;
Lee n;
Si n < 0 entonces
Escribe No se calcular potencias negativas ;
Sino
resultado = 1;
// Inicializamos el acumulador
i = 1;
Mientras i < n hacer
resultado = resultado * x;
Fin Mientras;
Escribe x, elevado a , n, es , resultado;
Fin si;
Fin
26
Algoritmo que obtenga el producto de dos nmeros enteros positivos mediante sumas sucesivas.
/* Ampliamos el problema para permitir nmeros negativos */
Programa
Producto;
Entorno
Entero
n1, n2;
Entero
i; // Contador
Entero
resultado;
Booleano
resultadoNeg;
Inicio
Escribe
Lee
n1;
Escribe
Lee
/*
Introduce un nmero 1: ;
Introduce un nmero 2: ;
n2;
Debemos considerar el caso de que alguno de los nmeros sea negativo, lo mejor es poner los dos
nmeros en positivo y luego considerar el signo. Vamos a evitar usar el operador de producto * /
resultadoNeg
//
Si
n1 < 0 entonces
n1
= -n1;
Finsi
Si
n2 < 0 entonces
n2
= -n2;
Finsi
resultado
//
i
= 0;
Inicializamos el acumulador
= 1;
Mientras
i < n2 hacer
resultado
Fin
Si
= resultado + n1;
Mientras;
resultadoNeg entonces
resultadoNeg = -resultadoNeg;
// Cambiamos de signo
Fin
si;
Escribe
Fin
Fin
si;
27
Algoritmos que obtenga el cociente y el resto de dos nmeros enteros positivos mediante restas.
/* Ampliamos el problema para permitir nmeros negativos */
Programa
Division;
Entorno
Entero dividendo, divisor;
Entero resto, cociente;
Booleano resultadoNeg;
Inicio
Escribe Introduce dividendo: ;
Lee dividendo;
Escribe Introduce divisor: ;
Lee divisor;
/* Debemos considerar el caso de
que alguno de los nmeros sea negativo, lo mejor es poner los dos
nmeros en positivo y luego considerar el signo. Vamos a evitar usar el operador de producto * */
resultadoNeg = (dividendo < 0 o divisor < 0) y no (dividendo < 0 y divisor < 0);
// Convertimos los nmeros a positivo
Si dividendo < 0 entonces
dividendo = - dividendo;
Finsi
Si divisor < 0 entonces
divisor = - divisor;
Finsi
cociente = 0;
// Inicializamos el acumulador
resto = dividendo;
Mientras divisor < resto hacer
resto = resto = divisor;
cociente = cociente + 1;
Fin Mientras;
Si resultadoNeg entonces
cociente = -cociente;
// Cambiamos de signo
Fin si;
Escribe dividendo, entre , divisor, da , cociente , con resto , resto;
Fin
Algoritmo que lee tres nmeros A, B, C, y los imprime en orden creciente e indica si fueron
introducidos en ese orden.
/*
Programa
NumerosOrdenAscendente;
Entorno
Entero
28
Inicio
Escribe Introduce tres nmeros: ;
Lee n1, n2, n3;
Si n1 > n2 entonces
Si n2 > n3 entonces
Escribe n3, n2, n1;
Sino // n2 <= n3
Si n1 > n3 entonces
Escribe n2, n3, n1;
Sino
Escribe n2, n1, n3;
Fin si;
Fin si;
Sino // n1 <= n2
Si n2 < n3 entonces
Escribe n1, n2, n3;
Sino // n2 >= n3 y n2 >= n1
Si n1 > n3 entonces
Escribe n3 n1, n2;
Sino
Escribe n1, n3, n2;
Escribe Los nmeros se introdujeron ordenados ;
Fin si;
Fin si;
Fin si
Fin;
Algoritmo que lea un nmero por teclado y nos diga si es primo.
/*
Un nmero es primo cuando solo es divisible por si mismo y por el 1. Para saber si un nmero es primo
debemos dividirlo sucesivamente por sus posibles divisores (nmeros menor que l) y si encontramos algn
divisor diremos que el nmero NO es primo, es caso contrario ser un nmero primo. */
Programa
NumeroPrimo;
Entorno
Entero n, cont;
Booleano esPrimo; // Variable que indicar si es primo o no
Inicio
Escribe Introduce un nmero: ;
Lee n;
esPrimo = true;
// suponemos que el nmero es primo
cont = 2; // Empezamos dividiendo por 2
/* Iremos dividiendo el nmero por sus posibles divisores hasta que encontremos un divisor, y por tanto
el nmero deje de ser primo o hasta que acabemos la lista de posibles divisores (los menores que l)
*/
29
Para resolver este algoritmo es necesario realizar una aproximacin descendente. Partiendo del hecho de que
ya sabemos calcular si un nmero es o no primo, damos por supuesta esta operacin e intentamos resolver
el problema.
Lee
i
n;
nPrimos
mientras
i < n hacer
Si
Escribe i;
nPrimos = nPrimos + 1;
Fin
/*
i
Si;
Fijarse que est fuera del si, se incrementa siempre independiente de que el nmero i sea primo o no */
= i + 1;
Fin
Mientras;
Una vez tenemos la 1 aproximacin tan solo tenemos que introducir el cdigo que nos indica si un nmero es
primo donde proceda.
Cuando veamos funciones, veremos que est tarea es trivial. */
Programa
NPrimerosPrimos;
Entorno
// Variables utilizadas para ver si el nmero i es primo
Entero i, cont;
Booleano esPrimo; // Variable que indicar si es primo o no
// Variables utilizadas para ir probando los nmeros
Entero nPrimos;
Entero n;
30
//
Inicio
Escribe Introduce un nmero: ;
Lee n;
i = 1; // Contador que avanza por los nmeros
nPrimos = 0; // N de primos que hemos visualizado
mientras i < n hacer
/* Si i es un numero primo entonces */
esPrimo = true; // suponemos que el nmero es primo
cont = 2; // Empezamos dividiendo por 2
Mientras cont < i y esPrimo hacer
// Mientras cont < i y esPrimo=true hacer Hace los mismo
Si n % cont entonces
esPrimo = false; // Se ha encontrado un divisor
Fin si;
Fin mientras;
Si esPrimo entonces
Escribe i;
nPrimos = nPrimos + 1;
Fin Si;
/* Fijarse que est fuera del si, se incrementa siempre independiente
o no */
i
Fin
= i + 1;
Mientras;
Fin;
Algoritmo lea un nmero N y muestre por pantalla los nmeros primos menores que N.
/*
Para resolver este algoritmo es necesario realizar una aproximacin descendente. Partiendo del hecho de que
ya sabemos calcular si un nmero es o no primo, damos por supuesta esta operacin e intentamos resolver
el problema.
Lee
n;
Para
Si
Escribe
Fin
Fin
i;
Si;
Para;
Una vez tenemos la 1 aproximacin tan solo tenemos que introducir el cdigo que nos indica si un nmero es
primo donde proceda.
Cuando veamos funciones, veremos que est tarea es trivial.
Este algoritmo a diferencia del anterior saca los nmeros primos menores que N, mientras que el otro sacaba
los N primeros primos.
La diferencia es la siguiente, para N=5
N primeros : 1,2,3,5,7
< N : 1,2,3,5 */
31
NPrimerosPrimos;
Entorno
// Variables utilizadas para ver si el nmero i es primo
Entero i, cont;
Booleano esPrimo;
// Variable que indicar si es primo o no
// Variables utilizadas para ir probando los nmeros
Entero n;
// Enterio i; Declarada previamente
Inicio
Escribe Introduce un nmero: ;
Lee n;
Para i=1 hasta n-1
/* Si i es un numero primo entonces */
esPrimo = true; // suponemos que el nmero es primo
cont = 2; // Empezamos dividiendo por 2
Mientras cont < i y esPrimo hacer
Si n % cont entonces
esPrimo = false; // Se ha encontrado un divisor
Fin si;
Fin mientras;
Si esPrimo entonces
Escribe i;
Fin Si;
Fin Para;
Fin;
Algoritmo que calcula e imprime los nmeros perfectos menores que 1000. (Un nmero es perfecto
si la suma de sus divisores, excepto l mismo, es igual al propio nmero.).
/*
Para resolver este algoritmo es necesario realizar una aproximacin descendente. Damos por supuesta la
operacin es numero perfecto que ms adelante desarrollaremos
Para
Si
Escribe
Fin
Fin
n;
Si;
Para;
sumaDivisores
Para
= 0;
Si
n % i = 0 entonces
sumaDivisores
= sumaDivisores + n;
32
Fin
Fin
Si
si;
Para
sumaDivisores = n entonces
//
Fin
De
N es un nmero perfecto
si;
nuevo unimos las dos soluciones y ya tenemos resuelto el problema
*/
Programa
NumerosPerfectos;
Entorno
Entero
n i, sumaDivisores;
Inicio
Para n=1 hasta 999 hacer
/* Si n es numero perfecto entonces */
sumaDivisores = 0;
Para i=1 hasta n-1 hacer
Si n % i = 0 entonces
sumaDivisores = sumaDivisores + n;
Fin si;
Fin Para
Si sumaDivisores = n entonces
// N es un nmero perfecto
Escribe n;
Fin Si;
Fin Para;
Fin;
Algoritmo que evala un polinomio de grado N. Los datos de entrada son el valor de la variable
y los coecientes.
Programa
EvaluaPolinomio;
Entorno
Entero
Entero
Inicio
coef, grado, x, i;
valorPol;
Lee grado;
Escribe Valor de X: ;
Lee x; // Acumulador en el que guardaremos el valor del polinomio
valorPol = 0;
Para i=x hasta 0 incremento -1
Escribe Introduce coeciente de grado ( , i, ): ;
Lee coef;
valorPol = valorPol + coef * x ^ i;
Fin para;
Escribe El valor del polinomio es: , valorPol;
Fin
TablaMultiplicar;
Entero n, i;
Inicio
Escribe Introduce un nmero: ;
Lee n;
Para i=1 hasta 10
Escribe
Fin
Para;
Fin
Algoritmo que lee un nmero entero y positivo N y escribe la lista de sus divisores.
Programa
ListaDivisores;
Entorno
Entero n, i;
Inicio
Escribe Introduce un nmero: ;
Lee n;
Para i=1 hasta n
Si
n % i = 0 entonces
Escribe
Fin
Fin
i;
Si;
Para;
Fin
Algoritmo que lee un nmero entero y positivo y calcula y escribe la suma de sus divisores.
Programa
Entorno
SumaDivisores;
Entero n, i;
Entero
suma;
Inicio
Escribe Introduce un nmero: ;
Lee n;
Suma=0;
Para i=1 hasta n
Si
n % i = 0 entonces
Suma
Fin
= suma + i;
Si;
Fin Para;
Escribe La suma de sus divisores es: , suma;
Fin
33
34
Algotimo que lee un nmero entero y positivo N y escribe los N primeros trminos de la sucesin
de Fibonacci. La sucesin se caracteriza porque cada trmino es igual a la suma de sus dos
anteriores, dandose por denicin el primero (0) y el segundo (1).
a1 = 0 a2= 1 an = an-1 + an-2
Programa
Fibonacci;
Entorno
Entero
Entero
Entero
an, an_1;
suma; // an + an_1
n, cont;
Inicio
Escribe Introduce un nmero: ;
Lee n;
// Casos base, triviales
Si n > 0 entonces
Escribe 0 ;
Fin si;
Si n > 1 entonces
Escribe 0 ;
Fin si;
// Comenzamos bucle
an_1 = 0;
an = 1;
/* Los dos casos anteriores ya se han visualizado, por eso empezamos en 3 */
Para cont=3 hasta n
Suma = an + an_1;
// Calculamos el trmino siguiente Escribe suma;
// Los dos ltimos trminos avanzan una posicin
an_1 = an;
an = suma;
Fin Para;
Fin
Captulo 2
main()
{
35
36
/*este
es un comentario*/
TIPOS DE DATOS
Cuando usamos un programa es muy importante manejar datos. En C podemos almacenar los datos en
variables. El contenido de las variables se puede ver o cambiar en cualquier momento. Estas variables pueden
ser de distintos tipos dependiendo del tipo de dato que queramos guardar en ellas. No es lo mismo guardar un
nombre que un nmero. Hay que recordar tambin que la memoria del ordenador es limitada, as que cuando
guardamos un dato, debemos usar slo la memoria necesaria
Identicadores Son nombres dados a constantes, variables y funciones. El identicador esta formado por una
secuencia de una o ms letras, dgitos y el caracter de subrayado. El primer caracter de un identicador siempre
debe ser una letra o el caracter de subrayado, en estos identicadores (nombres de variables) se debe tener gran
cuidado, ya que el C hace diferencia entre maysculas y minsculas. Por ejemplo, Max, max y MAX son tres
identicadores diferentes.
Constantes Las constantes son un valor que una vez jado por el compilador, no cambia durante la ejecucin
del programa. El C indica al programa que se trata de una constante usando la directiva #dene. Por ejemplo.
#dene pi 3.1416 Esta linea dene a la variable pi como una constante con el valor 3.1416, este valor de las
constantes puede ser un numero o bien una cadena de caracteres.
Tipos de Datos
Tipo Int
En una variable de este tipo se almacenan nmeros enteros (sin decimales). El rango de valores que admite
es -32767 a 32767. Cuando denimos una variable lo que estamos haciendo es decirle al compilador que nos
reserve una zona de la memoria para almacenar datos de tipo int. Hay que decirle al compilador que queremos
crear una variable y hay que indicarle de qu tipo. Si esta declaracin se hace antes del main(), esto indica que
la variable ser una variable global, o sea que se usar en todo el main() y en el resto de funciones. Mientras
que si se declara dentro del main(), esto indica que la variable ser una variable local, o sea, slo para la funcin
main().
Por ejemplo.
int valor;
main()...
Esta expresin declara una variable global de nombre "valor" y de tipo entero.
main()
{
oat valor;
}
Esta expresin declara una variable local de nombre "valor" y de tipo oat (coma otante)
Tipo Char
Las variables de tipo char sirven para almacenar caracteres. Los caracteres se almacenan en realidad como
nmeros del 0 al 255. Los 128 primeros (0 a 127) son el ASCII estndar. El resto es el ASCII extendido y
depende del idioma y del ordenador. Para declarar una variable char solo escribimos: "char nombre;" y listo, ya
existe una variable "nombre" que almacenar datos de tipo caracter.
Tipo Float
En este tipo de variable podemos almacenar nmeros decimales, no slo enteros como en los anteriores. El
rango de posibles valores es del 3.4 E-38 al 3.4 E+38. Para declarar un oat, de forma similar, escribimos: "oat
prom;" y con esto hemos declarado una variable de nombre "prom" que tendr un dato de tipo oat o coma
otante.
37
Tipo double
En las variables tipo double se almacenan nmeros reales, estos tiene el rango de 1.79769 E-308 a 1.79769
E+308. Al igual que las anteriores para declararla escribimos: "double num;" y tenemos una variable de nombre
"num" que aceptar datos tipo double.
Modicador Unsigned Este modicador (que signica sin signo) modica el rango de valores que puede
contener una variable. Slo admite valores positivos. Este modicador se usa as: "unsigned int total;" esto
declara un variable de nombre "total", de tipo entero positivo.
scanf
Al utilizar la palabra scanf, nosotros podemos hacer que el usuario introduzca datos por el teclado. El uso
de scanf es de la siguiente manera: "scanf(" %i", &num);" esta ltima expresin indica al programa que se debe
solicitar un nmero entero ( %i, es una especicacin de formato y esto lo puedes ver en la seccin de operadores
y manipuladores), luego se indica el nombre de la variable en la que se va a guardar el dato, ste (el nombre)
precedido por el signo &, que indica al programa la direccin de sta variable.
38
printf
El uso de printf, es similar al de scanf, lo que scanf hace para leer una variable, printf lo hace para imprimirla.
De esta manera podemos imprimir en pantalla, ya sea un mensaje o el valor contenido en una variable. La sintaxis
de printf es as: "printf(" %d", num);" esta sentencia lo que hace es imprimir el valor de la variable num en
el lugar donde aparece el " %d". El printf nos sirve tambin para mandar a imprimir en pantalla un mensaje
as: "printf("Bienvenidos al mundo de C")" esto impirmir en pantalla: Bienvenidos al mundo de C Nota: Para
hacer uso de estas funciones, es necesario incluir la directiva o archivo de cabecera stdio.h, esto se hace de la
siguiente manera: "#include ", as queda incluida ste archivo y se podr proceder con el programa.
Ahora haremos uso de lo que hemos aprendido para hacer un programa.
include stdio.h
main()
{
int x;
printf("Bienvenidos al mundo de C\n");
printf("Introduzca un valor entero ");
scanf(" %i", &x);
printf("\nEl valor que introdujo fue %i",x);
return 0;
}
Ahora explicaremos lo que hace: Primero se declara una variable de tipo entero y de nombre x. Despus se
manda a imprimir en pantalla el mensaje "Bienvenidos al mundo de C", el "\n" que sigue es para dar un salto
de lnea en el programa, si no lo pusieramos el siguiente mensaje aparecera pegado al anterior. Luego se imprime
"Introduzca un valor entero", para que el usuario pueda introducir un valor por medio del teclado y se manda
a guardar este valor a la variable antes declarada. Despues se imprime un mensaje y el valor de la variable.
Como pueden ver, no es tan difcil. La expresin "return 0" es una instruccin. Como vern, toda funcin debe
retornar un valor, como no queremos que nuestra funcin main devuelva nada, entonces le decimos que retorne
0.
La salida del programa anterior sera: Bienvenidos al mundo de C Introduzca un valor entero 25 (por ejemplo
25)
El valor que introdujo fue 25
getch y getche
Si lo que queremos es que el usuario introduzca un caracter por el teclado usamos las funciones getch y
getche. Estas esperan a que el usuario introduzca un carcter por el teclado. La diferencia entre getche y getch
es que la primera saca por pantalla la tecla que hemos pulsado y la segunda no.
Por ejemplo.
#
int
include stdio.h
main()
{
char letra;
printf( "Introduzca una letra: " );
letra = getche();
printf( "\nLa letra que introdujo es: %c", letra );
return 0;
}
39
La salida del programa anterior sera: Introduzca una letra:N La letra que introdujo es: N
Ahora hagamos el mismo programa con getch():
#
int
include stdio.h
main()
{
char letra;
printf( "Introduzca una letra: " );
letra = getch();
printf( "\nLa letra que introdujo es: %c", letra );
return 0;
}
La salida del programa anterior sera: Introduzca una letra: La letra que introdujo es: N
Se debe tener en cuenta, aunque no se haga en estos ejemplos, que el archivo de cabecera stdio.h debe estar
entre los signos <>, de lo contrario se producira un error en el programa.
OPERADORES (MANIPULADORES)
Los operadores son smbolos que indican como son manipulados los datos. Estos operadores se pueden
clasicar en: aritmticos, lgicos, relacionales, de asignacin, de manejo de bits y otros.
Operadores de Asignacin
Estos operadores son los que nos sirven para darle (asignarle) un valor a una variable. Este valor lo podemos
teclear manualmente o bien puede ser el valor de otra variable.
Por ejemplo.
x=5; /*Esto mete un valor directamente*/
x=a; /*Esto asigna el valor de otra variable*/
Operadores Aritmticos
Los operadores aritmticos son aquellos que sirven para realizar operaciones tales como suma, resta, divisin y
multiplicacin. Con ellos podemos calcular el resto o mdulo de una divisin entera, o bien podemos incrementar
o disminuir el valor de las variables.
Por ejemplo.
include stdio.h
main()
{
int x=7;
int y;
int z=2; /*Como vern es posible declarar e iniciar la variable al mismo tiempo*/
printf("El valor de x es: %i\n", x);
y=x+z; /*Asigna el valor de una suma*/
x++; /*Incrementa el valor de x en uno*/
printf("Los valores de x, y, z son %i, %i, %i", x,y,z);
return 0;
}
La salida a este programa sera:
El valor de x es: 7 Los valores de x, y, z son 8, 9, 2
40
Operadores Lgicos
Estos operadores son los que nos permiten hacer comparaciones entre dos o ms variables. Estos operadores
son los que nos permitirn decidir en una sentencia condicional que veremos ms adelante.
Por ejemplo.
x<7&&t==4; /*Esta lnea devuelve 1, si x es menor que 7 "y" t es igual a 4*/
Operadores Binarios
Estos permiten ver el contenido de las variables como valores binarios. Utiles en el acceso a bits individuales
en memoria, tales como la memoria de pantalla para mostrar grcos. Las funciones de estos operadores se
describen en la tabla, y se ocupan similarmente en los programas.
Operador Sizeof
Existe un operador muy utilizado que es el sizeof. Este operador nos devuelve el tamao en bytes de una
variable. De esta manera no tenemos que preocuparnos en recordar o calcular cuanto ocupa. Adems el tamao
de una variable cambia de un compilador a otro, es la mejor forma de asegurarse. Se usa poniendo el nombre
de la variable despus de sizeof y separado de un espacio.
Por
int
ejemplo.
main()
{
oat variable;
printf( "Tamao de la variable: %f\n", sizeof variable );
}
Se debe tener gran cuidado al agrupar estos operadores, pues unas acciones se llevan a cabo antes que otras, esto
depende del nivel de precedencia que tenga el operador. Para esto se presenta una tabla, en la que se muestra
en orden descendente la prioridad de los mismos.
OPERADORES DE ASIGNACION
Operador
Operacin
Mdulo o resto de una divisin entera, los operandos tienen que ser enteros
++
OPERADORES LOGICOS
Operador
&&
Operacin
AND , en espaol Y. Da como resultado el valor lgico 1, si ambos operadores son distintos de cero
||
NOT, en espaol NO. El resultado es cero si el operando tiene un valor distinto de cero
OPERADORES DE RELACION
Operador
Operacin
<
>
<=
>=
==
!=
41
OPERADORES BINARIOS
Operador
Operacin
&
>>
<<
OPERADORES DE ASIGNACION
Operador
=
Operacin
Asignacin simple
*=
Multiplicacin ms asignacin
/=
Divisin ms asignacin
%=
Mdulo ms asignacin
+=
Suma ms asignacin
-=
Resta ms asignacin
<<=
>>=
&=
!=
^=
NIVELES DE PRECEDENCIA
Operador
( ) [ ]
~ ! & ++
* /%
+ << >>
< <= > >=
== !=
^
!
&&
||
= *= /= %= += -= &= ^= != <<= >>=
SENTENCIAS Y BUCLES
Hasta ahora los programas que hemos visto eran lineales. O sea que las instrucciones se ejecutaban en orden
y una sola vez. Pero resulta que muchas veces no es esto lo que queremos que ocurra. Lo que nos suele interesar
es que dependiendo de los valores de los datos se ejecuten unas instrucciones y no otras. O tambin puede que
queramos repetir unas instrucciones un nmero determinado de veces. Para esto estn las sentencia de control
de ujo.
Bucles
Los bucles nos ofrecen la solucin cuando queremos repetir una tarea un nmero determinado de veces.
Supongamos que queremos escribir 100 veces la palabra Bienvenido. Con lo que sabemos, tendramos que
escribir 100 veces la expresin "printf("Bienvenido\n");", sin embargo un ciclo for nos facilitara en grande esta
tarea. Estos bucles pueden ser: For (Para), While (Mientras), Do while(Hacer mientras).
El Bucle For:
Este bucle nos permite hacer un nmero nito de tareas, cuantas veces necesitemos. La sintaxis del for es la
siguiente:
42
for([valor
inical];[condicin];[incremento])
{
...sentencias
...sentencias
}
La parte del valor inicial, es el valor con el que empieza la variable contadora, o la variable que nos va a decir
cuando salir. La condicin, es la que nos determinar el nmero de veces que se llevarn a cabo las instrucciones
que siguen. Estas sentencias se realizarn mientras la condicin estipulada se cumpla. El incremento, es el
numero en que vamos a incrementar la variable contadora.
El Bucle While:
La sintaxis del bucle while es la siguiente:
while
( condicin )
{
bloque
de instrucciones a ejecutar
}
La condicin de este bucle, al igual que el for, es la que indica cuantas veces se ejecutarn las instrucciones.
Estas (las instrucciones) se ejecutarn mientras la condicin estipulada se cumpla.
El Bucle Do While
La sintaxis de este bucle es:
do
{
instrucciones
a ejecutar
}
while
( condicin );
En este bucle,las instrucciones se llevan a cabo al menos una vez, puesto que la condicin se evala al nal del
mismo; a diferencia del while o el for, que si la condicin inicial no se cumple, entonces las instrucciones no se
cumplen ni una sola vez. La condicin es similar a las antes descritas.
Sentencias Condicionales
Hasta aqu hemos visto cmo podemos repetir un conjunto de instrucciones las veces que deseemos. Pero
ahora vamos a ver cmo podemos controlar totalmente el ujo de un programa. Dependiendo de los valores de
alguna variable se tomarn unas acciones u otras.
Sentencia if
La palabra if signica si (condicional), su sintaxis es como sigue:
if
( condicin )
{
instrucciones
}
a ejecutar
43
Cuando se cumple la condicin entre parntesis se ejecuta el bloque inmediatamente siguiente al if (instrucciones
a ejecutar).
Por ejemplo.
include stdio.h
main()
{
int x=2;
if(x==2)
printf("X
return 0;
es 2");
}
El programa anterior analiza la condicin de que si x es igual a dos, entonces se imprime el mensaje "X es 2".
Sentencia if-else
En el if, si la condicin no se cumpla, entonces las instrucciones no se ejecutaban y el programa nalizaba o
segua con las siguientes instrucciones. En el if-else, (si-sino) si no se cumple la condicin entonces se realizarn
otras instrucciones. Su sintaxis es la siguiente:
if
( condicin )
{
bloque
bloque
}
else
{
}
Por ejemplo.
int
main()
{
int a;
printf( "Introduce un nmero " );
scanf( " %i", &a );
if ( a==8 )
{
printf ( "El nmero que introdujo es ocho.\n" );
}
else
{
printf ( "El nmero que introdujo no es ocho"\n" );
}
}
44
En este ejemplo se manda a solicitar un nmero, si el nmero introducido es ocho, entonces manda un mensaje
positiv, mientras que si el numero no es ocho manda un mensaje negativo.
Se pueden agrupar varios if, o sea que si se cumple uno, luego se pregunta otra condicin y as sucesivamente.
A esto se le llama if anidados. A la vez es posible analizar ms de una condicin siempre y cuando estas vayan
ligadas con su respectivo operador.
Por ejemplo.
int
main()
{
int a;
printf( "Introduce un nmero " );
scanf( " %i", &a );
if ( a<10 )
{
printf ( "El nmero introducido era menor de 10.\n" );
}
else
if ( a>10 && a<100 )
{
printf ( "El nmero est entre 10 y 100"\n" );
}
else if ( a>100 )
{
printf( "El nmero es mayor que 100\n" );
}
En este ejemplo lo que se hace es pedir un numero, se analiza una condicin y si se cumple se mand un mensaje,
sino, se analiza otra condicin y se manda a imprimir un mensaje para cada caso.
Sentencia switch
La sentencia switch, analiza una condicin y dependiendo del valor escoge entre varias opciones para realizar
distintas instrucciones y si la opcin no est establecida, simplemente ejecuta una opcin por defecto. La sintaxis
para el switch es:
switch
( variable )
{
case
case
opcin 1:
cdigo
break;
opcin 2:
cdigo
break;
default:
cdigo
break;
}
Ahora miremos, el switch analiza el valor de "variable" luego si variable tiene el valor "opcion 1" entonces
se ejecutan las instrucciones que siguen, y as sucesivamente. Es importante poner al nal de cada grupo de
instrucciones la palabra "break", la que indica al programa que ah terminan las sentencias. Se pueden poner
cuantas opciones se desee y al nal es recomendable (aunque no exigido) que se ponga un grupo de instrucciones
que se ejecuten si la variable toma un valor que no se ha denido. Esta ltima se pone despues de la palabra
"default".
45
Sentencia goto
La sentencia goto (ir a) nos permite hacer un salto a la parte del programa que deseemos. En el programa
podemos poner etiquetas, estas etiquetas no se ejecutan. Es como poner un nombre a una parte del programa.
Estas etiquetas son las que nos sirven para indicar a la sentencia goto dnde tiene que saltar.
Por ejemplo.
int
main()
{
printf( "Lnea 1\n" );
goto linea3; /* Le decimos al goto que busque la etiqueta linea3 */
printf( "Lnea 2\n" );
linea3: /* Esta es la etiqueta */
printf( "Lnea 3\n" );
}
Como resultado tenemos: Lnea 1 Lnea 3 O sea que el printf de la linea 2 no se ejecuta, puesto que lo saltamos
con el goto.
ARREGLOS O MATRICES
Un array (arreglo) es un conjunto de variables del mismo tipo, las cuales se diferencian entre s por su
posicin (ubicacin). Para ilustrarlo, supongamos una tabla dividida en celdas y cada celda es una variable en
particular, por supuesto que todas las celdas son del mismo tipo y pertenecen a la misma tabla.
Los arreglos se declaran as:
tipo_dato nombre_arreglo [tamao];
El tipo de dato, puede ser uno de los denidos anteriormente.
El nombre del arreglo es cualquier identicador vlido y el tamao es el tamao que deseamos que tenga el
arreglo, este siempre debe ir entre corchetes. Los datos del arreglo empiezan a introducirse por el dato [0].
Por ejemplo.
int temp[24]; /* Con esto tenemos declaradas 24 variables de tipo entero*/
Para poder introducir los datos en un arreglo debemos recorrerlo, o sea ir a cada celda del arreglo y ah
escribir el dato. Para esto se usa frecuentement un ciclo for de la siguiente manera:
for(
{
printf( "Temperatura de las %i: ", hora );
scanf( " %i", &temp[hora] );
media += temp[hora];
}
Los arreglos al igual que las otras variables se pueden inicializar, para hacerlo se prosigue de la siguiente manera:
int temperaturas[24] = { 15, 18, 20, 23, 22, 24, 22, 25, 26, 25, 24, 22, 21, 20, 18, 17, 16, 17, 15, 14, 14, 14,
13, 12 };
De esta manera hemos inicializado el arreglo con los valores correspondientes. Asi temperatura[0] tiene el
valor 15, temperatura[1] tiene el valor 18 y as sucesivamente.
Punteros a Arreglos
Aqu tenemos otro de los importantes usos de los punteros, los punteros a arrays. Estos estn ntimamente
relacionados. Para que un puntero apunte a un array se puede hacer de dos formas, una es apuntando al primer
elemento del array:
Por ejemplo.
int *puntero;
int temperaturas[24];
puntero = &temperaturas[0];
46
#include
int main()
{
int i;
int temp[24];
for( i=0; i<24; i++ )
{
printf( "La direccin del elemento %i es %p.\n", i, &temp[i] );
}
}
Nota: Recuerda que %p sirve para imprimir en pantalla la direccin de una variable en hexadecimal.
El resultado es:
La direccin del elemento 0 es 4c430.
La direccin del elemento 1 es 4c434.
La direccin del elemento 2 es 4c438.
La direccin del elemento 3 es 4c43c. ...
La direccin del elemento 21 es 4c484.
La direccin del elemento 22 es 4c488.
La direccin del elemento 23 es 4c48c
Paso de un Arreglo a una funcin
En C no podemos pasar un array entero a una funcin. Lo que tenemos que hacer es pasar un puntero al
array. Con este puntero podemos recorrer el array, as:
int
sumar( int *m )
{
int suma, i;
suma = 0;
for( i=0; i<10; i++ )
{
suma += m[i];
}
return suma;
}
int
main()
{
int contador;
int matriz[10] = { 10, 11, 13, 10, 14, 9, 10, 18, 10, 10 };
for( contador=0; contador<10; contador++ )
printf( " %3i\n", matriz[contador] );
printf( "+ \n" );
printf( " %3i", sumar( matriz ) );
}
Este programa tiene alguna cosilla adicional como que muestra toda la matriz en una columna. Adems se usa
para imprimir los nmeros %3i. El 3 indica que se tienen que alinear los nmeros a la derecha, as queda ms
elegante. Como he indicado no se pasa el array, sino un puntero a ese array.
47
Por
int
ejemplo.
main()
{
char
nombre[20];
printf(
scanf(
printf(
}
Vemos cosas curiosas como por ejemplo que en el scanf no se usa el smbolo &. No hace falta porque es un
array, y ya sabemos que escribir el nombre del array es equivalente a poner &nombre[0]. Tambin puede llamar
la atencin la forma de imprimir el array. Con slo usar %s ya se imprime todo el array. Ya veremos esto ms
adelante.
Inicializacin
int
de una Cadena
main()
{
char
nombre[] = "Gorka";
printf(
printf(
}
Como vemos la inicializacin es parecida a la de un arreglo, solo que aqui se escribe toda la frase para inicializarla.
Cuando inicializamos una cadena el C automticamente introduce como ultimo elemento el "\0" que indica n
de la cadena. Esto sirve para que a la hora de imprimir el C, sepa cuando debe parar de imprimir. Es importante
no olvidar que la longitud de una cadena es la longitud del texto ms el smbolo de n de cadena. Por eso cuando
denamos una cadena tenemos que reservarle un espacio adicional.
strlen
Su sintaxis es:
strlen(char *s)
Esta funcin nos devuelve el nmero de caracteres que tiene la cadena (sin contar el '\0'). Si no utilizaramos
esta funcin, para poder saber cuantos elementos tiene una cadena tendramos que recorrerla con un puntero.
48
strcpy
Su sintaxis es:
char *strcpy(char *cadena1, const char *cadena2);
Esta funcin copia el contenido de cadena2 en cadena1. cadena2 puede ser una variable o una cadena directa
(por ejemplo "hola"). Debemos tener cuidado de que la cadena destino (cadena1) tenga espacio suciente para
albergar a la cadena origen (cadena2).
strcat
Su sintaxis es.
char *strcat(char *cadena1, const char *cadena2);
Esta funcin copia la cadena2 al nal de la cadena1. Como siempre tenemos que asegurarnos que la variable
en la que metemos las dems cadenas tenga el tamao suciente.
sprintf
Su sintaxis es:
int sprintf(char *destino, const char *format, ...);
Funciona de manera similar a printf, pero en vez de mostrar el texto en la pantalla lo guarda en una variable
(destino). El valor que devuelve (int) es el nmero de caracteres guardados en la variable destino.
strcmp
Su sintaxis es:
int strcmp(const char *cadena1, const char *cadena2);
Compara cadena1 y cadena2. Si son iguales devuelve 0. Un nmero negativo si cadena1 va antes que cadena2
y un nmero positivo si es al revs.
Ejemplo.
#include
stdio.h
#include
string.h
int
main()
{
char nombre1[]="Gorka";
char nombre2[]="Pedro";
char nombre_completo[50];
char nombre[]="Gorka";
char apellido[]="Urrutia";
sprintf( nombre_completo, " %s %s", nombre, apellido );
printf( "El nombre completo es: %s.\n", nombre_completo );
printf( " %i", strcmp(nombre1,nombre2));
}
En este ejemplo vemos claramente el uso de las funciones antes mencionadas, para la salida es mejor probarlo.
Entrada de Cadenas por el Teclado
scanf
Hemos visto en captulos anteriores el uso de scanf para nmeros, ahora es el momento de ver su uso con
cadenas. Scanf almacena en memoria (en un buer) lo que vamos escribiendo. Cuando pulsamos ENTER lo
analiza, comprueba si el formato es correcto y por ltimo lo mete en la variable que le indicamos. Scanf toma
una palabra como cadena. Usa los espacios para separar variables. Asi si introducimos una palabra, damos
espacio y escribimos otra, scanf solo almacenar la primea palabra. Es importante siempre asegurarse de que
no vamos a almacenar en cadena ms letras de las que caben. Para ello debemos limitar el nmero de letras que
le va a introducir scanf.
49
gets
Esta funcin nos permite introducir frases enteras, incluyendo espacios. Su sintaxis es: char *gets(char
*buer);
Almacena lo que vamos tecleando en la variable buer hasta que pulsamos ENTER. Si se ha almacenado
algn caracter en buer le aade un '\0' al nal y devuelve un puntero a su direccin. Si no se ha almacenado
ninguno devuelve un puntero NULL.
Por
int
ejemplo.
main()
{
char cadena[30];
char *p;
printf( "Escribe una palabra: " );
ush( stdout );
p = gets( cadena );
if (p) printf( "He guardado: \" %s\" \n", cadena );
else printf( "No he guardado nada!\n" );
}
Qu son los buer?
#include
int
stdio.h
main()
{
char ch;
char nombre[20],
apellido[20],telefono[10];
printf( "Escribe tu nombre: " );
scanf( " %[A-Z]s", nombre );
printf( "Lo que recogemos del scanf es: %s\n", nombre );
printf( "Lo que haba quedado en el buer: " );
while( (ch=getchar())!='\n' )
printf( " %c", ch );
}
En este ejemplo el [A-Z] lo que hace es que solamente lee las letras maysculas. Y la salida sera: Escribe tu
nombre: GORka Lo que recogemos del scanf es: GOR Lo que haba quedado en el buer: ka
Arreglos de Cadenas
Un array de cadenas puede servirnos para agrupar una serie de mensajes. Por ejemplo todos los mensajes
de error de un programa. Luego para acceder a cada mensaje basta con usar su nmero.
Por ejemplo.
#include
stdio.h
#include
string.h
int
{
50
char *errores[] = {
"No se ha producido ningn error",
"No hay suciente memoria",
"No hay espacio en disco",
"Me he cansado de trabajar"
};
printf( "Error nmero %i: %s.\n", errnum, errores[errnum] );
exit( -1 );
}
int
main()
{
error(
}
2 );
FUNCIONES
Las funciones son de una gran utilidad en los programas. Nos ayudan a que sean ms legibles y ms cortos.
Con ellos estructuramos mejor los programas.
Una funcin sirve para realizar tareas concretas y simplicar el programa. Nos sirve para evitar tener
que escribir el mismo cdigo varias veces. Ya hemos visto en el curso algunas funciones como printf, gotoxy,
scanf y clrscr. Estas funciones estn denidas en una biblioteca (la biblioteca estndar de C). No tenemos que
preocuparnos de ella porque el compilador se encarga de ella automticamente. Sin embargo nosotros tambin
podemos denir nuestras propias funciones. Pocas veces se ve un programa un poco complejo que no use
funciones. Una de ellas, que usamos siempre, es la funcin main.
Una funcin tiene la siguiente estructura:
tipo_de_variable nombre_de_la_funcin( argumentos )
{
denicin de variables;
cuerpo de la funcin;
return 0;
}
El nombre de la funcin debe ser un nombre de identicador vlido. Este se utiliza para llamar la funcin
dentro del programa.
El tipo_de_variable: Cuando una funcin se ejecuta y termina debe devolver un valor. Este valor puede ser
cualquiera de los tipos de variables que hemos visto en el captulo de Tipos de datos (int, char, oat, double), o
un tipo de dato denido por el usuario. El valor que devuelve la funcin suele ser el resultado de las operaciones
que se realizan en la funcin, o si han tenido exito o no. Aqui tambin podemos usar el tipo void, el cual nos
permite que podamos devolver cualquier tipo de variable o ninguna.
Denicin de variables: Dentro de la funcin podemos denir variables que slo tendrn validez dentro de
la propia funcin. Si declaramos una variable en una funcin no podemos usarla en otra. Cuerpo de la funcin:
Aqu es donde va el cdigo de la funcin.
Return: Antes hemos indicado que la funcin devuelve un valor. La sentencia return se usa para esto. El
dato que se pone despues de return es el dato que se devuelve. Puede ser una constante o una variable. Debe
ser del mismo tipo que tipo_de_variable.
Argumentos: Estos son variables que se pasan como datos a una funcin. Deben ir separados por una coma.
Cada variable debe ir con su tipo de variable. Las funciones deben denirse antes de ser llamadas.
Ejemplo.
#include
stdio.h
#include
conio.h
51
void
{
clrscr();
printf( "La pantalla est limpia\n" );
return; /* No hace falta devolver ningn valor, mucha gente ni siquiera pone este return */
}
int
main()
{
prepara_pantalla();/*
Llamamos a la funcin */
}
Este ejemplo aunque no devuelve ningn valor, nos muestra como se dene y llama una funcin.
Ejemplo.
#include
stdio
#include
conio.h
int
{
int mayor; /* Esta funcin dene su propia variable, esta variable slo se puede usar aqu */
if ( a>b )
mayor
= a;
mayor
= b; return mayor;
else
}
int
main()
{
int num1, num2;
int resultado;
printf( "Introduzca dos nmeros: " );
scanf( " %i %i", num1, num2 );
resultado = compara( num1, num2 );/* Recogemos el valor que devuelve la funcin en resultado */
printf( "El mayor de los dos es %i\n", resultado );
}
En este ejemplo vemos la denicin y llamada de la funcin, adems que podemos ver que devuelve un valor.
Este valor es la comparacin de dos numeros.
Las variables las podemos denir en cualquier parte del programa, aunque es recomendable que se denan
antes de que se llamen. Hay quienes, primero las declaran al inicio del programa y al nal del mismo las denen,
pero esto se puede hacer de la manera que nosotros querramos.
52
Argumentos de un Programa
Ya sabemos cmo pasar argumentos a una funcin. La funcin main tambin acepta argumentos. Sin embargo
slo se le pueden pasar dos argumentos. Veamos cules son y cmo se declaran: int main( int argc, char *argv[]
)
El primer argumento es argc (argument count). Es de tipo int e indica el nmero de argumentos que se le
han pasado al programa. El segundo es argv (argument values). Es un array de strings (o puntero a puntero
a char). En el se almacenan los parmetros. Normalmente (como siempre depende del compilador) el primer
elemento (argv[0]) es el nombre del programa con su ruta. El segundo (argv[1]) es el primer parmetro, el tercero
(argv[2]) el segundo parmetro y as hasta el nal. A los argumentos de main se les suele llamar siempre as, no
es necesario pero es costumbre.
Ejemplo.
#include stdio.h
int main(int argc,char *argv[])
{
int i;
for( i=0 ; i
printf( "Argumento %i: %s\n", i, argv[i] );
}
Si llamamos al programa argumentos.c y lo compilamos (argumentos.exe) podramos teclear "c:\programas>
argumentos hola amigos" y tendramos como salida:
Argumento 0: c:\programas\argumentos.exe
Argumento 1: hola
Argumento 2: amigos
ESTRUCTURAS
Supongamos que queremos hacer una agenda con los nmeros de telfono de nuestros amigos. Necesitaramos
un array de Cadenas para almacenar sus nombres, otro para sus apellidos y otro para sus nmeros de telfono.
Esto puede hacer que el programa quede desordenado y difcil de seguir. Y aqu es donde vienen en nuestro
auxilio las estructuras. Para denir una estructura usamos el siguiente formato:
struct nombre_de_la_estructura
{
campos de estructura;
};
Por ejemplo.
struct cliente
{
char nombre[30];
char apellido[40];
char telefono[10];
char edad;
};
Con esto hemos creado una estructura llamada cliente la que almacena 4 datos de tipo cadena de caracteres
que son: el nombre y el apellido del cliente, telefono y edad del mismo.
Ahora que tenemos la estructura denida, es necesario declarar una variable del tipo de la estructura, esto
se hace as: struct cliente cliente1;
Ahora tenemos una variable del tipo cliente. Para acceder a cada uno de sus miembros usamo un punto ".".
As para acceder al nombre simplemente escribimos "cliente1.nombre".
Ejemplo.
53
include stdio.h
struct
char
char
char
char
nombre[30];
apellido[40];
telefono[10];
edad;
};
struct
int
amigo amigo;
main()
{
printf( "Escribe el nombre del amigo: " );
ush( stdout );
scanf( " %s", &amigo.nombre );
printf( "Escribe el apellido del amigo: " );
ush( stdout );
scanf( " %s", &amigo.apellido );
printf( "Escribe el nmero de telfono del amigo: " );
ush( stdout );
scanf( " %s", &amigo.telefono );
printf( "El amigo %s %s tiene el nmero: %s.\n", amigo.nombre, amigo.apellido, amigo.telefono );
}
En este ejemplo se puede usar un gets, en vez del scanf, debido a que alguien puede introducir un nombre
separado por espacios, el cual no sera aceptado por scanf.
Arreglos de Estructuras
Supongamos ahora que queremos guardar la informacin de varios clientes. Con una variable de estructura
slo podemos guardar los datos de uno. Para manejar los datos de ms gente (al conjunto de todos los datos de
cada persona se les llama REGISTRO) necesitamos declarar arrays de estructuras.
Esto se hace de la siguiente manera:
struct cliente cliente1[NUMERO_ELEMENTOS];
Ahora para acceder a un elemento determinado simplemente hacemos cliente1[0].nombre.
Ejemplo.
#include
#dene
struct
stdio.h
ELEMENTOS 3
estructura_amigo
{
char nombre[30];
char apellido[40];
char telefono[10];
int edad;
};
struct
estructura_amigo amigo[ELEMENTOS];
54
int
main()
{
int num_amigo;
for( num_amigo=0; num_amigo
{
printf( "\nDatos del amigo nmero %i:\n", num_amigo+1 );
printf( "Nombre: " );
ush( stdout );
gets(amigo[num_amigo].nombre);
printf( "Apellido: " );
ush( stdout );
gets(amigo[num_amigo].apellido);
printf( "Telfono: " );
ush( stdout );
gets(amigo[num_amigo].telefono);
printf( "Edad: " );
ush( stdout );
scanf( " %i", &amigo[num_amigo].edad );
while(getchar()!='\n');
}
/*
for(
{
num_amigo=0; num_amigo
printf(
printf(
printf(
printf(
}
}
En este ejemplo debemos introducir los datos de 3 amigos y podemos ver la manera que se imprimen los datos.
55
Punteros a Estructuras
Cmo no, tambin se pueden usar punteros con estructuras. Vamos a ver como funciona esto de los punteros
con estructuras. Primero de todo hay que denir la estructura de igual forma que hacamos antes. La diferencia
est en que al declara la variable de tipo estructura debemos ponerle el operador '*' para indicarle que es un
puntero.
Es importante recordar que un puntero no debe apuntar a un lugar cualquiera, debemos darle una direccin
vlida donde apuntar. No podemos por ejemplo crear un puntero a estructura y meter los datos directamente
mediante ese puntero, no sabemos dnde apunta el puntero y los datos se almacenaran en un lugar cualquiera.
Ejemplo.
#include
struct
stdio.h
estructura_amigo {
char nombre[30];
char apellido[40];
char telefono[10];
int edad;
};
struct
estructura_amigo amigo = {
"Juanjo",
"Lopez",
"592-0483",
30
};
struct
int
estructura_amigo *p_amigo;
main()
{
p_amigo = &amigo;
printf( " %s tiene ", p_amigo->apellido );
printf( " %i aos ", p_amigo->edad );
printf( "y su telfono es el %s.\n" , p_amigo->telefono );
}
Ahora que denimos el puntero y le indicamos que apunte a amigo, podemos accesar los datos de la estructura
mediante el puntero. La diferencia es que ahora no se accesa con ".", sino que ahora se utiliza "->". Accesando
a estos datos podemos leer e imprimirlos.
56
include stdio.h
dene ELEMENTOS 3
struct
amigo
{
char nombre[30];
char apellido[40];
char telefono[10];
int edad;
};
struct
amigo amigo[] = {
amigo *p_amigo;
main()
{
int num_amigo;
p_amigo = amigo; /* apuntamos al primer elemento del array */
/* Ahora imprimimos sus datos */
for( num_amigo=0; num_amigo
{
printf( "El amigo %s ", p_amigo->nombre );
printf( " %s tiene ", p_amigo->apellido );
printf( " %i aos ", p_amigo->edad );
printf( "y su telfono es el %s.\n" , p_amigo->telefono );
/* y ahora saltamos al siguiente elemento */ p_amigo++;
}
}
Ahora que sabemos accesar a los datos de un arreglo de estructuras por medio de punteros, entonces podemos
introducir datos y tambin mandarlos a imprimir.
57
Estructuras Anidadas
Es posible crear estructuras que tengan como miembros otras estructuras. Esto tiene diversas utilidades, por
ejemplo tener la estructura de datos ms ordenada. Por ejemplo, si queremos una estructura de clientes de un
banco con sus datos y tambien la fecha del ltimo pago, se podra hacer de la siguiente manera:
struct ultimopago{
int dia;
int mes;
int ao;
};
Y ahora la estructura total, incluyendo la de la fecha del ltimo pago.
struct cliente{
char nombre[25];
char apellido[25];
oat saldo;
struct ultimopago pago;
}
cliente1;
De esta manera tenemos una variable "cliente1" del tipo cliente con una estructura anidada.
PUNTEROS
Los punteros son una de las ms potentes caractersticas de C, pero a la vez uno de sus mayores peligros. Los
punteros nos permites acceder directamente a cualquier parte de la memoria. Esto da a los programas C una
gran potencia. Sin embargo son una fuente ilimitada de errores. Un error usando un puntero puede bloquear
el sistema y a veces puede ser difcil detectarlo. Otros lenguajes no nos dejan usar punteros para evitar estos
problemas, pero a la vez nos quitan parte del control que tenemos en C.
Memoria
Cuando hablamos de memoria nos estamos reriendo a la memoria RAM del ordenador. Son unas pastillas
que se conectan a la placa base y nada tienen que ver con el disco duro. El disco duro guarda los datos
permanentemente (hasta que se rompe) y la informacin se almacena como archivos. Nosotros podemos decirle
al ordenador cundo grabar, borrar, abrir un documento, etc. La memoria RAM en cambio, se borra al apagar
el ordenador. La memoria Ram la usan los programas sin que el usuario de stos se de cuenta.
Direcciones de Variables
Al declarar una variable estamos diciendo al ordenador que nos reserve una parte de la memoria para
almacenarla. Cada vez que ejecutemos el programa la variable se almacenar en un sitio diferente, eso no lo
podemos controlar, depende de la memoria disponible y otros factores misteriosos. Puede que se almacene en el
mismo sitio, pero es mejor no arse. Dependiendo del tipo de variable que declaremos el ordenador nos reservar
ms o menos memoria. Como vimos en el captulo de tipos de datos cada tipo de variable ocupa ms o menos
bytes.
Cuando naliza el programa todo el espacio reservado queda libre. Existe una forma de saber qu direcciones
nos ha reservado el ordenador. Se trata de usar el operador & (operador de direccin).
Para mostrar la direccin de la variable usamos %p en lugar de %i, sirve para escribir direcciones de punteros
y variables. El valor se muestra en hexadecimal. No hay que confundir el valor de la variable con la direccin
donde est almacenada la variable. La variable 'a' est almacenada en un lugar determinado de la memoria, ese
lugar no cambia mientras se ejecuta el programa. El valor de la variable puede cambiar a lo largo del programa,
lo cambiamos nosotros. Ese valor est almacenado en la direccin de la variable. El nombre de la variable es
equivalente a poner un nombre a una zona de la memoria. Cuando en el programa escribimos 'a', en realidad
estamos diciendo, "el valor que est almacenado en la direccin de memoria a la que llamamos 'a'.
QUE ES UN PUNTERO?
Un puntero es una variable un tanto especial. Con un puntero podemos almacenar direcciones de memoria.
En un puntero podemos tener guardada la direccin de una variable.
58
Muchas veces los punteros se usan para guardar las direcciones de variables. Vimos en el captulo Tipos de
Datos que cada tipo de variable ocupaba un espacio distinto. Por eso cuando declaramos un puntero debemos
especicar el tipo de datos cuya direccin almacenar.
Para declarar un puntero se utiliza un asterisco, para indicar que se trata de un puntero.
Por ejemplo.
char *punt;
Esto declara una variable puntero que almacenara la direccion de una variable de tipo char. Cuando un
puntero contiene la direccion de una variable, se dice que ese puntero apunta a esa variable.
La sintaxis general para declarar un puntero es como sigue:
tipo_de_dato *nombre_del_puntero;
Utilidad de un Puntero
Los punteros tienen muchas utilidades, por ejemplo nos permiten pasar argumentos (o parmetros) a una
funcin y modicarlos. Tambin permiten el manejo de cadenas y de arrays. Otro uso importante es que nos
permiten acceder directamente a la pantalla, al teclado y a todos los componenetes del ordenador. Nos deben
dejar tambin la posibilidad de acceder a esas posiciones de memoria. Para acceder a ellas se usa el operador *,
que no hay que confundir con el de la multiplicacin.
Ejemplo.
#
int
include stdio.h
main()
{
int numero;
int *punt;
numero = 43;
punt = №
printf( "Direccin de numero = %p, valor de numero = %i\n", &numero, *punt );
}
Se puede observar en el ejemplo que para accesar al valor de numero usamos *punt en vez de numero. Esto es
porque punt apunta a numero y *punt nos permite accesar al valor al que apunta punt.
Usando un puntero podemos apuntar a una variable y con *puntero vemos o cambiamos el contenido de
esa variable. Un puntero no slo sirve para apunta a una variable, tambin sirve para apuntar una direccin de
memoria determinada.
Punteros como argumentos de funciones Hemos visto en el captulo de funciones cmo pasar parmetros y
cmo obtener resultados de las funciones (con los valores devueltos con return). Pero tiene un inconveniente, slo
podemos tener un valor devuelto. Ahora vamos a ver cmo los punteros nos permites modicar varias variables
en una funcin.
Ejemplo.
#
int
include stdio.h
suma( int *a, int b )
{
int c;
c = *a + b;
*a = 0;
return c;
}
int
{
main()
59
int var1,
var2;
var1 = 5;
var2 = 8;
printf( "La suma es: %i y a vale: %i\n", suma(&var1, var2), var1 );
}
En este ejemplo podemos ver como con un puntero podemos cambiar el valor de una variable, a traves de ellos
podemos accesar y cambiar los datos. Tambien los podemos utilizar como argumentos de funciones, tal es el
caso del ejemplo anterior.
malloc y free
Existen varias funciones para la asignacin dinmica de la memoria, pero las dos funciones bsicas son malloc
y free.
La funcin malloc sirve para reservar una parte de la memoria, y devuelve la direccin del comienzo de esa
parte. Esta direccin podemos almacenarla en un puntero y as podemos acceder a la memoria reservada. La
sintaxis de malloc, es como sigue:
puntero = (tipo_de_variable *) malloc( nmero de bytes a reservar );
puntero: es una variable tipo puntero que almacena la direccin del bloque de memoria reservado. Puede
ser un puntero a char, int, oat,... (tipo_de_variable *): es lo que se llama un molde. La funcin malloc nos
reserva una cierta cantidad de bytes y devuelve un puntero del tipo void (que es uno genrico). Con el molde
le indicamos al compilador que lo convierta en un puntero del mismo tipo que la variable puntero. Esto no es
necesario en C, ya que lo hace automticamente, aunque es aconsejable acostumbrarse a usarlo.
Una vez reservada la memoria y guardada su direccin en un puntero podemos usar ese puntero como hemos
visto hasta ahora. Si no haba suciente memoria libre malloc devolver el valor NULL. El puntero por tanto
apuntar a NULL. Es muy importante comprobar siempre si se ha podido reservar memoria o no comprobando
el valor de puntero. Esto se puede hacer de la siguiente manera: if(puntero)
Si hay memoria suciente entonces se cumple la condicion, de lo contrario es falso.
Cuando ya no necesitemos ms el espacio reservado debemos liberarlo, es decir, indicar al ordenador que
puede destinarlo a otros nes. Si no liberamos el espacio que ya no necesitamos corremos el peligro de agotar
la memoria del ordenador. Para ello usamos la funcin free.
La sintaxis de free es:
free( puntero );
Ejemplo.
#
int
include stdio.h
main()
{
int bytes;
char *texto;
printf("Cuantos bytes quieres reservar: ");
scanf(" %i",&bytes);
texto = (char *) malloc(bytes);
/* Comprobamos si ha tenido xito la operacin */
60
if
{
(texto)
}
else
printf("No
}
En este ejemplo vemos claramente la asignacion y liberacion de la memoria, despues de preguntar cuanta
memoria se desea reservar, se comprueba si se reservo y luego se procede a las instrucciones de lo contrario
inmediatamente manda el mensaje "No se ha podido reservar memoria".
ARCHIVOS
Lectura de un archivo
Todas las funciones de entrada/salida estndar usan el puntero *FILE para conseguir informacin sobre el
archivo abierto. Este puntero no apunta al archivo sino a una estructura que contiene informacin sobre l. Esta
estructura incluye entre otras cosas informacin sobre el nombre del archivo, la direccin de la zona de memoria
donde se almacena el chero, tamao del buer. Para poder utilizar este puntero se debe incluir el archivo de
cabecera stdio.h.
Para abrir el archivo utilizamos la funcion fopen. La sintaxis de esta funcion es asi:
FILE *fopen(const char *nombre_chero, const char *modo);
El nombre del archivo se puede indicar directamente o usando una variable. El archivo se puede abrir de
distintas formas, estas se muestran en la tabla.
Parametro
Modo
Crea un archivo nuevo y lo abre para escritura Si el archivo existe, borra su contenido
Abre un archivo (si no existe lo crea) para escritura El puntero se situa al nal del archivo, de forma que
Accion
Estos modicadores se pueden combinar con los parametros dados anteriormente para abrir el archivo en la
forma deseada. Ejemplo. wb+ Crea el archivo (o lo borra si existe) en modo binario para lectura y escritura. rt
Abre un archivo existente en modo texto para lectura.
Una cosa muy importante despus de abrir un chero es comprobar si realmente est abierto. El sistema no
es infalible y pueden producirse fallos: el chero puede no existir, estar daado o no tener permisos de lectura. Si
intentamos realizar operaciones sobre un puntero tipo FILE cuando no se ha conseguido abrir el chero puede
haber problemas. Por eso es importante comprobar si se ha abierto con xito. Si el chero no se ha abierto el
puntero chero (puntero a FILE) tendr el valor NULL, si se ha abierto con xito tendr un valor distinto de
NULL.
Por ejemplo.
if
(chero==NULL)
{
printf( "No se puede abrir el chero.\n" );
exit( 1 );
}
Este es un ejemplo para probar si el archivo se abrio con exito. Si no se ha abierto con exito lo mas conveniente
es salir del programa, esto se puede hacer con una funcion exit.
61
Leer un archivo
Para leer un archivo podemos utilizar la funcin getc, que lee los caracteres uno a uno. Se puede usar tambin
la funcin fgetc. Adems de estas dos existen otras funciones como fgets, fread que leen ms de un carcter. La
sintaxis de la funcion getc y fgetc es asi: int getc(FILE *archivo);
Ejemplo.
letra = getc( chero );
En este ejemplo se toma un caracter de archivo, lo almacena en letra y el puntero se coloca en el siguiente
caracter.
Comprobar el n de un Archivo
Cuando entramos en el bucle while, la lectura se realiza hasta que se encuentre el nal del chero. Para
detectar el nal del chero se pueden usar dos formas: con la funcin feof() comprobando si el valor de letra es
EOF.
Esta funcin comprueba si se ha llegado al nal de chero en cuyo caso devuelve un valor distinto de 0. Si
no se ha llegado al nal de chero devuelve un cero.
Ejemplo.
#
int
include stdio.h
main()
{
FILE *chero;
char letra;
chero = fopen("origen.txt","r");
if (chero==NULL)
{
printf( "No se puede abrir el chero.\n" );
exit( 1 );
}
printf( "Contenido del chero:\n" );
letra=getc(chero);
while (feof(chero)==0)
{
printf( " %c",letra );
letra=getc(chero);
}
if
(fclose(chero)!=0)
printf(
}
En este ejemplo se aplica todo lo que hemos dicho anteriormente, se abre el archivo para lectura.
Cerrar un Archivo
Una vez realizadas todas las operaciones deseadas sobre el archivo hay que cerrarlo. Es importante no olvidar
este paso pues el archivo podra corromperse. Al cerrarlo se vacan los buers y se guarda el archivo en disco. Un
archivo se cierra mediante la funcin fclose(chero). Si todo va bien fclose devuelve un cero, si hay problemas
devuelve otro valor.
62
Escritura de un Archivo
En esta etapa se utilizan las mismas funciones que para la lectura, la diferencia es que ahora se debe abrir
para escritura.
Para la escritura en un archivo usamos la funcion putc, la cual tiene la siguiente sintaxis: int putc(int c,
FILE *chero);
Aqui c contiene el carcter que queremos escribir en el chero y el puntero chero es el chero sobre el que
trabajamos. De esta forma vamos escribiento en un chero el contenido de otro chero.
Ejemplo.
#
int
include stdio.h
main()
{
FILE *origen, *destino;
char letra;
origen=fopen("origen.txt","r");
destino=fopen("destino.txt","w");
if (origen==NULL || destino==NULL)
{
printf( "Problemas con los cheros.\n" );
exit( 1 );
}
letra=getc(origen);
while (feof(origen)==0)
{
putc(letra,destino);
printf( " %c",letra );
letra=getc(origen);
}
if (fclose(origen)!=0)
printf( "Problemas al cerrar el chero origen.txt\n" );
if (fclose(destino)!=0)
printf( "Problemas al cerrar el chero destino.txt\n" );
}
Aqui se puede observar la apertura del archivo, luego la lectura del origen y la escritura en el destino.
fread y fwrite
Estas funciones nos permiten tratar con datos de cualquier tipo, incluso con estructuras dentro de un archivo,
al contrario de las pasadas en las que solo sirven para manejar caracteres y cadenas.
63
fwrite
Fwrite nos permite escribir en un chero. Esta funcin tiene la siguiente sintaxis:
size_t fwrite(void *buer, size_t tamano, size_t numero, FILE *pchero);
buer: variable que contiene los datos que vamos a escribir en el chero. tamano: el tamao del tipo de dato
a escribir. Puede ser un int, un oat, una estructura, ... Para conocer su tamao usamos el operador sizeof.
numero: el nmero de datos a escribir. pchero: El puntero al chero sobre el que trabajamos.
Ejemplo.
#include
struct
char
char
char
}
nombre[20];
apellido[20];
telefono[15];
registro;
int
main()
{
FILE *chero;
chero = fopen( "nombres.txt", "a" );
do
{
printf( "Nombre: " );
ush(stdout);
gets(registro.nombre);
if (strcmp(registro.nombre,""))
{
printf( "Apellido: " );
ush(stdout);
gets(registro.apellido);
printf( "Telfono: " );
ush(stdout);
gets(registro.telefono);
fwrite( registro, sizeof(registro), 1, chero );
}
}
while (strcmp(registro.nombre,"")!=0);
fclose( chero );
}
En este ejemplo guardamos los datos personales mediante fwrite usando la estructura registro. Abrimos el chero
en modo 'a', para que los datos que introducimos se aadan al nal del chero. Una vez abierto entramos en
un bucle do-while mediante el cual introducimos los datos. Los datos se van almacenando en la variable registro
(que es una estructura). Cuando ya tenemos todos los datos de la persona los escribimos en el archivo con la
funcion fwrite, la que tiene la siguiente sintaxis: fwrite( registro, sizeof(registro), 1, chero );
En donde: registro - es la variable (en este caso una estructura) que contiene la informacin a meter al
chero. sizeof(registro) - lo utillizamos para saber cul es el nmero de bytes que vamos a guardar, el tamao
en bytes que ocupa la estructura. 1 - indica que slo vamos a guardar un elemento. Cada vez que se recorre el
bucle guardamos slo un elemento. chero - el puntero FILE al chero donde vamos a escribir.
fread
64
La funcin fread se utiliza para sacar informacin de un Archivo, su sintaxis es: size_t fread(void *buer,
size_t tamano, size_t numero, FILE *pchero);
Siendo buer la variable donde se van a escribir los datos ledos del chero archivo. El valor que devuelve la
funcin indica el nmero de elementos de tamao 'tamano' que ha conseguido leer.
Ejemplo.
include stdio.h
struct
{
char
char
char
}
nombre[20];
apellido[20];
telefono[15];
registro;
int
main()
{
FILE *chero;
chero = fopen( "nombres.txt", "r" );
while (!feof(chero))
{
if (fread( registro, sizeof(registro), 1, chero ))
{
printf( "Nombre: %s\n", registro.nombre );
printf( "Apellido: %s\n", registro.apellido);
printf( "Telfono: %s\n", registro.telefono);
}
}
fclose( chero );
}
En este ejemplo observamos la utilidad de las funciones antes mencionadas.
fseek y ftell
fseek
La funcin fseek nos permite situarnos en la posicin que queramos de un chero abierto. Cuando leemos
un chero hay un 'puntero' que indica en qu lugar del chero nos encontramos. Cada vez que leemos datos del
chero este puntero se desplaza. Con la funcin fseek podemos situar este puntero en el lugar que deseemos. La
sintaxis de fseek es asi: int fseek(FILE *pchero, long desplazamiento, int modo);
pchero es un puntero de tipo FILE que apunta al chero con el que queremos trabajar. desplazamiento
son las posiciones (o bytes) que queremos desplazar el puntero. Este desplazamiento puede ser de tres tipos
dependiendo del valor de modo:
SEEK_SET
SEEK_CUR
SEEK_END
Estas tres constantes estn denidas en el chero . Como curiosidad se indican a continuacin sus deniciones:
#dene SEEK_SET 0
#dene SEEK_CUR 1
#dene SEEK_END 2
Si se produce algn error al intentar posicionar el puntero, la funcin devuelve un valor distinto de 0. Si
todo ha va bien el valor devuleto es un 0.
Ejemplo.
65
include stdio.h
main()
{
FILE *chero;
long posicion;
int resultado;
chero = fopen( "origen.txt", "r" );
printf( "Qu posicin quieres leer? " );
ush(stdout);
scanf( " %D", &posicion );
resultado = fseek( chero, posicion, SEEK_SET );
if (!resultado)
printf( "En la posicin %D est la letra %c.\n", posicion, getc(chero) );
else printf( "Problemas posicionando el cursor.\n" );
fclose( chero );
}
En este ejemplo se mostro el funcionamiento de fseek.
ftell
La funcin ftell es complementaria a fseek, devuelve la posicin actual dentro del chero. Su sintaxis es la
siguiente: long ftell(FILE *pchero); El valor que nos da ftell puede ser usado por fseek para volver a la posicin
actual.
fprintf y fscanf
Estas dos funciones trabajan igual que sus equivalentes printf y scanf. La nica diferencia es que podemos
especicar el chero sobre el que se desea operar. Las sintaxis de estas dos funciones son:
int fprintf(FILE *pchero, const char *formato, ...);
int fscanf(FILE *pchero, const char *formato, ...);
66
7. Dada una cantidad en pesos, obtener la equivalencia en dlares, asumiendo que la unidad cambiara
es un dato desconocido.
8. En un hospital existen tres reas: Ginecologa, Pediatra, Traumatologa. El presupuesto anual
del hospital se reparte conforme a la sig. tabla:
rea Porcentaje del presupuesto
Ginecologa 40 %
Traumatologa 30 %
Pediatra 30 %
Obtener la cantidad de dinero que recibir cada rea, para cualquier monto presupuestal.
9. Calcular el nmero de pulsaciones que una persona debe tener por cada 10 segundos de ejercicio,
si la formula es:
num. Pulsaciones = (220 - edad)/10
10. El dueo de una tienda compra un artculo a un precio determinado. Obtener el precio en que
lo debe vender para obtener una ganancia del 30 %.
11. Programa que convierte de metros a pies y pulgadas.
12. Leer un nmero y escribir el valor absoluto del mismo.
13. La presin, el volumen y la temperatura de una masa de aire se relacionan por la formula:
Masa = (presin * volumen)/(0.37 * (temperatura + 460))
14. Calcular el nuevo salario de un obrero si obtuvo un incremento del 25 % sobre su salario anterior.
15. Todos los lunes, mircoles y viernes, una persona corre la misma ruta y cronometra los tiempos
obtenidos. Determinar el tiempo promedio que la persona tarda en recorrer la ruta en una semana
cualquiera.
16. Tres personas deciden invertir su dinero para fundar una empresa. Cada una de ellas invierte
una cantidad distinta. Obtener el porcentaje que cada quien invierte con respecto a la cantidad total
invertida.
17. Un alumno desea saber cual ser su promedio general en las tres materias mas difciles que
cursa y cual ser el promedio que obtendr en cada una de ellas. Estas materias se evalan como se
muestra a continuacin:
La calicacin de Matemticas se obtiene de la sig. Manera:
Examen 80 %
Promedio de tareas 20 %
Examen 85 %
Promedio de tareas 15 %
18. Realizar un Programa que lea la entrada de 02 nmeros y muestre el doble producto del primero
menos la mitad del segundo.
19. Desarrollar un programa que permita capturar preguntas como (Edad, sueldo, y mascota favorita)
y al nal muestre los datos capturados en conjunto
20. Se desea obtener el precio total de la venta de un producto, conociendo el nmero de cajas
adquiridas por un cliente, el nmero de unidades que tiene caca caja, del precio por unidad y de la
tasa de impuesto.
21. Disee un programa que guarde y muestre la nota del examen nal de 3 alumnos
67
68
Captulo 3
Programacin en C#
C# (lase, en ingls C sharp, y en espaol C almohadilla) es un lenguaje de programacin que permite
el desarrollo de aplicaciones para Internet, para mviles y aplicaciones de propsito general. Inicialmente se
desarroll para programar en la plataforma .NET, pero dadas las caractersticas de esta y la estandarizacin
que se ha hecho de su estructura por parte de las principales entidades de estndares internacionales, se han
desarrollado otras plataformas que cumplen con dicha estructura y por lo tanto C# puede ser utilizado como
lenguaje de programacin en ellas. Entre estas plataformas se destaca el Proyecto MONO, desarrollado para
Linux y Mac.
El lenguaje C# es orientado a objetos y se ha creado basndose en la estructura de C y C++, especialmente
su sintaxis y potencia, y adoptando el estilo y metodologa de la programacin en Visual Basic. Sin embargo es
importante aclarar que C# no es el resultado de la evolucin directa de ninguno de estos lenguajes, sino que
ha sido creado desde cero, para programar sobre la plataforma .NET. Es un lenguaje que fue concebido con el
objetivo de programar esta plataforma y por lo tanto se puede decir que es el lenguaje natural de .NET.
La empresa Microsoft, creadora de C#, en un intento de superar a otras plataformas que estn imponindose
en el soporte a aplicaciones que trabajan en red, especialmente sobre Internet, decidi estandarizar la plataforma
.NET y con ella el lenguaje base de la misma, C#. Con esta decisin se ha logrado que Microsoft de a conocer
las especicaciones tanto de la plataforma como del lenguaje de programacin, y de esta manera permitir que
terceros desarrollen implementaciones de .NET para el mismo Windows o para sistemas operativos diferentes.
69
70
CAPTULO 3. PROGRAMACIN EN C#
La plataforma .NET
71
73
Para comenzar no entraremos en muchos detalles sobre la plataforma .NET, y evitar de esta manera confundir
al lector poco experimentado, con tecnicismos que cuando se tenga una mejor familiaridad se pueden abordar
con mayor propiedad.
.NET, en esencia es una librera de clases que contienen o encapsulan una gran cantidad de funciones que
trabajan sobre el sistema operativo. La caracterstica fundamental de este aspecto, es que dichas clases tienen
una estructura comn para todos los lenguajes que trabajen sobre esta plataforma. Esto trae como consecuencia
que una clase que sea programada en C#, podr ser heredada o utilizada en cualquier lenguaje de la plataforma,
como pueden ser Visual Basic .NET o JScript, para comenzar.
Desde la perspectiva del programador el aspecto ms importante, es que .NET pone a su disposicin un
marco o entorno de trabajo, llamado .NET Framework, el cual le permite acceder a una infraestructura dotada
con lenguajes de programacin como C#, Visual Basic .NET, C++ y JScript, y con la posibilidad de acceder
a innidad de servicios tiles para desarrollar cualquier tipo de aplicacin.
74
CAPTULO 3. PROGRAMACIN EN C#
75
77
El objetivo inicial de este curso es conocer los fundamentos bsicos de la programacin C# para aplicaciones
de propsito general en .NET, y no el manejo de una herramienta especica de software. Sin embargo, en el
transcurso del mismo, y para hacer ms fcil la tarea de programacin, se recomienda utilizar software asistente
que se encargue de administrar los detalles tcnicos repetitivos y nos permite concentrarnos en los detalles de
nuestro inters.
Para iniciar a programar en C# y .NET, tan solo se necesita el entorno de trabajo, conocido como .NET
Framework, el cual incluye la plataforma de desarrollo y ejecucin de las aplicaciones .NET. Actualmente est
a disposicin del pblico la versin 4.0 de este entorno, que puede ser descargada gratuitamente desde la pgina
de Microsoft, pero para efectos de este curso se utilizar la versin 2.0, para la cual existe mayor soporte
y documentacin. Sin embargo, se sugiere descargar el kit de desarrollo de software de Microsoft .NET 2.0,
que contiene adems del .NET Framework una serie de herramientas y archivos de ayuda tiles a la hora de
programar.
Se sugiere que las prcticas iniciales se programen utilizando nicamente un editor de texto sencillo, como
el Bloc de notas, y se realice la compilacin mediante la lnea de comandos. Esto con el n de que tengamos la
posibilidad de comprender al detalle aquellos aspectos que un entorno de desarrollo integrado, como el Visual
Studio, no nos permite observar, pero cuya comprensin y familiaridad resultan muy importantes a la hora de
desarrollar aplicaciones que requieren programacin avanzada.
78
CAPTULO 3. PROGRAMACIN EN C#
La lnea de comandos
79
81
Para compilar nuestras aplicaciones a travs de la lnea de comandos, lo primero que se debe hacer es
congurar adecuadamente este entorno. Cualquier aplicacin de .NET depende para su ejecucin de una serie
de libreras propias de la plataforma, las cuales le suministran la comunicacin necesaria con el sistema operativo.
Por lo tanto para compilar un archivo es necesario poner a disposicin del compilador las direcciones donde
posiblemente pueda encontrar algn componente que requiera o que se est utilizando en la aplicacin. Para
facilitar esta tarea vamos a denir algunas variables de entorno que facilitan el trabajo de indicar las direcciones
bsicas del framework .NET.
Lo primero que se debe crear es una carpeta, donde se guardarn los archivos fuente y sus correspondientes
compilados. Para facilitar la coherencia entre este escrito y las prcticas que se desarrollen se sugiere crear la
carpeta C:\CursoLP.
Para
evitar tener que crear manualmente las variables de entorno con las direcciones necesarias para el compilador, vamos a crear un archivo de procesamiento por lotes, *.BAT, que realice este trabajo en forma
rpida y automtica. Ejecute el Bloc de notas, copie las lneas siguientes y guarde el archivo en el directorio
C:\CursoLP, nombrndolo como cmdSharpLP.bat:
@echo o Echo Lnea de comandos para el compilador de .NET Framework 2.0 Echo.
rem Ejecute este archivo con la instruccin: %comspec % /k cmdSharpLP.bat
@SET DirFramework=C:\WINDOWS\Microsoft.NET\Framework
@SET VerFramework=v2.0.50727
@set PATH= %DirFramework %\v2.0; %DirFramework %\ %VerFramework %; %PATH %
@set LIBPATH= %DirFramework %\v2.0; %DirFramework %\ %VerFramework %; %LIBPATH %
cd C:\cursoLP
A continuacin abra la ventana Ejecutar (puede hacerse mediante la combinacin de teclas WINDOWS+R) y
ejecute la siguiente instruccin:
%comspec % /k c:\cscurso\cursoLP.bat
A continuacin debe cargarse la ventana de lnea de comandos congurada con las direcciones necesarias
para trabajar con los compiladores instalados con el framework .NET. Se debe repetir este ltimo paso siempre
que se desee abrir una nueva lnea de comandos para compilar un programa desarrollado en C#
public
class PrimerPrograma
{
static
void Main()
CAPTULO 3. PROGRAMACIN EN C#
82
{
System.Console.WriteLine("Hola
mundo C#...!");
}
}
Guarde el archivo en la carpeta de trabajo,CursoLP, y asigne el nombre ejemplo01.cs.
El compilador de C# se identica como csc.exe (C Sharp Compiler), y tiene una diversidad de opciones,
dependiendo del tipo de compilacin que se desee realizar. Para este caso, basta con ejecutar el compilador
seguido del nombre del archivo fuente que se desea compilar. Por defecto se genera un archivo ejecutable,
*.EXE.
La instruccin de compilacin es la siguiente:
> csc ejemplo01.cs
El siguiente grco muestra el resultado de la compilacin de ejemplo01.cs y posterior ejecucin del programa
generado.
83
84
CAPTULO 3. PROGRAMACIN EN C#
CAPTULO 3. PROGRAMACIN EN C#
86
Como se ha dicho, C# es un lenguaje de programacin orientada a objetos y todo en l son clases. La clase
es el concepto fundamental de esta metodologa de programacin y es quin identica a los componentes que
constituyen un programa. En un sencillo programa como el del ejemplo 1, el programador solo escribe una clase,
pero en la prctica existen muchas clases trabajando para permitir que el programa se ejecute. Todo programa
C# est constituido por ms de una clase, aunque el programador tan solo deba escribir una de ellas.
El ejemplo 1 muestra una estructura bsica de un sencillo programa que se ejecutar en una consola de
comandos, o al menos la parte que debe construir el programador, pero permite visualizar con detalle los
elementos esenciales que soportan a cualquier aplicacin de software, sin importar el entorno donde vaya a
ejecutarse.
public
class PrimerPrograma
{
static
{
}
void Main()
//
Instrucciones
}
La clase es algo as como la estructura o molde de un componente de software, y se dene con la palabra clave
class. El trmino public le informa al sistema que dicha clase y sus componentes estn disponibles para ser vistos
desde afuera del componente de software que la contiene, en este caso el propio programa.
El programa en s, observe, es una clase, pero no se puede perder de vista que en la prctica el programa
necesita otros componentes de software para poder ejecutarse, y lo ms seguro es que estos ltimos de alguna
manera dependan de una o ms clases. Cuando se ejecuta el programa, el sistema operativo a travs de la
plataforma de ejecucin, .NET, crea una instancia (para comenzar entindase, un componente de software
basado en ese molde) de esta clase e interpreta las ordenes contenidas en ella.
En este caso el nombre que se ha colocado a la clase, PrimerPrograma, es una cadena de texto tomado
arbitrariamente e indiferente a como se lo escriba, lo importante es tener en cuenta las reglas que la mayora
de lenguajes imponen a los nombres de sus elementos. Como regla general se ha establecido que los nombres de
los elementos de programacin deben iniciar por un carcter alfabtico (letra) o por una raya abajo (_). Sin
embargo, se sugiere no utilizar esta ltima forma de iniciar el nombre de un elemento, ya que le hace perder
esttica al contenido y sobre todo diculta su lectura por parte del programador. Adems, aunque no es un
requisito, es importante tener en cuenta las recomendaciones hechas por la documentacin del .NET Framework,
sobre la nomenclatura de los nombres asignados a los diferentes elementos que se utilizan en el desarrollo de un
programa, ya que permiten estandarizar los nombres utilizados en nuestras aplicaciones y en los componentes
que vayamos a agregar al mismo entorno de desarrollo. As, por ejemplo, para nombrar las clases se sugiere
identicadores que inicien por una letra mayscula, y cuando se requiera utilizar palabras compuestas, cada
palabra debe iniciar por mayscula, tales como: MiPrograma, ProgramaDibujo, NominaTrabajadoresEmpresa,
etc. No es correcto llamar a una clase, como: 5ProgramaDibujo, Programa#dibujo, programa-dibujo.
Adems, un buen programador debe manejar un estilo de escritura de cdigo que haga clara su interpretacin,
no solo por l mismo, sino por otras personas a quienes les puede interesar revisarlo. Como sugerencia de estilo,
la cual manejaremos en este escrito, se sugiere utilizar identicadores lo ms explicativos posible. Es mejor evitar
el uso de abreviaturas, ya que con el tiempo podemos olvidar su signicado y cuando el programador deba volver
a revisar su cdigo, despus de algunos meses o aos, le complicar su interpretacin. Talvez, despus de algn
tiempo, sea ms fcil interpretar para que sirva una clase llamada IdentidadTrabajador, que una con el nombre
CITra. Todo programa desarrollado en C# debe incluir un mtodo Main(), el cual le informa al compilador por
donde debe iniciar y tambin terminar un programa. Este mtodo o funcin siempre se dene antecedida de la
palabra clave static, la cual permite utilizar la clase directamente, sin necesidad de instanciar un objeto de ella.
Esto debe ser as por que en el momentos de iniciar la ejecucin de un programa, an no se ha montado en el
sistema todos los componentes necesarias para manejar objetos y por lo tanto el procesador no sabe que hacer
con ellos.
La palabra clave void, que antecede a Main, le dice al sistema que la funcin que viene en seguida no
retornar ningn valor y que por lo tanto no espere nada. En C#, esta funcin tambin se puede denir como
int
La funcin Main() puede ir como se mostr en el ejemplo 1, o tambin incluir argumentos de tipo cadena
de texto. Dichos argumentos se identican por un arreglo o vector del tipo string (cadena de texto), como en la
siguiente forma:
87
static
{
//
Instrucciones
}
En apariencia, los argumentos de inicio de ejecucin solo son vlidos para programas de consola, y no para
programas que manejan un sistema grco de ventanas, como las aplicaciones tipo Windows. Pero esto no
es muy exacto, los programas tipo Windows, o en general que manejan ventanas, tambin pueden requerir
argumentos de entrada en el instante en que inician su ejecucin. Un buen ejemplo son los programas que
manejan algn formato de archivo especico, como puede ser el Bloc de notas que genera archivos de texto que
se identican con la extensin *.TXT y los cuales, generalmente, el sistema operativo asocia con este editor.
Esto trae como consecuencia dos formas de iniciar la ejecucin del Bloc de notas: una, a travs de su acceso
directo en el men de Programas, y la otra haciendo doble clic en el archivo de texto. En este ltimo caso el
sistema operativo enva un argumento al programa informndole que su ejecucin la inicio un archivo y no el
acceso directo del men de programas. El argumento que se enva contiene el nombre completo del archivo que
lo llam, y de esta forma el programa se ejecuta y realiza su apertura.
public
class Bienvenida
{
static void Main(string[] nombre)
{
System.Console.WriteLine("Bienvenido(a)
}
" + nombre[0]);
}
Compile el programa con la instruccin,
> csc ejemplo02.cs
En seguida realice la ejecucin del programa llamando a ejemplo02 seguido de un nombre, como por ejemplo:
> ejemplo02 Homero
Si todo ha salido bien, la salida que muestra el programa despus de teclear ENTER es,
Bienvenido(a) Homero
Pruebe a ejecutar el programa sin enviarle un argumento. Observar que se produce un error, el cual es
informado por la plataforma de ejecucin del .NET.
CAPTULO 3. PROGRAMACIN EN C#
88
La consola
Este es el nombre como en Windows, e incluso en otros sistemas operativos, se conoce a la interfaz que
permite enviar rdenes al sistema operativo a travs de comandos escritos. Tales comandos, no son otra cosa
sino programas desarrollados para este entorno de ejecucin.
Para .NET la consola de Windows se manipula a travs de un objeto que se identica con el nombre
Console, el cual incluye todas las funciones bsicas para manejar este elemento del sistema operativo. Una de
esas funciones es WriteLine que se encarga de enviar a la pantalla, o tambin a otros dispositivos de salida, el
argumento que se le asigne, ya sea una cadena de texto o un valor numrico.
En la instruccin que hemos utilizado en el anterior ejemplo,
System.Console.WriteLine("Bienvenido(a) " + nombre[0]);
se observa que el objeto Console esta antecedido por el identicador System. Este en realidad es lo que se
denomina espacio de nombres, que no es ms que el nombre de un conjunto que agrupa a una serie de clases,
que por lo general el programador considera guardan alguna relacin entre s. En este caso la clase Console
pertenece al conjunto o espacio de nombres llamado System.
Miembro
Color
Black
Negro
Blue
Azul
Cyan
Aguamarina
DarkBlue
Azul marino
DarkCyan
Verde azulado
DarkGray
Gris oscuro
DarkGreen
Verde oscuro
DarkMagenta
Fucsia oscuro
DarkRed
Rojo oscuro
DarkYellow
Amarillo oscuro
Gray
Gris
Green
Verde
Magenta
Fucsia
Red
Rojo
White
Blanco
Yellow
Amarillo
public
class LectorDatos
{
static
{
void Main()
System.Console.ForegroundColor = System.ConsoleColor.Green;
System.Console.Write("Nombre del usuario: ");
System.Console.ReadLine();
System.Console.Write("Nmero de indenticacin: ");
System.Console.ReadLine();
System.Console.WriteLine("Acceso permitido");
89
System.Console.ResetColor();
//
}
}
Inicie un nuevo archivo de texto en el Bloc de notas, incluya las lneas de codigo sugeridas y gurdelo con el
nombre ejemplo03.cs.
En los ejemplos anteriores la compilacin se realiz utilizando la opcin bsica que ofrece el compilador de
C#, llamando al compilador y asignndole el nombre del archivo fuente que se desea compilar. Por defecto,
el compilador asigna al archivo compilado el mismo nombre del archivo fuente, pero en un momento dado
el programador puede desear asignar un nombre conveniente al archivo ejecutable. Como cualquiera de los
compiladores antecesores a C#, este cuenta con una serie de opciones que permiten obtener diferentes salidas
en el proceso de compilacin. Para este caso en particular, se puede utilizar el parmetro out, que permite
asignar un nombre al archivo compilado, diferente al de su fuente. Se aplica siguiendo la sintaxis,
csc /out:ArchivoCompilado ArchivoFuente
Teniendo en cuenta lo anterior compile el programa con la instruccin,
> csc /out:LectorDatos.exe ejemplo03.cs
y ejectelo mediante la llamada,
> LectorDatos
En la programacin de este ejemplo nos hemos dado cuenta que las instrucciones pueden ser un tanto
complejas de escribir, dada la necesidad de tener que incluir el espacio de nombres en las llamadas a las clases y
sus mtodos. Si tenemos en cuenta que la programacin en .NET se hace a base de objetos, cuyas clases hacen
parte de espacios de nombres, y que muchos de estos espacios de nombres a su vez hacen parte de otros espacios
de nombres, el grado de dicultad parece aumentarse innecesariamente para el programador de C#, a causa de
estos mtodos de asignacin de nombres. Sin embargo, esta forma de identicar las clases y sus objetos tiene
una poderosa razn de ser y, en vez de perjudicar, ms bien es un benecio para el programador. En seguida
se describe la importancia de esta metodologa de agrupamiento de clases y la forma como podemos evitar las
dicultades que ofrece el manejo de los espacios de nombres.
Espacios de nombres
Un espacio de nombres es un nombre que identica a un conjunto de clases y que ayuda a distinguirlas de otras
que pueden llevar el mismo nombre base. Por ejemplo, la clase Console que hemos utilizado en todos los ejemplos,
hace parte del espacio de nombres System, que agrupa a todas las clases bsicas de la plataforma .NET. Si un
programador necesita denir otra clase con el nombre Console, puede hacerlo sin ningun problema siempre y
cuando incluya un espacio de nombres diferente, como por ejemplo CursoCSharp.Console. Ambas clases pueden
ser utilizadas en una misma aplicacin sin ningn problema, pero para referenciarlas se deber utilizar su nombre
compuesto, espacio de nombres y nombre de la clase, tal como System.Console y CursoCSharp.Console.
Tambin se puede decir que un espacio de nombres es algo as como un directorio que agrupa a un conjunto
de clases, las cuales el programador las agrupa dependiendo de su criterio. La plataforma .NET posee muchos
espacios de nombres, que agrupan a clases cuya funcionalidad tiene alguna caracterstica que las relaciona a
unas con otras. La siguiente tabla muestra algunos de los espacios de nombres bsicos que se han denido en
.NET, y los archivos DLL que los contienen junto a sus clases (o tambin llamadas tipos):
CAPTULO 3. PROGRAMACIN EN C#
90
Es importante destacar que estos son solo algunos de los espacios de nombres que existen en .NET. Pero
todos los espacios de nombre que conforman la plataforma .NET se encuentran denidos dentro del espacio de
nombres System, y una gran cantidad de ellos estn ubicados dentro de los anteriores espacios de nombres.
Otro aspecto interesante, es observar la forma como han sido nombrados los archivos DLL que contienen
a estos espacios de nombres, como por ejemplo el espacio de nombres System.Drawing es guardado en el
archivo compilado System.Drawing.dll. No signica esto que se trate de una regla obligatoria que vaya a tener
algn efecto en el proceso de compilacin, sino ms bien una cuestin de organizacin que facilita mucho la
identicacin del espacio de nombres y sus clases. Por lo general los entornos de desarrollo integrado, como
Sharpdevelop y VisualStudio .NET generan estos nombres en forma automtica.
El objetivo fundamental de los espacios de nombres, adems de ayudar en la organizacin, es impedir las
incompatibilidades creadas por la posible duplicidad de nombres asignados a las clases. Es tanta la cantidad de
clases que se encuentran denidas dentro de la plataforma de .NET y las que vaya a utilizar el programador de
aplicaciones, que bien podra entrar en conicto a la hora de dar un nombre a una clase, lo cual aunque puede ser
detectado por el compilador, de todas maneras puede perjudicar el diseo y sobre todo la posibilidad de trabajar
un proyecto con componentes de software asignados a diferentes grupos de desarrollo. Adems se corre el riesgo
que los nombres de las clases de un programador coincidan con las de otro, lo cual creara inconsistencias al
sistema.
Supongamos un caso: un equipo de desarrollo encarga a dos grupos diferentes de programadores el diseo de
algunos de los componentes de software para la aplicacin de software que est desarrollando. Los dos grupos,
debido a la dicultad que tienen de comunicacin, implementan, cada uno de ellos, una clase llamada ColorTexto
para colorear las lneas de texto de la salida, pero con funcionalidades un tanto diferentes. Por ejemplo, el primer
grupo dota a esta clase con la funcionalidad de colorear el texto con rojo, mientras que el segundo grupo le
asigna funcionalidades para colorear con amarillo y azul. Si el equipo de desarrollo base necesita utilizar los tres
colores, est obligado a utilizar las dos clases por que cuentan con las funcionalidades que se necesitan y no
se puede obviar una de ellas, pero puede verse en un serio problema si ambas fueron compiladas con el mismo
nombre.
La solucin al anterior problema es utilizar los espacios de nombres para identicar claramente a cada clase
y evitar conicto de nombres. Supongamos que los equipos de programadores se identican con los nombres
de Alfa y Beta y hacen parte de la organizacin MiEmpresa, entonces podran utilizar como nombres para sus
respectivas clases,
MiEmpresa.EquipoAlfa.ColorTexto
y
MiEmpresa.EquipoBeta.ColorTexto
Con esto queda perfectamente solucionado el problema de la duplicidad de clases y permite la utilizacin de
ambas clases sin ningn problema.
Para establecer un espacio de nombres se utiliza la palabra clave namespace, que tiene la siguiente estructura:
namespace
{
Nombre
91
//
//
}
Se puede anidar cualquier cantidad de espacios de nombres para permitir alargar la identidad de las clases. De
esta manera la clase de nuestro ejemplo puede denirse, por parte del Equipo Alfa as:
namespace
MiEmpresa
{
namespace EquipoAlfa
{
public class ColorTexto
{
// Instrucciones
}
}
}
y por parte del equipo Beta asi:
namespace
MiEmpresa
{
namespace EquipoBeta
{
public class ColorTexto
{
// Instrucciones
}
}
}
En el caso antes planteado, la referencia a las clases resulta un tanto compleja ya que se debe escribir el nombre
completo de la clase, incluyendo los identicadores de sus espacios de nombres. Esto puede complicar el trabajo
del programador, al obligarlo a teclear demasiado cdigo. Para evitar tener que teclear nombres demasiado
largos a causa de los espacios de nombres, C# cuenta con la palabra clave using que permite direccionar los
espacios de nombres en el encabezado del archivo fuente y acortar la referencia a una clase, ya sea llamndola
por su nombre bsico o al menos sin tener que recurrir a todos los espacios de nombres que la identican,
siempre y cuando no entre en conicto con otros nombres.
//
Archivo: EquipoAlfa.ColorTexto.cs
using
System;
namespace
{
EquipoAlfa
CAPTULO 3. PROGRAMACIN EN C#
92
//
Archivo: Ejemplo04.cs
93
//
Archivo: EquipoBeta.ColorTexto.cs
using System;
namespace EquipoBeta
{
public static class ColorTexto
{
public static void Amarillo(string cadena)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(cadena);
Console.ResetColor();
}
public static void Azul(string cadena)
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine(cadena);
Console.ResetColor();
}
}
}
Guarde el archivo con el nombre EquipoBeta.ColorTexto.cs y complelo con la instruccin de lnea de comandos,
> csc /t:library EquipoBeta.ColorTexto.cs
Con esto ya tenemos los ensamblados entregados por los equipos Alfa y Beta y los vamos a utilizar en
nuestro proyecto de software. El cdigo del programa que nos permite calcular las funciones trigonomtricas es
el siguiente:
//
Archivo: Ejemplo05.cs
using System;
public class Trigonometria
{
static void Main()
{
CAPTULO 3. PROGRAMACIN EN C#
94
double angulo = 0;
Console.Clear();
Console.Title = "Funciones trigonomtricas";
Console.Write("Valor del ngulo en grados = ");
angulo = Convert.ToDouble(Console.ReadLine());
angulo = angulo * Math.PI / 180;
// Convierte de grados a radianes
EquipoBeta.ColorTexto.Amarillo("\nSeno = " + Math.Sin(angulo));
EquipoBeta.ColorTexto.Azul("Coseno = " + Math.Cos(angulo));
EquipoAlfa.ColorTexto.Rojo("Tangente = " + Math.Tan(angulo));
Console.ReadLine();
// Detiene la ejecucin hasta presionar ENTER
}
}
Este programa, para empezar limpia e inicializa la pantalla mediante el mtodo clear de la clase Console y
asigna un ttulo a la barra de ttulos de la consola, mediante la propiedad Title.
La lectura de datos se realiza mediante el mtodo ReadLine. Pero este mtodo captura el dato como una
cadena de texto de tipo string, lo cual implica que para poderse manipular como un valor numrico se debe
convertir primero a nmero. En este caso se utiliza la Clase esttica Convert y su mtodo ToDouble, que lo
convierte de cadena a un valor de tipo double (numero real de precisin doble).
Tambin, es necesario realizar una conversin del dato ingresado, pasndolo de grados a radianes, ya que
este es el formato que utilizan las funciones trigonomtricas de .NET. Tanto el valor de la constante PI como las
funciones trigonomtricas, y otras funciones matemticas, se encuentran denidas e implementadas en al clase
esttica Math.
Finalmente, hay que compilar este archivo fuente, para generar el ensamblado de nuestro programa, teniendo
en cuenta que este depende de dos ensamblados ms, EquipoAlfa.ColorTexto.dll y EquipoBeta.ColorTexto.dll.
En el llamado al compilador se debe pasar el listado de las libreras que se necesitan para la compilacin,
utilizando la opcin /r: seguida de los nombres de los archivos DLL, separados por comas (pero sin espacios).
Debe tenerse en cuenta que para llamar a la clase ColorTexto, fue necesario incluir el espacio de nombres
al cual perteneca, dado que si no se hacia as se creara una ambigedad que no permitira al sistema saber de
cual clase se est hablando.
La compilacin se realiza ejecutando la siguiente instruccin en la lnea de comandos:
> csc /r:EquipoAlfa.ColorTexto.dll,EquipoBeta.ColorTexto.dll ejercicio05.cs
Con este sencillo ejemplo se ha mostrado la forma como se puede organizar una aplicacin de software y la
reutilizacin de algunos de sus componentes para ahorrar trabajo y ganar tiempo en el proceso de desarrollo.
Cuando abordemos el concepto de programacin orientada a objetos, propiamente dicho, se dar mayor nfasis
a este tipo de diseo.