Documentos de Académico
Documentos de Profesional
Documentos de Cultura
1 BÁSICOS
APUNTES DE PROGRAMACIÓN I -2-
1.1. COMPUTADORA
MEMORIA
PRINCIPAL
UNIDAD DE
CONTROL
UNIDAD DE UNIDAD DE
ENTRADA SALIDA
UNIDAD
ARITMETICO-
LOGICA
CPU
UNIDAD DE
ALMACENAMIENTO
En forma muy simplificada, podemos decir que la memoria está compuesta por
circuitos electrónicos que pueden estar, en un momento dado cerrados o abiertos,
es decir, hay o no hay cierto voltaje. Estos dos estados podemos simbolizarlos
mediante un 0 para el estado cerrado y un 1 para el estado abierto. Esto
constituye el más elemental dato que puede procesar una computadora, y lo
denominamos bit, que viene de la expresión inglesa Binary Digit (dígito binario).
para ambiente gráfico por su alta resolución (640x480 píxeles). Pueden llegar
hasta 256,000 colores ó 64 tonalidades de gris dependiendo de la memoria
destinada al dispositivo; SVGA (Super Vídeo Graphics Array), maneja una
resolución más alta (1,024x768), el número de colores desplegables varía
dependiendo de la memoria, pero puede ser mayor que 1 millón de colores;
UVGA (Ultra Vídeo Graphics Array), resolución de 1280 x 1024.
La calidad de las imágenes que un monitor puede desplegar se define más por
las capacidades de la tarjeta controladora de vídeo, que por las del monitor
mismo. El controlador de vídeo es un dispositivo intermediario entre el CPU y
el monitor. El controlador contiene la memoria y otros circuitos electrónicos
necesarios para enviar la información al monitor para que la despliegue en la
pantalla.
1.2. PROGRAMA
Un programa es un conjunto de instrucciones, escritas en un determinado
lenguaje, que permite realizar una tarea dada con la computadora.
Las instrucciones, así como los datos, que un procesador digital es capaz de
entender están constituidas por conjuntos de unos y ceros, es decir, bits. A esto se
llama Lenguaje de Máquina, y es muy difícil de manejar por los seres humanos.
Por ello, se comenzaron a desarrollar los llamados Lenguajes de Alto Nivel (tales
como Fortran, Cobol, BASIC, Pascal, C, C++, Java, etc.), que están mucho más
cerca del lenguaje natural. Cada lenguaje dispone de una sintaxis o conjunto de
reglas con las que se indica de modo inequívoco las operaciones que se quiere
realizar.
Los lenguajes de alto nivel son más o menos comprensibles para el usuario, pero
no para el procesador. Para que éste pueda ejecutarlos es necesario traducirlos a
su propio lenguaje de máquina. Esta es una tarea que realiza un programa
especial llamado compilador, que traduce el programa a lenguaje de máquina.
Esta tarea se suele descomponer en dos etapas, que se pueden realizar juntas o
por separado. El programa escrito, con la ayuda de un editor, en un lenguaje de
alto nivel se suele almacenar en uno o más archivos llamados programa fuente,
que en casi todos los sistemas operativos se caracterizan por una terminación
especial, también llamada extensión. Así, todos los programas fuente de C deben
terminar por .c; ejemplos de nombres de estos ficheros son calculos.c, derivada.c,
etc.
La tarea del compilador es realizar una traducción directa del programa fuente al
lenguaje de máquina de la computadora, produciendo un programa objeto con el
mismo nombre que el archivo original, pero con la extensión .obj. En una segunda
etapa se realiza el proceso de montage (linkage) con un programa llamado
enlazador, que incorpora las funciones estándar utilizadas por el programa fuente
y que pertenecen a la así llamada biblioteca del sistema, con el objetivo de
producir un programa ejecutable en lenguaje de máquina. En un PC con sistema
operativo Windows el programa ejecutable se guarda en un fichero con extensión
.exe. Este fichero es cargado por el sistema operativo en la memoria RAM cuando
el programa va a ser ejecutado.
Programador EDITOR
Programa
Fuente
*.cpp
Errores
COMPILADOR
Programa
Objeto
*.obj
Biblioteca ENLAZADOR
Programa
Ejecutable
*.exe
Para entender lo que es un dato, debemos definir primero algunos conceptos: una
entidad es un objeto, físico o abstracto, que puede distinguirse de los demás; son
entidades una persona, un libro, un carro, una cuenta bancaria, un país, etc. Para
distinguir una entidad de otra apelamos a algunas características especiales a las
que llamaremos atributos o propiedades que en el caso de las personas podrían
ser nombre, cédula, edad, peso, estatura, nacionalidad, etc. Y tratándose de un
carro, marca, modelo, placas, año, color, entre otras.
Entrada. Un algoritmo tiene cero o más entradas: cantidades que le son dadas
antes de que el algoritmo comience, o dinámicamente mientras el algoritmo
corre. Estas entradas son tomadas de conjuntos específicos de objetos.
Salida. Un algoritmo tiene una o más salidas, las cuales tienen una relación
específica con las entradas.
INICIO
N 1
N N+1
F
N > 10
FIN
Figura 4. Algoritmo para sumar los números de 1 al 10
(Diagrama de Flujos)
LENGUAJE C
2 ELEMENTOS
NERIO VILLALOBOS FINOL
APUNTES DE PROGRAMACIÓN I - 13 -
2.1. Historia
El lenguaje de programación C fue creado por Dennis Ritchie entre en 1973
cuando trabajaba en Bell Laboratories de la corporación AT&T junto con Ken
Thompson en el diseño del sistema operativo UNIX. C fue creado para poder
escribir dicho sistema operativo en un lenguaje de alto nivel, independiente del
hardware donde se ejecutara. Su evolución ha sido así:
A mediados de los años 60s, Martin Richards diseña el lenguaje BCPL con la
finalidad de usarlo para escribir software de sistemas operativos y
compiladores.
En 1983/84, "C con Clases", lenguaje C++. C++ queda disponible en 1985,
Creado por Bjarne Stroustrup (en Bell Laboratories).
Escoger el tipo de dato adecuado para cada variable es una de las primeras
tareas que realizamos al programar. Una selección equivocada puede provocar
resultados con fallas de precisión o exactitud, que no siempre somos capaces de
determinar al observarlos. Al modelar datos a partir de objetos o conceptos del
mundo real, hay que detenerse a observar ciertas características de los mismos y
decidir aspectos como si son números o cadenas de caracteres; si es un entero o
un número real; cuantos dígitos de precisión se requieren; cual es el dominio de
valores permitidos; si puede ser negativo o no; etc.
float. Un número real (de coma flotante como se prefiere decir en ciencia e
ingeniería) con una precisión de 7 dígitos aproximadamente.
El tamaño y el rango de estos tipos de datos varían con cada tipo de procesador y
con la implementación del compilador de C. El tipo void, o bien declara
explícitamente una función que no devuelve valor alguno, o bien crea punteros
genéricos.
Hay que advertir, sin embargo, que en muchos casos, que depende del
procesador, sistema operativo o compilador utilizado, los tipos int y unsigned int se
almacena en 4 bytes, por lo que su rango de valores son iguales al de los tipos
long int y unsigned long int, respectivamente. Por tanto, se recomienda verificar
esto en el compilador que utilice.
int n;
char c;
n = ‘A’; c = 65;
printf(“El carácter %c tiene código ASCII %d\n”, n, n);
printf(“El carácter %c tiene código ASCII %d\n”, c, c);
2.4.2. IDENTIFICADORES
2.3.3. CONSTANTES
Constantes numéricas. Son valores numéricos con signo o sin signo, enteros
o de punto flotante. Pueden usarse prefijos o sufijos para indicar explícitamente
el tipo o la base numérica de un número (decimal, octal o hexadecimal).
Ejemplos: 15400 (int), -350 (int), 572L (long), 063 (octal), 0x9f (hexadecimal),
0xa2e4 (hexadecimal), 0xffL (hexadecimal long). Igualmente pueden
expresarse en notación exponencial o científica: 1.25e-05 o 6.02e+23.
Código Significado
\a Alerta (campana)
\b Retroceso
\f Salto de página
\n Nueva línea
\r Retorno de carro
\t Tabulación horizontal
\v Tabulación vertical
\0 Carácter nulo (ASCII)
\ddd Constante octal (d = dígito)
\xddd Constante hexadecimal
\\ Barra invertida (\)
Tabla 4. Secuencias de Escape ASCII
2.2.4. OPERADORES
Los operadores son signos especiales (a veces, conjuntos de dos caracteres) que
indican determinadas operaciones a realizar con las variables y/o constantes
sobre las que actúan en el programa. El lenguaje C es particularmente rico en
distintos tipos de operadores: aritméticos, relacionales, lógicos, binarios y de
asignación.
ARITMÉTICOS RELACIONALES
+ Suma == Igual
- Resta > Mayor
* Multiplicación < Menor
/ División >= Mayor o igual
% Módulo (Residuo) <= Menor o igual
!= Diferente
LÓGICOS BINARIOS
&& Conjunción (Y) – AND & AND binario
|| Disyunción (O) – OR | OR binario
! Negación (NO) - NOT ^ XOR binario
NOT binario
~
(Complemento a 1)
Desplazamiento a la
<<
izquierda
Desplazamiento a la
>>
derecha
Tabla 5. Operadores de C
pero si los dos operandos son enteros el resultado será entero, es decir, sin la
parte fraccionaria. Mientras que el operador %, el cual sólo debe aplicarse a
operandos enteros, obtiene el residuo de la división. Ejemplos:
int m = 7, n = 2, a, b;
…
a = m / n; // a vale 3
b = m % n; // b vale 1
En cuanto a los operadores relacionales hay que decir que el resultado de dichas
operaciones es de tipo lógico, es decir, sus posibles valores son 0 (falso) y 1
(verdadero). Ejemplos:
int m = 5, n = 3, a, b, c;
…
a = m > n; // a vale 1
b = n >= 3 // b vale 1
c = m == n; // c vale 0
p && q p || q p !p
0 0 0 0 0 0 0 1
1 0 0 1 1 0 1 0
0 0 1 0 1 1
1 1 1 1 1 1
2.2.5. DELIMITADORES
Los delimitadores están constituidos por uno o varios espacios en blanco,
tabuladores, y caracteres de nueva línea. Su papel es ayudar al compilador a
descomponer el programa fuente en cada uno de sus elementos sintácticos. Es
conveniente introducir espacios en blanco incluso cuando no son estrictamente
necesarios, con objeto de mejorar la legibilidad de los programas.
2.2.6. COMENTARIOS
El lenguaje C permite que el programador introduzca comentarios en el código de
su programa fuente que sirven de explicación o aclaración sobre cómo está hecho
el programa, de forma que pueda ser entendido por una persona diferente (o por
el propio programador algún tiempo después). En C se usan los caracteres /* para
iniciar un comentario el cual termina con los caracteres */. Los comentarios son
siempre ignorados por el compilador. Estos símbolos pueden comenzar en una
línea y terminar en otra. Una fuente frecuente de errores al programar en C, es el
olvidarse de cerrar un comentario que se ha abierto previamente.
En el lenguaje C++ se utiliza además otra forma con el símbolo //, el cual inicia un
comentario que finaliza al final de la línea. Para comentarios cortos, esta forma es
más cómoda que la anterior, pues no hay que preocuparse de cerrar el
comentario. Ejemplos:
/*****************************************/
/* Programa.CPP */
/* Objetivo: Programa que realiza alguna tarea */
/* Autor: Pedro Pérez */
/* Fecha: 21/05/2007 */
/*****************************************/
2.5. VARIABLES
Una variable es un espacio de la memoria donde se almacenan datos que pueden
cambiar durante la ejecución de un programa. Se representa por un nombre y
tiene que señalarse el tipo de datos que puede almacenar. Antes de usarse
cualquier variable en un programa debe declararse su tipo, de la siguiente manera:
tipo variable;
Ejemplo:
int m; // declara a m como una variable de tipo int
2.5.1. ASIGNACIÓN
A una variable se le puede asignar un valor en cualquier lugar del programa
mediante la sintaxis:
variable = expresión;
int a, b, c, n;
…
a = 25;
b = a;
c = b * 2 + a;
n = sqrt(a) * (b + c);
Un ejemplo de inicialización:
valor es convertido a real con la parte fraccionaria en cero (0). Veamos los
siguientes ejemplos:
int a = 7, b = 2;
float x = 7.0, y = 2.0, m, n;
…
m = x / y; // n toma el valor de 3.5
n = a / b; // m toma el valor de 3.0
la variable masa es convertida a tipo int. El casting se aplica con frecuencia a los
valores de retorno de las funciones.
k = k + 1;
a + b = c; // incorrecto
n += 1; // Equivale a n = n + 1;
rango /= 2.0 // Equivale a rango = rango /2.0
x *= 3.0 * y - 1.0 // Equivale a x = x * (3.0 * y - 1.0)
Ejemplo:
a = b = b = c = d = 1;
a = 2; b = 3; c = 4;
b++: // b pasa a ser 4
--c; // c pasa a ser 3
m = a++; // al ejecutarse esta sentencia m = 2, a=3
n = ++a; // al ejecutarse esta sentencia n = 3, a=3
Hay que tener cuidado cuando utilicemos los operadores incrementales ya que al
efectuarse una asignación junto con un incremento, uno se efectúa primero que el
otro dependiendo de si usamos un preincremento (++variable) o un posincremento
(variable++), como vemos en las dos últimas operaciones del ejemplo anterior.
x = y = 5;
a = ++x;
b = y++;
-b + b2 – 4ac
x=
2a
se escribe, en C en la forma:
int a = 10, b = 5, c = 2, m, n;
…
m = ( (a > 0) && (b < 10) ); // m vale 1
n = ( (a == b * 2) || (b != c) ); // n vale 1
(a - b * 2.0) && (c != d)
3+4*2
Existe dos tipos de reglas para determinar este orden de evaluación: las reglas de
prioridad Además, el orden de evaluación puede modificarse por medio de
paréntesis, pues siempre se realizan primero las operaciones encerradas en los
paréntesis más interiores.
Precedencia Asociatividad
( ) [ ] -> . Izquierda a Derecha
++ -- ! - y + unarios * y & Derecha a Izquierda
* / % Izquierda a Derecha
+ - Izquierda a Derecha
< <= > >= Izquierda a Derecha
== != Izquierda a Derecha
&& Izquierda a Derecha
|| Izquierda a Derecha
?: Derecha a Izquierda
= += -= *= /= Derecha a Izquierda
, (operador coma) Izquierda a Derecha
Tabla 6. Orden de Precedencia y Asociatividad
a – b + d * 5.0 + u / 2.0
equivale a
double tiempo;
float masa;
…
printf("En el instante %lf la masa vale %f\n", tiempo, masa);
en el que se imprimen 2 variables (tiempo y masa) con los formatos (%lf y %f),
correspondientes a los tipos double y float, respectivamente. La cadena de control
se imprime con el valor de cada variable intercalado en el lugar del formato
correspondiente.
Lo importante es considerar que debe haber correspondencia uno a uno (el 1º con
el 1º, el 2º con el 2º, etc.) entre los formatos que aparecen en la cadena de control
y los otros argumentos (constantes, variables o expresiones). Entre el carácter % y
el carácter de conversión puede haber, por el siguiente orden, uno o varios de los
elementos que a continuación se indican:
Un signo (-), que indica alineamiento por la izquierda (el defecto es por la
derecha).
Un cualificador: una (h) para short o una (l) para long y double o una u para
unsigned.
donde el número 2021 se imprime como un entero (%d), mientras que 15200 se
imprime con formato float con 8 caracteres de los cuales 2 son para los decimales
(%8.2f). Es importante hacer corresponder bien los formatos con el tipo de los
argumentos, pues si no los resultados pueden ser muy diferentes de lo esperado.
donde x1, x2, ... son los caracteres de formato, mostrados en la Tabla 7, que
representan los formatos con los que se espera encontrar los datos. La función
scanf() devuelve como valor de retorno el número de conversiones de formato
realizadas con éxito. La cadena de control de scanf() puede contener caracteres
además de formatos. Dichos caracteres se utilizan para tratar de detectar la
presencia de caracteres idénticos en la entrada por teclado. Si lo que se desea es
leer variables numéricas, esta posibilidad tiene escaso interés. A veces hay que
comenzar la cadena de control con un espacio en blanco para que la conversión
de formatos se realice correctamente.
En la función scanf() los argumentos que siguen a la cadena de control deben ser
pasados por referencia, ya que la función los lee y tiene que trasmitirlos al
programa que la ha llamado. Para ello, dichos argumentos deben estar
constituidos por las direcciones de las variables en las que hay que depositar los
datos, y no por las propias variables. Una excepción son las cadenas de
caracteres, cuyo nombre es ya de por sí una dirección (un puntero), y por tanto no
debe ir precedido por el operador (&) en la llamada. Ejemplos:
int cantidad;
float precio;
unsigned char edad;
…
printf(“Cantidad…..: “); scanf(“%d”, &cantidad);
printf(“Precio……...: “); scanf(“%f”, &precio);
printf(“Edad............: “); scanf(“%u”, &edad);
gets(): Lee una cadena de caracteres del teclado. Esta función, a diferencia de
scanf, permite ingresar cadenas con espacios en blanco y otros delimitadores.
El argumento de la función gets es justamente la variable que recibe el valor
ingresado. Pertenece al archivo de cabecera stdio.h. Ejemplo:
char nombre[20];
…
printf(“Escribe el nombre: “);
gets(nombre);
char ch;
…
putchar(ch); // Equivale a printf(“%c”, ch);
2.7.4. EL PREPROCESADOR
El preprocesador del lenguaje C permite indicar los archivos de la biblioteca a ser
incluidos en el programa, definir macros, realizar compilaciones condicionales,
entre otras cosas. El preprocesador de C reconoce los siguientes comandos:
#include, #define, #undef, #if, #ifdef, #ifndef, #else, #endif, #elif, #pragma, #error
#include
Cuando en un archivo fuente (*.c, *.cpp) se encuentra una línea con #include
seguido del nombre de un archivo de la biblioteca, el preprocesador incluye su
contenido en ese archivo fuente.
La sintaxis de este comando es la siguiente:
#include "nombre_del_archivo"
o
#include <nombre_del_archivo>
En la práctica, los archivos del sistema (stdio.h, math.h, etc.) se incluyen con la
segunda forma, mientras que los archivos hechos por el propio programador se
incluyen con la primera. Este comando del preprocesador se utiliza normalmente
para incluir archivos con los prototipos (declaraciones) de las funciones de librería,
o con módulos de programación y prototipos de las funciones del propio usuario.
Estos archivos suelen tener la extensión *.h (de header = cabecera), aunque
puede incluirse cualquier tipo de archivo de texto.
#define
El comando #define establece una macro en el código fuente. Existen dos
posibilidades de definición:
Ejemplos:
#define E 2.718281828459
#define CUAD(x) ((x)*(x))
…
double a, b, c;
…
a = 2.5;
b = 7 / CUAD(a);
c = 3.1 + b / E;
double a, b, c;
…
a = 2.5;
b = 7 / (a * a);
c = 3.1 + b / 2.718281828459;
Cuando se define una macro con argumentos conviene ser muy cuidadoso para
prever todos los posibles resultados que se pueden alcanzar, y garantizar que
todos son correctos. En la definición de una macro pueden utilizarse macros
definidas anteriormente. En muchas ocasiones, las macros son más eficientes que
las funciones, pues realizan una sustitución directa del código deseado, sin perder
tiempo en copiar y pasar los valores de los argumentos. Es recomendable tener
presente que el comando #define:
No define variables.
EJERCICIOS DE LA UNIDAD 2.
1. Indique si las siguientes cadenas de caracteres son identificadores válidos del
lenguaje C. De no serlos, señale la causa.
a. PANORAMA k. double
b. Mi Dato l. n5jw26vss
c. aParTamEnto m. Kapital
d. 5veces n. Año
e. _POCO o. Fecha_de_Nacimiento
f. __MUCHO p. Sueldo Basico
g. Pago99 q. “Apodo”
h. Carátula r. _1_Grado
i. A1 s. Nº_de_Cedula
j. x+y t. Peso y Estatura
2. Qué tipo de datos usaría para representar los valores correspondientes a las
siguientes propiedades:
a. 1 k. 1.123
b. 123 l. 999
c. 1234 m. -999
d. 123456 n. 9
e. 1234567890 o. -9
f. 9876543210 p. ‘9’
g. 1.23456789 q. “9”
h. 1234.5678 r. “999”
i. 12345678.9 s. “UNO”
j. 1.0 t. 12345.6000000
b. int a, b, c; f. int i, j, k;
a = 1; i = j = k = 3;
b = a++; k += i++;
c = ++b; j = 2 + k++;
c. int x, y, z; g. int a, b, c;
x = 4; a = 4;
y = x; b = 3 + a * 2;
z = x == y; c = a - b % 3;
d. int p, q, r; h. int a, b, c;
p = 4; float w, x, y;
q = 2; a = 14; x = 22;
r = p % q; b = a / 3;
p *= 2; y = a / 3;
q = p && r; c = x / b;
w = a / b;
int a, b, c;
float x, y, z;
int const k = 4;
a. x = a + b;
b. b = k;
c. printf(“%f”, a);
d. scanf(“%d”, &k);
e. y++;
f. c = k++;
g. a = b > 0;
h. z = x % y;
i. printf(“%d”, &a)
j. a + b = c + 1;
k. c += a + b;
l. x = y * a++;
m. b = 25000 * 2;
n. printf(“%d”, a + b);
o. z = k;
p. a = b = c = 0;
q. z = x == y;
r. y = x / a;
s. b += ++c;
t. ++a = b++;
int a, b, c, d;
a = 9; b = 3, c = 2, d = 12;
a. c + a / b
b. b * (d / b * 2) + c
c. (d > a + b) && ((b * c) == (d / 2))
d. (b * (a – b)) == d
e. b + (c + d * b) / b
A = s (s – a) (s – b) (s – c)
donde s = a + b + c
2
p = 2nr * tan( )
2
c. La distancia s desde un punto (p, q) a la línea Ax + By + C = 0 viene dada
por
Ap + Bq + C
s=
A2 + B2
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2
1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
_