Conceptos Básicos de C
Elementos del
lenguaje
Comenzaremos
viendo los elementos mas simples que integran un programa escrito en C++, es
decir palabras, sımbolos y las reglas para su formacion.
1. Identificadores
Son nombres
elegidos por el programador para representar entidades (variables, tipos,
constantes, procedimientos, modulos) en el programa. El usuario puede elegir cualquier identificador excepto un peque no
grupo que se reserva para usos especıficos.
C++ distingue entre letras
mayusculas y minusculas, por lo que a efectos del programa seran
identificadores distintos "hola", "Hola" o "hoLa".
No se impone ningun lımite en cuanto a la
longitud de los identificadores.
<Ident> ::= <letra>
{<letra>|<digito>}
2. Palabras reservadas
Tienen un significado
predeterminado para el compilador y s´olo pueden ser usadas con dicho sentido.
and
|
and
|
eq
|
asm
|
auto
|
bitand
|
bitor
|
|||||||||||||||||
bool
|
break
|
case
|
catch
|
chat
|
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
|
while
|
|||||||||||||||||
xor
|
xor
|
eq
|
|||||||||||||||||||||
3. Literales constantes
Se distingue entre n´umeros reales, n´umeros
enteros y cadenas de caracteres.
<num_entero> ::= <digito> {<digito>}
|
|
|
|
<digito_octal> {<digito_octal>}
(u|U|l|L)|
|
||
<digito> {<digito_hex>} H
|
||
<num_real>
|
::= <digito>
{<digito>}.{<digito>} [<factor_esc>]
|
|
<factor_esc>
|
::= E (+|-|e) {<digito>}
|
Si el numero lleva u como sufijo, es un numero sin
signo. Si lleva l como sufijo es de tamano long. Todo numero al que se le
antepone el caracter 0 esta expresado en base 8. Si se le antepone 0x, esta
expresado en base 16. Cuando se usa E
en un literal
constante real se dice que el numero esta expresado en punto flotante
(notacion cientıfica). e representa la cadena vacıa.
Una cadena de
caracteres (string) en C++ es una secuencia de caracteres encerrados entre
comillas dobles (). Las constantes que representan un solo caracter se
encierran entre comillas simples(’ ’).
4. Delimitadores
Son símbolos
(con o sin significado propio) que indican comienzo o fin de una entidad. Son
elementos indivisibles: por ejemplo al escribir == se debe hacer sin ningún carácter
intercalado.
{
|
}
|
[
|
]
|
#
|
##
|
(
|
)
|
<:
|
>:
|
<%
|
>%
|
%:%:
|
%:
|
;
|
:
|
?
|
:: .
|
.* +
|
-
|
*
|
/
|
%
|
^
|
||
&
|
|
|
~
|
!
|
=
|
<
|
>
|
+=
|
-=
|
*=
|
/=
|
%=
|
^=
|
&=
|
|=
|
<<=
|
>>= <<
|
>>
|
==
|
!=
|
<=
|
>=
|
&&
|
||
|
++
|
|
--
|
,
|
->
|
->* ...
|
5. 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. Hay dos formas de
incluir un comentario en C++. El texto que hay entre // y el fin de lınea se
considera un comentario. Tambien es comentario el texto que se encuentra entre
los sımbolos /* y */. Los comentarios de este estilo no se pueden anidar.
Debe tenerse
cuidado para no encerrar trozos de codigo util dentro de un comen-tario, ya
que un comentario puede extenderse a lo largo de multiples lıneas. Encerrar
trozos de codigo como comentarios es util cuando se esta desarrollando un
programa para comprobar si ciertas partes funcionan o no, pero es un error muy
comun encerrar por descuido otras zonas de codigo que son necesarias o bien
olvidarse de sacar sentencias de dentro de un comentario.
6. Separadores
Son espacios en
blanco, tabuladores, retornos de carro, fin de fichero y fin de lınea. Habra ocasiones en que se pongan para dar legibilidad al programa, y otras por
necesidad. Los comentarios son considerados tambien separadores por el
compilador.
2.2.
Constantes,
variables y tipos de datos
En un programa intervienen objetos sobre los que actuan las
instrucciones que lo componen. Algunos de estos objetos tomaran 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, que tomar´ un valor al principio (zona
de declaraciones) y no se podra modificar a lo largo del programa.
Variable: Objeto,
referenciado por un identificador, que puede tomar distintos val-ores a lo
largo del programa.
Sera mision del programador asignar el identificador que desee a cada
constante y variable. El identificador o nombre de cada objeto sirve para
identificar sin ning´un tipo de ambig¨uedad a cada objeto, diferenciandolo de
los demas objetos que intervienen en el programa.
En C++ hay que 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. La declaracion tiene que encontrarse
en el codigo antes de cualquier instruccion que las use.
Al realizar las declaraciones de las variables, ademas de indicar su
identificador o nombre, hay que indicar explıcitamente el tipo de los datos
que pueden contener.
Un tipo determina la clase de valores que puede asumir una variable,
constante o expresion. Cada valor pertenece a un tipo. Sobre los tipos de
datos hay que destacar:
Importancia de
poseer tipo. Cada variable, constante y expresion tienen asocia-do un unico tipo. La informacion de tipo determina la representacion de los valores, y la
cantidad de espacio de memoria que debe serle asignado. Esa informacion
tambien determina la forma en que deben ser interpretados los operadores
aritmeticos, y permite al compilador detectar errores semanticos en aquellos
programas que contienen operaciones inapropiadas. El tipo de una variable no
solo determina el conjunto de valores que puede almacenar sino tambien el
conjunto de operaciones permitidas sobre dicha variable. Esto ultimo es el
principio fundamental de la programacion usando Tipos Abstractos de Datos
(TADs).
Cardinalidad. El numero de valores que tiene un
tipo de datos.
Operadores
b´asicos. A cada tipo se le asocia un conjunto de operadores b´asicos,
destinados a ser de utilidad en el dise˜no de programas y que, adem´as, tienen
por
lo menos una implementaci´on razonablemente
eficiente en un computador. Por supuesto, la selecci´on de operadores b´asicos
es, en cierta medida, arbitraria, y podr´ıa haberse aumentado o disminuido. El
principio que suele seguirse es posibilitar al programador construir cualquier
operaci´on adicional en funci´on de las b´asicas, y permitir hacerlo de una
forma eficiente. Las operaciones m´as importantes y m´as generales definidas
para los datos de cualquier tipo, son la asignaci´on (representada por =) y la
verificaci´on de igualdad (==).
Compatibilidad
de tipos. Cada operador act´ua sobre operandos de un mismo tipo, y da como
resultado un valor siempre de un mismo tipo determinado. Como ya se ha dicho la
informaci´on de tipo ayuda a los compiladores para detectar si se est´an
realizando operaciones inapropiadas con tipos de datos distintos. Cuando el
mismo s´ımbolo es aplicado para varios tipos distintos (por ejemplo + para la
suma de enteros y la de reales –se le llama operador sobrecargado–), dicho
s´ımbolo puede considerarse ambig¨uo, denotando varios operadores concretos
diferentes.
En un lenguaje
de programaci´on existen normalmente una serie de tipos de datos pre-definidos
(tipos b´asicos) que el programador puede utilizar directamente para declarar
variables. Por otro lado se pueden definir nuevos tipos propios para satisfacer
las necesi-dades particulares del programador. Los principales tipos de datos
predefinidos en C++ son:
El tipo int. N´umeros enteros.
El tipo bool. Valores l´ogicos Verdadero y
Falso.
El tipo char. Caracteres del c´odigo ASCII.
El tipo float. N´umeros reales.
Todos ellos
tienen dos propiedades en com´un: cada uno est´a formado por elemen-tos
indivisibles o at´omicos que adem´as est´an ordenados. Los tipos de datos con
estas caracter´ısticas se denominan tipos de datos escalares. Cuando decimos
que un valor es at´omico, nos referimos a que no contiene partes componentes a
las que pueda acceder-se independientemente. Por ejemplo, un car´acter es
indivisible, mientras que la cadena de caracteres ”Hola”no. Cuando hablamos de
que un conjunto de valores est´a ordena-do, queremos decir que los operadores
relacionales est´andares (<, >, ==, <=, >=, !=) pueden aplicarse a
aqu´ellos.
Todos estos
tipos, excepto float, poseen una propiedad adicional. Cada valor tiene un predecesor
y un sucesor unicos´ (excepto el primer y ultimo´ valor, respectivamente).
Los tipos de
datos escalares que tienen esta propiedad se denominan tipos de datos
ordinales. De los tipos de datos predefinidos s´olo el tipo float no es
ordinal, pues 0.0501 es el predecesor de 0.0502 con cuatro d´ıgitos de
precisi´on, pero 0.05019 es el predecesor de 0.05020 con un d´ıgito m´as de
precisi´on.
El tipo int
Los valores que pertenecen a este tipo son los n´umeros enteros. Los
operadores apli-cables a los enteros son:
+ suma
- resta
* producto
/ cociente de la division entera
% resto de la divisi´on entera.
Cada computador restringir´a el conjunto de valores de este tipo a un
conjunto finito de enteros, comprendido en el intervalo −2(N − 1) ... 2(N − 1) − 1, donde N es el
n´umero de bits que el computador usa para representar internamente un entero.
En nuestro caso, para el tipo int, N = 32, por lo que este rango es: -
2147483648 .. 2147483647. Se pueden definir variables para valores enteros con
un rango menor indi-cando que son de tipo short int. En nuestro compilador,
para los short int N = 16 y el rango es: -32768 .. 32767. Asimismo, long int
est´a pensado para un rango mayor de valores, pero en el caso de nuestro
compilador coincide con los int.
El tipo unsigned int
No es tipo independiente de int, sino una variaci´on de aqu´el. Sus
valores son los n´umeros enteros no negativos, esto es, los n´umeros naturales
(incluido el 0). Los oper-adores aplicables son los mismos que para int. La
ventaja de usar unsigned int en lugar de int es que hacemos expl´ıcito que una
determinada variable s´olo puede ser positiva. Adem´as de esto, si un
computador usa N bits para almacenar un entero, el rango de los valores
unsigned int ser´a 0...2N - 1, con lo que podemos almacenar un n´umero entero
positivo m´as grande que con el tipo int. En nuestro caso los rangos para unsigned
int y short unsigned int son, respectivamente: 0 .. 65535 y 0 .. 4294967295.
El tipo float
Los valores del
tipo float son los n´umeros reales. Los operadores disponibles son los b´asicos
anteriormente mencionados. La divisi´on se denota por /, siendo la divisi´on
real, no la entera. Las constantes de tipo float se caracterizan por tener un
punto decimal y, posiblemente, un factor de escala. Por ejemplo:
1.5 1.50 1.5E2 2.34E-2 0.0 0. 5.
Si se quieren representar n´umeros con mayor precisi´on, se puede usar
el tipo double. En C++ el mayor real representable es 3.40282347e+38F (6
d´ıgitos de precisi´on) y el
menor n´umero positivo distinto de 0 es
1.17549435e-38F.
El tipo bool
Un valor bool
es uno de los dos valores de verdad l´ogicos denotados por los iden-tificadores
est´andares del lenguaje: true y false (Verdadero y Falso). Las expresiones de
tipo bool son muy importantes en programaci´on. Estos valores no pueden leerse
o escribirse directamente desde el teclado o al monitor, al contrario de lo que
ocurre con los tipos num´ericos.
Cuando se
eval´ua una expresi´on en C++, cualquier valor distinto de 0 es considerado
true y 0 es considerado false.
El tipo char
Cada computador
se comunica con su entorno mediante alg´un dispositivo de entrada y salida.
Lee, escribe, o imprime elementos pertenecientes a un conjunto fijo de
carac-teres. Este conjunto constituye el rango de valores del tipo char. El
conjunto fijo de caracteres m´as estandarizado es el denominado ASCII (American
Standard Code for In-formation Interchange). Este conjunto est´a ordenado y
cada car´acter tiene una posici´on fija o n´umero ordinal.
Las constantes
de tipo char se denotan por el car´acter encerrado entre comillas sim-ples(’ ’).
Un valor car´acter puede ser asignado a una variable de tipo char, pero no
puede usarse en operaciones aritm´eticas. Sin embargo, las operaciones
aritm´eticas pueden apli-carse a sus n´umeros obtenidos por la funci´on de
cambio de tipo int(ch). De forma inversa el car´acter con el n´umero n
asociado, se obtiene con la funci´on est´andar char(n). Estas dos funciones se
complementan se relacionan con las ecuaciones:
int(char(ch)) = ch y char(int(n)) = n
Chequeo de
tipos
En C++ cada variable y constante tiene un tipo concreto, y cuando se
efect´ua una operaci´on, sus operandos deben tener el tipo apropiado.
En principio, y hasta que no presentemos las reglas para el uso de
tipos, supondremos que las operaciones s´olo est´an definidas entre operandos
del mismo tipo. Dos tipos son iguales si tienen el mismo nombre, y no si su
composici´on es la misma. Esto resultar´ es-pecialmente importante cuando se
trabaje con tipos de datos estructurados.
Si el programador necesita usar expresiones en las que los operandos
sean de distintos tipos, debe efectuar conversi´on de tipos expl´ıcita
(casting). Para ello se especifica el tipo al que se convierte y, entre
par´entesis, la expresi´on que se convierte.
int(Valor) //Convierte el parametro Valor al tipo int.
float(Valor) //Convierte el parametro Valor al tipo float.
etc...
Estructura de
un programa en C++
Comenzaremos
viendo la estructura global de un programa escrito en C++ para a continuaci´on
ir desglosando y analizando cada uno de sus componentes.
Esquema general
de un programa
//lista de inclusiones
//declaraciones globales
int main(int argc, char
*argv[])
{
//declaraciones locales
//sentencias de programa
}
Listas
de inclusiones
Dentro de un programa podemos necesitar algunos procesos que por ser muy
fre-cuentes est´an disponibles en el lenguaje y por tanto no nos debemos
preocupar de pro-gramarlos. Para ello hay que indicar expl´ıcitamente que
estamos incluyendo en nuestro programa los ficheros que contienen esos
recursos. Una l´ınea de inclusi´on consta de la expresi´on reservada #include y el nombre del
fichero a incluir entre los caracteres ’<’ y’>’:
Cuerpo del
programa
Es la zona del programa formada por las
sentencias a ejecutar, especific´andose los
pasos a seguir para la resoluci´on del problema.
En C++ hay diversos tipos
de sentencias:
|
|||
Asignaci´on
|
switch
|
for
|
exit
|
Llamada a funci´on
|
while
|
return
|
break
|
if
|
do-while
|
continue
|
Entre estas
sentencias no hay ninguna dedicada a entrada/salida (E/S). Lo que ocurre es que
la E/S en C++ se efect´ua mediante llamadas a procedimientos que hay que
importar mediante listas de inclusiones.
Los
procedimientos que se importan se encuentran en bibliotecas. Aunque existe un
conjunto est´andar de bibliotecas, cada compilador de C++ puede a˜nadir sus
propias librer´ıas predefinidas e informar de las caracter´ısticas de los
procedimientos que contiene.
´
Este es un aspecto a
revisar siempre que, a´un usando el mismo lenguaje, cambiemos de compilador.
<sec_sent> ::=
|
<sentencia>; {<sentencia>}
|
|
<sentencia> ::=
|
<sent_asignacion>
|
|
|
<llamada_funcion>
|
|
|
|
<sent_if>
|
|
|
|
<sent_switch>
|
|
|
|
<sent_while>
|
|
|
|
<sent_do_while>
|
|
|
<sent_for>
|
exit
|
break
|
continue
|
return[<expresion>]
|
<sent_vacia>
|
Asignacion
Es el operador que permite dar un valor a una
variable.
<sent_asignacion> ::= <variable> =
<expresion>
Ejemplo:
i = 10;
El operador de asignaci´on es ”=”, y se lee toma el valor. La variable
(izquierda) toma el valor de la expresi´on (derecha). Por defecto, las
variables, despu´es de haber sido declaradas, no tienen ning´un valor (est´an
indefinidas) y el programador debe encargarse de inicializarlas, es decir,
asignarles un valor conocido, en el caso de que se vaya a utilizar su
contenido.
En el lado izquierdo de la sentencia de asignaci´on s´olo puede haber
una variable. Se eval´ua la expresi´on de la derecha y el resultado se guarda
en la variable.
Las variables mantienen el valor que se les asigna hasta que cambian
mediante otra sentencia de asignaci´on (u otro mecanismo), momento en que
pierden el antiguo valor.
Expresiones
En los lenguajes de programaci´on el concepto de expresi´on es similar
al usado en matem´aticas. Una expresi´on ser´a un conjunto de operadores y
operandos que tras su evaluaci´on devolver´a un unico´ valor. Para saber el
resultado de una expresi´on debemos conocer la precedencia de los operadores,
es decir, el orden en el que se eval´uan dentro de la misma. De mayor a menor
precedencia, los operadores disponibles son:
!
* / % &&
+ - ||
== !=
< > <= >=
ENTRADA/SALIDA EN C++
|
13
|
En caso de igualdad de
precedencia se eval´uan de izquierda a derecha. Estas reglas
pueden alterarse mediante el uso de par´entesis.
Ejemplos:
|
||
A = 3
|
* B - 7
|
↔ A = (3*B)-7
|
A = 3 - B - C ↔ A
= (3-B)-C
|
||
A = 3
|
- B * 7
|
↔ A = 3-(B*7)
|
Entrada/salida
en C++
Trataremos por
el momento la entrada y salida de datos en forma de caracteres. En principio
supondremos que nuestros programas de C++ son procesos (programas en ejecución)
que toman información de un flujo de entrada y entregan información a un flujo
de salida, utilizando para ello dispositivos externos capaces de manejar información
en forma de caracteres organizados como una sucesión de líneas.
Se conocen como
flujos de entrada/salida estandares aquellos que se realizan con la pantalla y
con el teclado (E/S interactiva).
Otra
alternativa de comunicación con un programa consiste en preparar un fichero de
datos, por ejemplo en el disco, de donde el programa los pueda leer cuando los
necesite o grabar cuando tenga resultados ( E/S diferida).
En C++ las
instrucciones para efectuar E/S se encuentran en modulos de librea, es decir, módulos
preprogramados disponibles para el programador. A continuacion se describirán
algunas de las instrucciones de E/S interactiva contenidas en la librería
iostream.h.
Salida
Para enviar
datos a la salida por defecto (generalmente la pantalla del monitor del
ordenador), vamos a usar el flujo de salida cout. Este flujo se encuentra en el
fichero de biblioteca iostream.h. Aunque se pueden efectuar muchas operaciones
diferentes sobre este flujo, por ahora s´olo vamos a ver la operaci´on <<.
Esta operaci´on manda un valor al flujo cout. Este valor puede ser de cualquier
tipo. Ejemplo:
cout << "El
valor de la variable cuyo nombre es i es "; cout << i;
cout << endl;
El primer ejemplo escribe una cadena de
caracteres, el segundo el contenido de la variable i y en el tercero se escribe
el valor del caracter endl, lo que hace que se escriba una nueva lınea. Tambien
se pueden concatenar los valores que se vayan a mandar a la salida. La
siguiente instruccion equivale a las tres anteriores:
cout << "El valor de la variable cuyo
nombre es i es " << i << endl;
Entrada
Este apartado se refiere a todas aquellas instrucciones que hacen
posible introducir datos para que el programa los maneje. A continuación veremos
instrucciones que tambien se encuentran en el fichero de biblioteca iostream.h.
En este caso, el flujo de entrada en cin y la operacion que vamos a ver de
momento para la lectura de datos es >>. Como en el caso de la salida, el
parametro puede ser de cualquier tipo. Ejemplo:
int i, j; char c; cin
>> i; cin >> j; cin >> c;
Finalmente
vamos a se˜nalar algunas notas importantes que hay que tener en cuenta al hacer
entrada/salida interactiva:
·
Las entradas y salidas de nuestro programa tienen eco normalmente en el
monitor y se mezclan. El programador debe prever este efecto para que el
resultado sea legible.
·
El computador normalmente no se percata de lo que se teclea hasta pulsar
la tecla ENTER, quien provoca adem´as un salto de l´ınea en la pantalla. Por
tanto es posible una edici´on limitada de los valores que se est´an tecleando
(borrarlos, cambiarlos, etc...) antes de pulsar ENTER.
·
Hay otras instrucciones que permiten hacer una salida con formato para
que sea m´as visible, aunque por ahora no lo vamos a ver.
Ejemplos
1. Copiar (editar), compilar y
ejecutar el siguiente programa que permite introducir una medida en
cent´ımetros y muestra la medida equivalente en pulgadas (una pulgada mide 2,54
cent´ımetros).
ENTRADA/SALIDA EN C++
|
15
|
#include <iostream.h> #include <stdlib.h>
const float
cent_por_pulgada = 2.54;
int main()
{
float centimetros, pulgadas;
cout << "Teclee
una medida en centimetros\n"; cin >> centimetros;
pulgadas = centimetros /
cent_por_pulgada; // Calculo de pulgadas cout << "Sus "
<< centimetros << " centimetros equivalen a " <<
pulgadas <<
"pulgadas" << endl;
system("PAUSE"); return 0;
}
·
Escribir (editar), compilar y ejecutar el programa siguiente, que recibe
el radio de un c´ırculo y que muestra en pantalla el di´ametro, la longitud de
la circunferencia y el ´area de ese c´ırculo.
#include <iostream.h> #include <stdlib.h> const float PI =
3.14;
int main() {
float radio, diametro,
longitud, area;
cout << "Teclee
la medida del radio de la circunferencia en cm\n"; cin >> radio;
// C\’{a}lculos de magnitudes
diametro = 2.0 * radio; longitud = PI * diametro; area = PI * radio * radio;
// Salida de resultados
cout << "DATOS DEL CIRCULO:"
<< endl;
cout <<
"Radio introducido por el usuario: " << radio << "
cm" << endl;
cout <<
"Diametro de la circunferencia: " << diametro << "
cm" << endl;
cout <<
"Longitud de la circunferencia: " << longitud << "
cm" << endl;
cout << "Area de la circunferencia:
" << area << " cm2" << endl;
system("PAUSE");
return 0;
}
Comentarios
Publicar un comentario