=====C++ Data Types===== C++ programmers have access to the five data types for C: void, int, float, double, and char. ^Type^Description^ |''void''|associated with no data type| |''int''|integer| |''float''|floating-point number| |''double''|double precision floating-point number| |''char''|character| In addition, C++ defines two more: ''bool'' and ''wchar_t''. ^Type^Description^ |''bool''|Boolean value, true or false| |''wchar_t''|wide character| ====Type Modifiers==== Several of these types can be modified using the keywords ''signed'', ''unsigned'', ''short'', and ''long''. When one of these type modifiers is used by itself, a data type of ''int'' is assumed. A complete list of possible data types follows (equivalent types are displayed in the same row): ^integer types^^^^ |''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''|| ^floating point types^^^^ |''float''|||| |''double''|||| |''long double''|||| ^optionally supported integer types^^^^ |''long long''|''long long int''|''signed long long''|''signed long long int''| |''unsigned long long''||''unsigned long long in''t|| ====Type Sizes and Ranges==== The size and range of any data type is compiler and architecture dependent. You can use the [[keywords/sizeof]] operator to determine the size of any data type (frequently expressed as a number of bytes). However, many architectures implement data types of a standard size. ''ints'' and ''floats'' are often 32-bit, chars 8-bit, and ''doubles'' are usually 64-bit. ''bools'' are often implemented as 8-bit data types. ''long long'' type is 64-bit. The "cfloat" (or "float.h") header file defines the ranges for the floating types, the "climits" (or "limits.h") - for the integer types. Limits for numeric values are defined in the header. The templated values of [[limits/numeric_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()||smallest number that can be respresented (not the most negative)| |max()||largest number| |epsilon()||inherent representation error value| |round_error()||maximum rounding adjustment possible| |infinity()|| | |quiet_NaN()||invalid number that does not signal floating point error| |signaling_NaN()||invalid number that signals floating point error| |denorm_min()|| | |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|_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 std::cout << "Maximum short value: " << std::numeric_limits::max() << std::endl; std::cout << "Minimum short value: " << std::numeric_limits::min() << std::endl; ====Reading Type Declarations==== 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: - Start at the variable name (''d'' or ''foo'' in the examples above) - End with the data type (''double'' or ''char'' above) - Go right when you can, and left when you must. (Grouping parentheses can cause you to bounce left.) For example: ^Expression^Meaning^ | ''double %%**%%d[8];'' | | | ''double %%**%%d[8];'' | **d is ... double** | | ''double %%**%%d[8];'' | d is **an array of 8** ... double | | ''double **d[8];'' | d is an array of 8 **pointer to** ... double | | ''double %%**%%d[8];'' | d is an array of 8 pointer to **pointer to** double | Another example: ^Expression^Meaning^ | ''char *(*(%%**%%foo [][8])())[]'' | | | ''char *(*(%%**%%foo [][8])())[]'' | **foo is ... char** | | ''char *(*(%%**%%foo [][8])())[]'' | foo is **an array of** ... char | | ''char *(*(%%**%%foo [][8])())[]'' | foo is an array of **an array of 8** ... char | | ''char *(*(**foo [][8])())[]'' | foo is an array of an array of 8 **pointer to** ... char | | ''char *(*(%%**%%foo [][8])())[]'' | foo is an array of an array of 8 pointer to **pointer to** ... char | | ''char *(*(%%**%%foo [][8])())[]'' | foo is an array of an array of 8 pointer to pointer to **function returning** ... char | | ''char *(*(%%**%%foo [][8])())[]'' | foo is an array of an array of 8 pointer to pointer to function returning **pointer to** ... char | | ''char *(*(%%**%%foo [][8])())[]'' | foo is an array of an array of 8 pointer to pointer to function returning pointer to **array of** ... char | | ''char *(*(%%**%%foo [][8])())[]'' | 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]].