Programadores de C++ tem acesso, ou podem se utilizar, dos 5 tipos de dados da linguagem C: 'void', 'int', 'float', 'double' e 'char'.
| Tipo | Descrição |
|---|---|
| void | não é associado a nenhum tipo de dado |
| int | número inteiro |
| float | número fracionário (“ponto flutuante”) |
| double | número fracionário de precisão dupla |
| char | caractere |
Além destes, o C++ define mais dois: 'bool' e 'wchar_t'.
| Tipo | Descrição |
|---|---|
| bool | Valor Booleano: 'true' ou 'false' (verdadeiro ou falso) |
| wchar_t | caractere wide (?) |
Vários desses tipos podem ser modificados usando-se as palavras-chave 'signed', 'unsigned', 'short' e 'long'. Quando um desses modificadores de tipo é usado sozinho (isto é, sem definir um tipo de dados), o tipo 'int' é considerado. Isto é, se você definir uma váriavel usando apenas o modificador 'short', o compilador vai interpretar como 'short int'. Uma lista completa dos tipos de dados possíveis segue abaixo (tipos equivalentes são mostrados na mesma linha):
| tipos inteiros | |||
|---|---|---|---|
| bool | |||
| char | |||
| signed char | |||
| unsigned char | |||
| wchar_t | |||
| short | short int | signed short | signed short int |
| unsigned short | unsigned short int | ||
| int | signed | signed int | |
| unsigned | unsigned int | ||
| long | long int | signed long | signed long int |
| unsigned long | unsigned long int | ||
| tipos fracionários | |||
| float | |||
| double | |||
| long double | |||
| tipos inteiros com suporte opcional | |||
|---|---|---|---|
| long long | long long int | signed long long | signed long long int |
| unsigned long long | unsigned long long int | ||
O tamanho e o intervalo de qualquer tipo de dados é compilador e dependente da arquitetura. Você pode usar o operador sizeof para determinar o tamanho de qualquer tipo de dados (expresso em bytes). No entanto, muitas arquiteturas implementam tipos de dados de um tamanho padrão. ints e floats são normalmente 4-byte (32-bit), chars 1-byte (8-bit), e doubles são normalmente 8-byte (64-bit). Booleanos são freqüentemente implementados como tipos de dados 1-byte (8-bit), apesar de só usar um bit para armazenamento do valor, true ou false. O tipo long long é 8-byte (64-bit). O header <cfloat> (ou “float.h”), define os intervalos para os tipos numéricos de ponto flutuante, e o <climits> (ou “limits.h”) para os tipos numéricos inteiros.
Limits for numeric values are defined in the <limits> header. The templated values of limits provide system-dependant numerical representations of the C++ data types. Use the appropriate function given the data type as the template argument as shown in the table below. Note that numeric_limits can be overloaded for user-defined types as well.
| Method or constant | Return | Description |
|---|---|---|
| is_specialized | bool | |
| radix | int | base of exponent |
| digits | int | number of radix digits in mantissa |
| digits10 | int | number of base 10 digits in mantissa |
| is_signed | bool | |
| is_integer | bool | |
| is_exact | bool | |
| min() | <type> | smallest number that can be respresented (not the most negative) |
| max() | <type> | largest number |
| epsilon() | <type> | inherent representation error value |
| round_error() | <type> | maximum rounding adjustment possible |
| infinity() | <type> | |
| quiet_NaN() | <type> | invalid number that does not signal floating point error |
| signaling_NaN() | <type> | invalid number that signals floating point error |
| denorm_min() | <type> | |
| min_exponent | int | |
| min_exponent10 | int | |
| max_exponent | int | |
| max_exponent10 | int | |
| has_infinity | bool | |
| has_quiet_NaN | bool | |
| has_signaling_NaN | bool | |
| has_denorm | <type>_denorm_style | |
| has_denorm_loss | bool | |
| is_iec559 | bool | conforms to IEC-559 |
| is_bounded | bool | |
| is_modulo | bool | |
| traps | bool | |
| tinyness_before | bool | |
| round_style | float_round_style { round_to_nearest, … } |
The most common usage is in bounds checking, to determine the minimum and maximum values a data type can hold. The following code prints out the minimum and maximum values for a short on the system it is run.
#include <limits> std::cout << "Maximum short value: " << std::numeric_limits<short>::max() << std::endl; std::cout << "Minimum short value: " << std::numeric_limits<short>::min() << std::endl;
Simple type declarations are easy to understand:
int i
However, it can be tricky to parse more complicated type declarations:
double **d[8] // hmm... char *(*(**foo [][8])())[] // augh! what is foo?
To understand the above declarations, follow three rules:
d or foo in the examples above)double or char above)For example:
| Expression | Meaning |
|---|---|
double **d[8]; | |
| d is … double |
| d is an array of 8 … double |
| d is an array of 8 pointer to … double |
| d is an array of 8 pointer to pointer to double |
Another example:
| Expression | Meaning |
|---|---|
char *(*(**foo [][8])())[] | |
| foo is … char |
| foo is an array of … char |
| foo is an array of an array of 8 … char |
| foo is an array of an array of 8 pointer to … char |
| foo is an array of an array of 8 pointer to pointer to … char |
| foo is an array of an array of 8 pointer to pointer to function returning … char |
| foo is an array of an array of 8 pointer to pointer to function returning pointer to … char |
| foo is an array of an array of 8 pointer to pointer to function returning pointer to array of … char |
| foo is an array of an array of 8 pointer to pointer to function returning pointer to array of pointer to char |
For a much more detailed explanation, see Steve Friedl's excellent description of how to read C declarations at http://www.unixwiz.net/techtips/reading-cdecl.html.