Introducción al sistema de los tipos de datos en C++14
El sistema de tipos de datos en C++14 es una parte fundamental del lenguaje que permite a los programadores definir y manipular diferentes tipos de información de manera eficiente y segura. C++14, una versión del estándar C++ publicada en 2014, introduce varias mejoras y nuevas características que refinan y amplían las capacidades del sistema de tipos de datos.
Tipos de Datos Fundamentales
En C++14, los tipos de datos fundamentales incluyen:
- Tipos Enteros: int, short, long, long long, unsigned int, unsigned short, unsigned long, unsigned long long.
- Tipos de Punto Flotante: float, double, long double.
- Tipos de Carácter: char, wchar_t, char16_t, char32_t.
- Tipos Booleanos: bool.
- Tipos Vacíos: void.
A cada tipo de dato se le suele asignar un valor, estos valores en el común de los casos se suelen usar para cálculos, almacenar o imprimir valores. Estos valores están limitados por el tipo de dato asignado. El rango típico puede variar dependiendo de la arquitectura del hardware y software, así como del compilador.
Tipos Enteros
En C++14, los tipos de enteros tienen rangos definidos por la implementación del compilador, pero el estándar proporciona límites mínimos garantizados para cada tipo.
- signed
char: De-127a127(mínimo garantizado, pero suele ser-128a127en la mayoría de las implementaciones) - unsigned
char: De0a255 - char: Típicamente de
-128a127o de0a255. Puede variar su comportamiento y actuar como signed char e incluso como unsigned char, dependiendo de su implementación, así como del entorno en que se desarrollar, compila y ejecuta. - short: De
-32767a32767(mínimo garantizado, pero suele ser-32768a32767) - unsigned
short: de
0a65535 - int: De
-32767a32767(mínimo garantizado, pero suele ser-2147483648a2147483647) - unsigned
int: de
0a65535(mínimo garantizado, pero suele ser de0a4294967295) - long: de
-2147483647a2147483647(mínimo garantizado, pero suele ser-2147483648a2147483647) - unsigned
long: de
0a4294967295 - long
long: de
-9223372036854775807a9223372036854775807(mínimo garantizado, pero suele ser-9223372036854775808a9223372036854775807) - unsigned
long
long: de
0a18446744073709551615
El tipo char es considerado un tipo entero. Aunque se usa principalmente para almacenar caracteres, técnicamente es un tipo entero con un tamaño mínimo de 8 bits (1 byte), lo cual le permite almacenar valores numéricos en el rango adecuado.
#include <iostream>
int main() {
// signed char
signed char sc = -128;
std::cout << "signed char: " << static_cast<int>(sc) << std::endl;
// unsigned char
unsigned char uc = 255;
std::cout << "unsigned char: " << static_cast<int>(uc) << std::endl;
// char
char c = 127;
std::cout << "char: " << static_cast<int>(c) << std::endl;
// short
short s = -32768;
std::cout << "short: " << s << std::endl;
// unsigned short
unsigned short us = 65535;
std::cout << "unsigned short: " << us << std::endl;
// int
int i = -32767;
std::cout << "int: " << i << std::endl;
// unsigned int
unsigned int ui = 65535;
std::cout << "unsigned int: " << ui << std::endl;
// long
long l = -2147483647;
std::cout << "long: " << l << std::endl;
// unsigned long
unsigned long ul = 4294967295;
std::cout << "unsigned long: " << ul << std::endl;
// long long
long long ll = -9223372036854775807;
std::cout << "long long: " << ll << std::endl;
// unsigned long long
unsigned long long ull = 18446744073709551615;
std::cout << "unsigned long long: " << ull << std::endl;
system("pause");
return 0;
}
Resultado:
static_cast es una
operación de conversión de tipos en C++ que se utiliza para realizar
conversiones explícitas entre tipos relacionados. En el contexto de los
tipos de enteros, static_cast se utiliza para convertir un valor de un tipo a otro tipo de manera segura y explícita.
std::cout interpreta los tipos char, signed
char y unsigned
char como caracteres, no como valores numéricos. Esto significa que si intentas imprimir directamente un valor de estos tipos, std::cout mostrará el carácter correspondiente en lugar del valor numérico.
// Se usa para añadir comentarios, todo lo escrito en el comentario será ignorado por el compilador y no se verá reflejado de ninguna manera en el programa, y tiene generalmente el propósito de ayudar a la persona que está leyendo el código a tener una mayor comprensión de este. El programa puede funcionar sin necesidad de ellos.
Estos son los tamaños en bytes de los tipos de enteros en C++14, según lo definido por el estándar y lo que es común en la mayoría de las implementaciones:
signed char: 1 byte
unsigned char: 1 byte
char: 1 byte
short: 2 bytes
unsigned short: 2 bytes
int: 4 bytes
unsigned int: 4 bytes
long: 4 bytes (en sistemas de 32 bits) o 8 bytes (en sistemas de 64 bits)
unsigned long: 4 bytes (en sistemas de 32 bits) o 8 bytes (en sistemas de 64 bits)
long long: 8 bytes
unsigned long long: 8 bytes
Puedes usar el operador sizeof en C++ para verificar los tamaños en bytes de estos tipos:
#include <iostream>
int main() {
std::cout << "sizeof(signed char): " << sizeof(signed char) << " bytes" << std::endl;
std::cout << "sizeof(unsigned char): " << sizeof(unsigned char) << " bytes" << std::endl;
std::cout << "sizeof(char): " << sizeof(char) << " bytes" << std::endl;
std::cout << "sizeof(short): " << sizeof(short) << " bytes" << std::endl;
std::cout << "sizeof(unsigned short): " << sizeof(unsigned short) << " bytes" << std::endl;
std::cout << "sizeof(int): " << sizeof(int) << " bytes" << std::endl;
std::cout << "sizeof(unsigned int): " << sizeof(unsigned int) << " bytes" << std::endl;
std::cout << "sizeof(long): " << sizeof(long) << " bytes" << std::endl;
std::cout << "sizeof(unsigned long): " << sizeof(unsigned long) << " bytes" << std::endl;
std::cout << "sizeof(long long): " << sizeof(long long) << " bytes" << std::endl;
std::cout << "sizeof(unsigned long long): " << sizeof(unsigned long long) << " bytes" << std::endl;
system("pause");
return 0;
}
Resultado:
********************
En C++14, los tipos de punto flotante son fundamentales para la representación de números con decimales y para realizar cálculos matemáticos precisos. Estos tipos se utilizan en una amplia variedad de aplicaciones, desde simulaciones científicas hasta gráficos y juegos. Los tipos de punto flotante en C++14 incluyen float, double y long double, cada uno con diferentes niveles de precisión y rango.
float:
Precisión: Aproximadamente 6-7 dígitos decimales.
Rango: Desde aproximadamente 1.2 por 10 elevado a -38 hasta 3.4 por 10 elevado a 38.
Memoria: Generalmente ocupa 4 bytes de memoria.
double:
Precisión: Aproximadamente 15-16 dígitos decimales.
Rango: Desde aproximadamente 2.2 por 10 elevado a -308 hasta 1.8 por 10 elevado a 308.
Memoria: Generalmente ocupa 8 bytes de memoria.
long double:
Precisión: Aproximadamente 18-19 dígitos decimales (puede variar según el compilador y la arquitectura).
Rango: Desde aproximadamente 3.4 por 10 elevado a -4932 hasta 1.2 por 10 elevado a 4932.
Memoria: Su tamaño puede variar dependiendo del compilador y la arquitectura del sistema, pero generalmente ocupa 10, 12 o 16 bytes de memoria.
La precisión se refiere al número de dígitos significativos que un tipo de punto flotante puede representar. En otras palabras, es la cantidad de dígitos que se pueden almacenar de manera precisa en el número. Fuera de los dígitos significativos los valores pueden variar considerablemente, y son generalmente un aproximado del valor real. Esto quiere decir que tendrás un mínimo de precisión garantizado.
#include <iostream>
int main() {
float numeroFloat = 3.14f;
double numeroDouble = 3.14;
long double numeroLongDouble = 3.14L;
std::cout << "Valor de float: " << numeroFloat << std::endl;
std::cout << "Valor de double: " << numeroDouble << std::endl;
std::cout << "Valor de long double: " << numeroLongDouble << std::endl;
system("pause");
return 0;
}
Resultado:
float
numeroFloat = 3.14f;: Aquí declaramos una variable de tipo float y le asignamos el valor 3.14. El sufijo f indica que el literal es de tipo float. Sin el sufijo, el literal se considera de tipo double.double
numeroDouble = 3.14;: Aquí declaramos una variable de tipo double y le asignamos el valor 3.14. Los literales de punto flotante sin sufijo se consideran de tipo double por defecto.
long
double numeroLongDouble = 3.14L;: Aquí declaramos una variable de tipo long
double y le asignamos el valor 3.14. El sufijo L indica que el literal es de tipo long
double. Sin el sufijo, el literal se considera de tipo double.
Los valores se convierte implícitamente al tipo de variable al cual se le está siendo asignando un valor. Por ejemplo, si asignas un valor de tipo double a una variable definida como tipo float, el valor de tipo double se convertirá implícitamente al de tipo float.
En C++, puedes usar la función typeid de la librería <typeinfo> para obtener el tipo de una variable y luego imprimirlo en la consola. <typeinfo> es parte de la librería estándar de C++14.
#include <iostream>
#include <typeinfo>
int main() {
float numeroFloat = 3.14;
double numeroDouble = 3.14L;
long double numeroLongDouble = 3.14f;
std::cout << "Valor de float: " << numeroFloat << ", Tipo: " << typeid(numeroFloat).name() << std::endl;
std::cout << "Valor de double: " << numeroDouble << ", Tipo: " << typeid(numeroDouble).name() << std::endl;
std::cout << "Valor de long double: " << numeroLongDouble << ", Tipo: " << typeid(numeroLongDouble).name() << std::endl;
system("pause");
return 0;
}
Resultado:
Se escribe el encabezado #include <typeinfo> para habilitar el uso de las funciones de esta librería, como typeid.
.name() es el método usado para adquirir el valor devuelto de la cadena que representa el nombre del tipo asignado como argumento de typeid, typeid(argumento). El formato de esta cadena puede variar dependiendo del compilador. Algunos compiladores pueden devolver nombres de tipos que no son muy legibles. Sin embargo, en la mayoría de los casos, deberías poder identificar claramente los tipos de datos.
En este ejemplo se asignaron datos con sufijos diferentes al tipo de variable definidos, concluyendo en una conversión implícita de los datos asignados al tipo de variable definido.
*****************
En C++14 podemos trabajar con diferentes tipos de datos de caracteres para manejar caracteres con distintos rangos de representaciones.
char: Este tipo maneja caracteres ASCII (7 bits), con un rango de 0 a 127.
wchar_t: Este tipo puede manejar caracteres Unicode básicos (16 bits en muchas implementaciones, como Windows).
char16_t: Este tipo maneja caracteres Unicode usando 16 bits (UTF-16).
char32_t: Este tipo maneja caracteres Unicode usando 32 bits (UTF-32).
#include <iostream>
#include <locale>
int main() {
char ascii_char = 'A';
wchar_t wide_char = L'Á';
std::locale::global(std::locale(""));
std::cout << "ASCII char: " << ascii_char << '\n';
std::wcout << L"Wide char: " << wide_char << '\n';
system("pause");
return 0;
}
Resultado:
#include <locale> incluye la librería de localización, que permite configurar la localización del programa para manejar diferentes configuraciones regionales. <locale> es parte de la librería estándar de C++14.
char
ascii_char = 'A' declara una variable de tipo char llamada ascii_char y la inicializa con el carácter 'A'.
wchar_t
wide_char = L'Á' declara una variable de tipo wchar_t llamada wide_char y la inicializa con el carácter 'Á'. El prefijo L indica que es un carácter ancho (wide character). Los caracteres anchos son especialmente útiles para representar
caracteres que no están en el conjunto de caracteres de tipo char, como
caracteres acentuados, caracteres de idiomas no latinos (por ejemplo,
chino, japonés, árabe), y otros símbolos especiales.
std::locale::global(std::locale("")) establece la localización global del programa a la localización
predeterminada del sistema. Esto permite que el programa maneje
correctamente caracteres y configuraciones regionales específicas del
sistema.
std::cout
<<
"ASCII
char: "
<<
ascii_char <<
'\n' imprime en la consola el texto "ASCII char: " seguido del valor de ascii_char y un salto de línea.
std::wcout
<<
L"Wide
char: "
<<
wide_char <<
'\n' imprime en la consola el texto "Wide char: " seguido del valor de wide_char y un salto de línea. std::wcout se utiliza para imprimir caracteres anchos.
**********
El tipo bool se introdujo en C++ para representar valores booleanos, normalmente se usan para manejar los tipos de estados "verdado" y "falso".
#include <iostream>
int main() {
bool LuzEncendida = true;
if (LuzEncendida==true) {
std::cout << "La luz sigue encendida." << std::endl;
}
else {
std::cout << "La luz ya no sigue encendida." << std::endl;
}
system("pause");
return 0;
}
Resultado:
#include <iostream>
int main() {
bool LuzEncendida = false;
if (LuzEncendida==true) {
std::cout << "La luz sigue encendida." << std::endl;
}
else {
std::cout << "La luz ya no sigue encendida." << std::endl;
}
system("pause");
return 0;
}
Resultado:
bool LuzEncendida = true declara una variable de tipo bool llamada LuzEncendida y se le asigna el valor true.
if es una condición que verifica si LuzEncendida es true. Si es así, imprime "La luz sigue encendida." en la consola. Si LuzEncendida no es true (es decir, es false), entonces se activa else en lugar de if y se imprime "La luz ya no sigue encendida." en la consola.
*********
En C++14, los tipos de datos vacíos son una característica que permite definir clases, estructuras y otros para que no contengan ningún dato como miembro. Estos tipos vacíos pueden ser utilizados en la implementación de patrones de diseño, en la optimización de memoria y en la creación de tipos de datos marcadores (tags) que no requieren almacenamiento. Los tipos de datos vacíos no ocupan espacio en memoria, lo que puede ser beneficioso en situaciones donde se necesita minimizar el uso de memoria. Esto es especialmente útil en sistemas embebidos o en aplicaciones donde el rendimiento es crítico.
Comentarios
Publicar un comentario