Análisis
y Diseño de Algoritmos
Prof:
Ing. Victor Garro
Asistente:
Marco Elizondo Vargas
PROGRAMACION
EN C++
CAPITULO 1 Conceptos Básicos de
Programación
En este
capítulo vamos a introducir el lenguaje de programación C++ que se va a
utilizar en la asignatura, describiendo algunos conceptos básicos y plasmando
la estructura general de un programa escrito en este lenguaje. A lo largo de
los sucesivos temas se seguirá la notación BNF para ir describiendo las
diferentes reglas sintácticas del lenguaje. De esta forma se irá introduciendo
de una manera formal la sintaxis de C++.
1.1 ELEMENTOS DEL LENGUAJE
Comenzaremos
viendo los elementos más simples que integran un programa escrito en C++, es
decir palabras, símbolos y las reglas para su formación.
a)
Identificadores: Son nombres elegidos por el programador para representar
entidades (variables, tipos, constantes, etc.) en el programa. El usuario puede
elegir cualquier identificador excepto un pequeño grupo que se reserva para
usos específicos.
C++
distingue entre letras mayúsculas y minúsculas, por lo
que a efectos del programa serán identificadores distintos hola, Hola y hoLa.
La
gramática que define la sintaxis de los identificadores es la siguiente:
<ident> ::= <carácter_ident>
{<carácter_ident>|<dígito>}
<carácter_ident> ::= a | b |···| z | A | B
|··· | Z | _
<dígito> ::= 0 | 1 | 2 | ··· | 9
No se
impone en principio ningún límite en cuanto a la longitud de los
identificadores.
Dichos
limites dependerán del compilador que se esté empleando. Más aún, en esta
asignatura
no emplearemos identificadores tan largos como para darnos problemas en este
sentido.
b)
Palabras reservadas: Tienen un significado predeterminado para
el compilador y sólo pueden ser usadas con dicho sentido. En C++ se escriben
siempre con minúsculas.
and
and_eq asm auto bitand bitor
bool
break case catch cdecl char
class
compl const const_cast continue default
delete
do double dynamic_cast else enum
explicit
export extern false float for
friend
goto if inline int long
mutable
namespace new not not_eq operator
or
or_eq private protected public register
reinterpret_cast
return short signed sizeof
static
static_cast struct switch template this
throw
true try typedef typeid typename
union
unsigned using virtual void volatile
wchar_t
xor xor_eq while
c)
Identificadores estándares: Tienen un significado predefinido dentro
del lenguaje,
pero a
diferencia de las palabras reservadas, el programador puede redefinirlos dentro
de su programa (aunque esto normalmente no es aconsejable). Dos ejemplos de
dichos
identificadores
estándares serán presentados en este tema: los flujos de entrada y salida cin
y
cout.
d)
Literales constantes: Se distingue entre números reales, números
enteros y cadenas
de
caracteres.
<literal > ::= <num_entero> |
<num_real> | <car> | <cadena_car>
<num_entero>
::= [+|-] <dígito> {<dígito>}
<num_real>
::= <num_entero>.{<dígito>} [<factor_esc>]
<factor_esc>
::= (e|E) <num_entero>
<car> ::= ‘ <carácter> ‘
<cadena_car> ::= “ {<carácter>} “
Cuando se
usa e en un literal constante real se dice que el
número está expresado en punto flotante (notación
científica). En cuanto a las cadenas de caracteres (o strings), en C++
se expresan mediante una secuencia de
caracteres cualesquiera1 encerrados entre comillas
simples.
IMPORTANTE:
El símbolo \ tiene un
significado especial en C/C++ como introductor de caracteres especiales (e.g., \n
para un salto de línea, \t para
una tabulación, \” para las comillas
dobles, etc.), lo que deberá tenerse en cuenta a la hora de su introducción
como literal. Si se desea usar literalmente, utilícese ‘\\’.
e)
Delimitadores: Son símbolos que indican el comienzo o fin de una entidad.
! % ^ & ( ) - + =
{ } ~ [ ] \ ; • :
< > ? , . / “
f)
Comentarios: Un comentario es una secuencia de caracteres que es ignorada por
el
compilador.
Se usan para documentar el programa, de manera que aunque no contribuyan a
resolver el problema, sí ayudan a mejorar la comprensión del programa. Se
pueden insertar en el programa de dos maneras: escribiendo un texto entre los
símbolos /* y */ (este
texto se puede extender a lo largo de varias líneas), o usando el símbolo //
(se
interpretará como comentario todo lo que siga hasta llegar al final de la
línea).
Debe
tenerse cuidado para no encerrar trozos de código útil dentro de un comentario,
ya
que un
comentario puede extenderse a lo largo de múltiples líneas. Encerrar trozos de
código como comentarios es útil cuando se está desarrollando un programa para
comprobar si ciertas partes funcionan o no, pero es un error muy común encerrar
por descuido otras zonas de código que son necesarias o bien olvidarse de sacar
órdenes de dentro de un comentario.
El
anidamiento de comentarios (poner comentarios dentro de otros comentarios)
puede dar problemas en algunos compiladores. En Visual C++ se dá este problema pero
nunca emplearemos
este tipo de anidamiento.
g)
Separadores: Son espacios en blanco, tabuladores, retornos
de carro, fin de fichero y fin
de línea. Habrá ocasiones en que se pongan para dar legibilidad al
programa, y otras por necesidad. Los comentarios son considerados también separadores
por
el compilador.
CONSTANTES, VARIABLES Y TIPOS DE DATOS
En un programa
intervienen objetos sobre los que actúan las instrucciones que lo componen.
Algunos de
estos objetos tomarán valores a lo largo del programa. Dependiendo de si pueden
cambiar de valor o no, podemos distinguir dos tipos de objetos:
• Constante: Objeto
–referenciado mediante un identificador- al que se le asignará un
valor que no se podrá modificar a lo largo
del programa.
• Variable: Objeto
–referenciado por un identificador– que puede
tomar distintos valores a lo largo del programa.
Será misión
del programador asignar el identificador que desee
a cada constante y variable. El identificador o nombre de cada objeto sirve
para identificar sin ningún tipo de ambigüedad a cada objeto, diferenciándolo
de los demás objetos que intervienen en el programa. En C++ hay que indicar (de
la manera que más adelante se indicará) el nombre de las constantes y variables
que vamos a usar, para que el compilador pueda asociar internamente a dichos
nombres las posiciones de memoria correspondientes.
Para esto último
es preciso también que junto con dichos nombres, se indique explícitamente para
cada constante o variable el tipo de los datos que pueden contener.
En C++
existen una serie de tipos básicos predefinidos, así como herramientas para la
construcción
de tipos más complejos. Los principales tipos de datos predefinidos en C++ son
los siguientes:
• Enteros: el tipo
básico es int. Las variables definidas de
este tipo podrán tomar
típicamente
valores entre -2147483648 y 2147483647. En determinadas circunstancias
podremos
querer modificar este rango, para lo que disponemos de dos tipos de
modificadores
short/long y signed/unsigned. o short
int:
el rango de representación es menor (–32768 a 32767 típicamente), y por lo
tanto también lo es la memoria ocupada (la mitad).
o long int: mayor rango de representación4
(e.g.,
-9223372036854775808 a
9223372036854775807),
y más memoria necesaria (el doble). o unsigned
int:
ocupa la misma memoria que un int, pero
sólo toma valores
positivos
(e.g., 0 a 4294967295).
o signed int: es equivalente a un int.
Los
modificadores mencionados se pueden combinar, e.g., long unsigned int (ocupa
la misma
memoria que un long int, pero
sólo almacena números positivos, con lo que
el rango
de representación es mayor). Adicionalmente, puede suprimirse la indicación
int en todos los casos anteriores, asumiéndose
ésta por defecto (e.g., unsigned es lo
mismo que unsigned int).
• Carácter: se
emplea el tipo char.
• Lógico: se
utiliza el tipo bool. Los
objetos de este tipo sólo pueden tomar dos valores:
true (cierto) y false (falso).
• Reales: los
números reales (en realidad números en punto flotante, ya que los números
reales en
sentido estricto no son representables en ningún computador digital) se
representan
mediante los tipos float y double. El segundo tipo permite representar
números
con mayor magnitud y precisión, empleando para ello el doble de memoria que float. Si se precisa mayor rango de
representación o de precisión puede emplearse el modificador long sobre double, i.e., long double. No se pueden emplear los modificadores signed/unsigned
sobre
double.
Todos
estos tipos tienen dos propiedades en común: cada uno está formado por
elementos indivisibles o atómicos
que además están ordenados. Los
tipos de datos con estas características se denominan tipos
de datos escalares. Cuando decimos que un valor es atómico, nos referimos a que no
contiene partes componentes a las que pueda accederse independientemente. Por
ejemplo, un carácter es indivisible, mientras que la cadena de caracteres “Hola”
no. Cuando hablamos de que un conjunto de valores está ordenado, queremos decir
que los operadores relacionales estándares (mayor que, menor que, igual, etc.)
pueden aplicarse a los mismos.
Para declarar
una variable basta con indicar el tipo de la misma y su nombre. La declaración
termina con el punto y coma. Los siguientes ejemplos muestran declaraciones
válidas:
int num;
unsigned x,y;
long double masaPlanetaria;
char car = ‘c’, letra;
short int corto;
Como puede
apreciarse en el último ejemplo, es posible dar un valor inicial a una variable
a la vez que se declara. Así, la sintaxis BNF de una declaración de variable
es:
<decvar> ::= <tipo> <ident> [=
<literal>] {, <ident> [= <literal>]};
La declaración
de constantes es muy similar a la de variables, con dos diferencias
fundamentales:
hay que usar la palabra reservada const
para
indicar que se está definiendo una constante, y la asignación de un valor
inicial no es opcional, sino obligatoria:
<decconst>
::= const <tipo> <ident> = <literal>;
Ejemplos
de declaraciones de constantes válidas5 son los
siguientes:
const int HORAS = 24;
const double NUMERO_AVOGADRO = 6.023e+23;
const short ALUMNOS = 100;
const char ACEPTAR = ‘S’;
En algunos
compiladores se permite que no se indique el tipo de una constante, asumiéndose
que es entera por defecto. En Visual C++
siempre indicaremos
explícitamente el tipo de las constantes que definamos.
Tanto las
declaraciones de variables como de constantes pueden realizarse de dos maneras:
global y local. El
primer modo consiste en situar dicha declaración al principio del código, justo
después de las inclusiones. El segundo modo consiste es situarlas dentro del
programa principal, en la zona delimitada por las llaves.
Ejemplos:
GLOBAL
int num,
x, y;
int main()
{
LOCAL
int main()
{
int num,
x, y;
La
diferencia entre ambas formas de declaración será evidente cuando en temas
posteriores se introduzca la noción de función. De momento, la regla práctica que
seguiremos será definir siempre variables y constantes de manera local. C++
permite que las declaraciones locales se realicen en cualquier punto del
algoritmo situado entre el comienzo ({) y el final (}) del
mismo. Siempre declararemos los objetos locales
inmediatamente después de la llave de apertura.