deas 2015

La utilidad de los programas "HelloWorld" mostrados en el artículo anterior de este Tutorial, es bastante cuestionable. Sí, realmente esto es así porque tuvimos que escribir varias líneas de código, para luego compilarlas y en seguida ejecutar el programa resultante, tan sólo para obtener una simple frase escrita en pantalla.
Muchas personas estarán de acuerdo con que habría sido mucho más fácil escribir la frase de salida nosotros mismos no?.
Sin embargo, la programación es mucho más que imprimir textos simples en pantalla señores.
Para ir un poco más allá y ser capaces de escribir programas que realicen tareas útiles y que realmente nos ahorren trabajo, necesitamos pues introducir el concepto de variables a nuestro estudio!.
Se lo explico de la siguiente manera: para comenzar, imaginemos que le pido que guarde en su mente el número 5 y luego pido que también memorice el número 2 al mismo tiempo. Usted acaba de almacenar 2 valores diferentes en su memória (el 5 y el 2), no es muy difícil. Ahora, si le pido que  añada 1 al primer número que le dije, debería entonces, estar conservando los números 6(5+1) y el número 2 en su memória; ya la cosa cambia y usted comienza a trabajar como lo haría un programa en C++.
Entonces podríamos, por ejemplo, restar los dos valores y obtener 4 como resultado.
a = 5;
b = 2;
a = a + 1;
resultado = a - b;
Es obvio que este ejemplo es muy simple, ya que hemos utilizado tan sólo 2 pequeños valores enteros integer, pero considere que su computadora puede almacenar millones de números como estos al mismo tiempo y llevar a cabo sofisticadas operaciones matemáticas con ellos.
¿Entendió esto?,
Pues entonces ahora podremos definir a una variable como una porción de memória para almacenar un valor, perfecto?.
Cada variable necesita un nombre que la identifique y la distinga entre las demás. Por ejemplo, en el código anterior los nombres de ellas eran a, b y resultado; pero podríamos haberlas llamado de cualquier otra forma; siempre y cuando consigan ser identificadores C++ válidos. ¿Qué son identificadores C++ válidos?

Identificadores C++ válidos

Un identificador C++ válido es una secuencia de una o más letras, dígitos o carácteres de subrayados (_). Los espacios, los signos de puntuación y los símbolos no pueden formar parte de un identificador. Además, los identificadores siempre comenzarán con una letra o con un carácter de subrayado(_).
Pero en la mayoría de los casos estos identificadores se consideran reservados para palabras claves específicas del compilador o identificadores externos, así como identificadores que contienen dos carácteres de subrayado sucesivos en cualquier lugar. En ningún caso pueden comenzar con un dígito.
C++ utiliza una serie de palabras claves para identificar operaciones y descripciones de datos; por lo tanto, los identificadores creados por un programador no pueden coincidir con estas palabras clave, que no se le olvide.
Las palabras clave estándar reservadas que no se pueden utilizar como identificadores creados por el programador son:

*alignas *alignof *and *and_eq  *asm *auto *bitand *bitor *bool *break 
*case *catch *char *char 16_t *char 32_t *class *compl *const *constexpr 
*const_cast *continue *decltype *default *delete *do *double *long *mutable 
*namespace *new *noexcept *not *not_eq *null_ptr *operator *or *or_eq 
*private *protected *public *register *reinterpret_cast *return *short 
*signed *sizeof *static *static_assert *static_cast *struct *switch *this 
*template *thread_local *throw *true *try *typedef *typeid *typename *union 
*unsigned *using *virtual *void *volatile *wchar_t *while *xor *xor_eq

Los compiladores específicos también pueden tener palabras clave específicas adicionales.
Muy Importante: El lenguaje C++ es un lenguaje "sensible a mayúsculas y minúsculas". Esto significa que un identificador escrito en mayúsculas no es equivalente a otro con el mismo nombre, escrito en minúsculas. Así por ejemplo, la variable RESULT no es lo mismo que la variable Result o la variable result; estos son 3 identificadores diferentes que identifican 3 variables diferentes.  

Tipos de Datos Fundamentales

Los valores de las variables se almacenan en algún lugar y en una ubicación que no es especificada, dentro de la memória del ordenador, todas ellas siendo ceros y unos.
Nuestro programa no necesita saber la ubicación exacta donde se almacena una variable, este simplemente puede referirse a ella por su nombre y usarla como quiera.
Lo que el programa necesita realmente saber es el tipo de datos almacenados en la variable. No es lo mismo almacenar un entero simple que almacenar una letra o un número de punto flotante grande; a pesar de que todos están representados con ceros y unos, no se interpretan de la misma manera y en muchos casos, no ocupan la misma cantidad de memória.
Los tipos de datos fundamentales: son tipos básicos implementados directamente por el lenguaje,  los cuales representan unidades de almacenamiento básicas soportadas nativamente por la mayoría de los sistemas.
Pueden clasificarse principalmente en:
  • Primer Tipo: Caracteres: representan un solo carácter, como 'A' o '$'. El tipo más basico es char, que es un carácter de un byte. Otros tipos también se proporcionan para caracteres más amplios.
  • Segundo Tipo: Enteros numéricos: Pueden almacenar un valor de número entero, como por ejemplo: 7 ó 1024. Estos existen en una variedad de tamaños y pueden ser asignados(con signo - o +) o no asignados(sin formato, osea sin - ó +), dependiendo si soportan valores negativos o no.
  • Tercer Tipo: De punto Flotante: Pueden representar valores reales, como 3.14 ó 0.01; con diferentes niveles de precisión, dependiendo claro de cuál de los 3 tipos de punto flotante se utilize; que pueden ser: Float, Double ó Long Double.
  • Cuarto Tipo: Booleano: conocido en C++ como bool, sólo puede representar uno de los 2 estados: True ("verdadero") y False ("Falso").
Aquí les dejo una tabla que muestra los tipos fundamentales en C++:
Grupo Nombres de Tipos Notas sobre Tamaño/Precisión
Carácteres
char Exactamente un byte en tamaño. Por lo menos 8 bits.
char16_t No puede ser más pequeño que char. Al menos 16 bits.
char32_t No es más pequeño que char16_t. Al menos 32 bits.
wchart_t Puede representar el mayor conjunto de caracteres admitidos en C++.
Tipo Enteros (signed)
signed char El mismo tamaño que char. Al menos 8 bits. .
signed short int No es más pequeño que char. Al menos 16 bits.
signed int No más pequeño que short. Al menos 16 bits.
signed long int No es menor que int. Al menos 32 bits.
signed long long int No más pequeño que long. Al menos 64 bits.
Tipo Enteros (unsigned)
unsigned char (El mismo tamaño que sus homólogos signed)
unsigned short int
unsigned int
unsigned long int
unsigned long long int
Tipo de Puntos Flotantes
float
double Precisión no inferior al float
long double Precisión no inferior al double
Tipo Boolean
bool
Tipo Void
void Sin Almacenamiento
Puntero Nulo
decltype(nullptr)
Al analizar la tabla anterior debemos anotar que los nombres de ciertos tipos de enteros integer, pueden ser abreviados sin sus componentes asignados signed e int; osea sólo la parte que NO está con letra cursiva es necesaria para identificar el tipo, la parte que esta con letra cursiva es opcional.
Por ejemplo, signed short int puede ser abreviado como signed short, short int ó simplemente short; todos identifican el mismo tipo fundamental.
Dentro de cada uno de los grupos anteriores, la diferencia entre tipos es sólo su tamaño (es decir, cuanto ocupan de memória):
  • el primer tipo en cada grupo es el que menos memoria ocupa, osea es el más pequeño; 
  • mientras que el último de cada tipo corresponde al más grande por lo tanto el que ocupa más memoria. Siendo cada tipo mayor que el que lo precede en el mismo grupo.
  • Además de eso tenemos que tener en cuenta que los tipos en un mismo grupo tienen las mismas propiedades.
Observe en la tabla anterior que aparte de char (el cual tiene establecido un tamaño de un byte), ninguno de los tipos fundamentales tiene un tamaño estándar especificado (más un tamaño mínimo a lo mucho); entonces afirmamos que el tipo a veces no es requerido exactamente de este tamaño mínimo.
Esto de ninguna manera significa que estos tipos son de un tamaño indeterminado, lo que pasa es que no hay un tamaño estándar en todos los compiladores y máquinas; cada implementación del compilador puede especificar los tamaños de estos tipos, los cuales se ajustan mejor a la arquitectura en la que se va a ejecutar el programa en desenvolvimiento.
Esta especificacion de tamaño bastante genérica para los tipos es que le da al lenguaje C++ mucha más flexibilidad para adaptarse a un trabajo extraordinario en todo tipo de plataformas, hasta en las más actuales.
Los tamaños de tipo anteriores se expresan en bits; cuanto más bits tenga un tipo, más valores distintos puede representar; pero al mismo tiempo, también consumirá más espacio en memória:
Tamaño Valores Representables Únicos Observaciones
8-bit
256 = 28
16-bit
65 536 = 216
32-bit
4 294 967 296 = 232 (~4 billones)
64-bit
18 446 744 073 709 551 616 = 264 (~18 billones de billones)
Los tipos enteros integer al tener valores representables altos: significa que el rango de valores que estos pueden representar es mayor. Vamos a entender mejor esto, por ejemplo: un 16-bit unsigned integer podría representar 65 536 valores distintos en el rango de 0 a 65 535, mientras que su contrario osea el "no asignado" "unsigned" sería capaz de representar, en la mayoría de los casos, la mitad de estos valores ósea entre -32 768 y 32 767. Tenga en cuenta que el rango de valores positivos reduce aproximadamente a la mitad en tipos asignados signed en comparación con tipos no asignados unsigned, todo esto debido a que uno de los 16 bits se utiliza para el signo + ó - positivo ó negativo; esta es una diferencia relativamente modesta en el rango y rara vez se justifica el uso de tipos sin asignar unsigned basados puramente en el rango de valores positivos que puedan representar.
Para los tipos de puntos flotantes, el tamaño afecta su precisión, por tener más o menos bits para su valor significativo y exponente.
Las propiedades de los tipos fundamentales en un sistema particular y la implementación del compilador: pueden ser obtenidos usando la class numeric_limits (esto lo veremos en un capítulo posterior). Si por alguna razón, se necesitan tipos de tamaños específicos, la biblioteca define ciertos alias del tipo de tamaño fijo en el encabezado <cstdint>.
Los tipos descritos anteriormente (carácteres, enteros, punto flotantes y booleano) se conocen colectivamente como tipos aritméticos. Pero existen dos tipos fundamentales adicionales: vacío void, que identifica la falta de tipo; y el tipo nullptr que es un tipo especial de puntero. Ambos tipos serán discutidos más adelante en un próximo capítulo donde trataremos especificamente sobre punteros.

C++ admite una amplia variedad de tipos basados en los tipos fundamentales discutidos anteriormente; estos otros tipos se conocen como tipos de datos compuestos y son una de las principales fortalezas del lenguaje C++; estos los veremos también con más detalles en capítulos posteriores.

Declaración de Variables:

C++ es un lenguaje fuertemente tipado, y requiere pues que cada variable sea declarada con su tipo antes de su primer uso. Esto informará al compilador dos cosas importantes:
  • el tamaño a reservar en memoria para esta variable y
  • cómo interpretar su valor. 
La sintaxis para declarar una variable en C++ es sencilla, simplemente escribimos el tipo seguido por el nombre de la variable(es decir, su identificador). Por ejemplo:
int a;
float minumero;
Estas son dos declaraciones de variables que son completamente válidas. La primera declara una variable del tipo int con el identificador a. El segundo declara una variable del tipo float con el identificador minumero. Una vez declaradas, las variables a y minumero se podran utilizar en el resto del ámbito scope del programa. En el caso de que usted quiera declarar más variables del mismo tipo, estas podrán escribirse separando sus identificadores con comas. Aquí un ejemplo:
int a, b, c;
Esto declara 3 variables (a, b y c), todas ellas de tipo int y tiene exactamente el mismo significado que:
int a;
int b;
int c;
Para ver cómo se ven las declaraciones de variables en acción dentro de un programa, echemos un vistazo a todo el código C++ del ejemplo sobre su memória mental propuesto al principio de este artículo:

//Operación con variables

#include <iostream>
using namespace std;

int main ()
{
  // declarando variables
    int a, b;
    int resultado;

  // procesando:
    a = 5;
    b = 2;
    a = a + 1;
    resultado = a - b;
  
  // imprimiento el resultado en pantalla
    cout << resultado;

  // cerrando el programa
    return 0;
}

No se preocupe si algo diferente a las declaraciones de las variables le parece extraño. La mayor parte se explicará con mayor profundidad en los próximos capítulos.

Inicialización de variables 

Cuando se declararon las variables en el ejemplo anterior, estas tuvieron un valor indeterminado hasta que le asignamos un valor por primera vez.
Pero, ¿es posible que una variable tenga un valor específico desde el momento en que se declara?, sí claro,  a esto justamente se le llama inicialización de una variable!
En el lenguaje C++, hay tres maneras de inicializar una variable. Todas equivalentes y recuerdan la evolución del lenguaje a lo largo de los años:
  • El primero, conocido como inicialización c-like (debido a que se hereda del lenguaje C), este consiste en anexar un signo igual seguido del valor desde el cual se inicia la variable:

tipo identificador = valor_inicial;
Por ejemplo si queremos:
  • declarar una variable del tipo int llamada x e inicializarla con un valor de 0 desde el mismo momento en que se declara, escribiremos esto:
int x = 0;
  • Un segundo método, conocido como inicialización del constructor (introducido por el lenguaje C++), incluye el valor inicial entre paréntesis ().
tipo identificador (valor_inicial)
Por ejemplo:
int x (0);
  • Por último, tenemos un tercer método, conocido como Inicialización Uniforme, que es similar al anterior, pero con llaves en lugar de paréntesis (este fué introducido por la revisión de la norma C++, en 2011):
tipo identificador {valor_inicial};
Por ejemplo:
int x {0};
Las 3 formas de inicializar variables son válidas y equivalentes en C++, no se le olvide de aprenderlas de manera firme!:

Deducción de Tipos : auto y decltype

Cuando una nueva variable es inicializada, el compilador puede descubrir cual es el tipo de variable de forma automática, todo por medio del inicializador; ¿sabías? pues sí, así es. 
Para esto, simplemente basta usar auto  como el especificador del tipo para la variable Por ejemplo:

int foo = 0;
auto bar = foo;    // esto es lo mismo que: int bar = foo; 
Aqui, la variable bar es declarada como teniendo un tipo auto; por lo tanto, el tipo de bar es el tipo de valor utilizado para iniciarla: en este caso utiliza el tipo de foo, que es int.
Las variables que no se inicializan también pueden hacer uso de la deducción de tipo, pero estas utilizaran el especificador decltype:
int foo = 0;
decltype(foo) bar;    // esto es lo mismo que: int bar;
Aquí, se declara que bar tiene el mismo tipo que foo.
auto y decltype son potentes funciones que fueron recientemente agregadas al lenguaje C++.
Pero las características de deducción de tipo que introducen están destinadas a ser utilizadas cuando el tipo no se puede obtener por otros medios o cuando se utiliza para mejorar la legibilidad del código. Estos dos ejemplos encima indicados, no son probablemente ninguno de estos casos. De hecho, probablemente disminuyen la legibilidad, ya que al leer el código, uno tiene que buscar el tipo de foo para saber realmente el tipo de bar. Mas detalles de este tema los encontraremos en un capítulo posterior, donde iremos paso a paso aprofundandonos!.

Introducción a Strings

Los tipos fundamentales representan los tipos más básicos manejados por máquinas donde se puede ejecutar código. Pero uno de los principales puntos fuertes del lenguaje C++ es su rico conjunto de tipos compuestos, de los cuales los tipos fundamentales son simples bloques de construcción!
Un ejemplo de tipo compuesto es la class string. Las variables de este tipo compuesto son capaces de almacenar secuencias de caracteres, tales como palabras u oraciones. Una característica muy útil!.
Una primera diferencia con los tipos de datos fundamentales es que para declarar y utilizar objetos (variables) de este tipo, el programa debe incluir el header(encabezado)  donde se definirá el tipo dentro de la biblioteca estándar (header <string>: #include <string>), veamos un ejemplo práctico de esto:
Como puede usted ver en este ejemplo, los strings se pueden inicializar con cualquier literal de string válido, así como las variables de tipo numérico que se pueden inicializar con cualquier literal numérico válido. Al igual que con los tipos fundamentales, todos los formatos de inicialización son válidos con string:

string mistring = "Esta es una string";
string mistring ("Esta es una string");
string mistring {"Esta es una string"};
¿Los strings pueden realizar todas las otras operaciones básicas que los tipos fundamentales?, claro que sí!, estos por ejemplo pueden ser declarados sin un valor inicial y cambiar su valor durante la ejecución:

Nota Importante

Al insertar el manipulador endl se termina la línea (y lo que hace este es imprimir un carácter de nueva línea vaciando el búfer stream).
Como antes afirmamos la class string es un tipo compuesto no lo olvidemos. 
Como podemos ver en el ejemplo anterior, los tipos compuestos se utilizan de la misma manera que los tipos fundamentales: la misma sintaxis se utiliza para declarar variables y para inicializarlas.
Para obtener más detalles sobre strings de C++ estándar, consulte este site.
Culminado y entendido este paso, habremos llegado a una parte importante de conocimientos para empezar a trabajar con C++, no podemos desistir si queremos llegar a desenvolver cualquier cosa con este maravilloso lenguaje!, más adelante veremos lo que son las Constantes en este lenguaje con lo cual iremos practicando con varios programas más complejos. No deje de practicar, eso es vital!

Publicar un comentario

Con la tecnología de Blogger.