B. Stroustrup - The C++ Programming Language (794319), страница 37
Текст из файла (страница 37)
There is no limit to the number of hexadecimal digits in the sequence. Asequence of octal or hexadecimal digits is terminated by the first character that is not an octal digitor a hexadecimal digit, respectively. For example:OctalHexadecimalDecimalASCII'\6''\60''\137''\x6''\x30''\x05f'64895ACK'0''_'This makes it possible to represent every character in the machine’s character set and, in particular,to embed such characters in character strings (see §7.3.2).
Using any numeric notation for characters makes a program nonportable across machines with different character sets.It is possible to enclose more than one character in a character literal, for example, 'ab'. Suchuses are archaic, implementation-dependent, and best avoided. The type of such a multicharacterliteral is int.When embedding a numeric constant in a string using the octal notation, it is wise always to usethree digits for the number.
The notation is hard enough to read without having to worry aboutwhether or not the character after a constant is a digit. For hexadecimal constants, use two digits.Consider these examples:char v1[] = "a\xah\129";char v2[] = "a\xah\127";char v3[] = "a\xad\127";char v4[] = "a\xad\0127";// 6 chars: 'a' '\xa' 'h' '\12' '9' '\0'// 5 chars: 'a' '\xa' 'h' '\127' '\0'// 4 chars: 'a' '\xad' '\127' '\0'// 5 chars: 'a' '\xad' '\012' '7' '\0'Wide character literals are of the form L'ab' and are of type wchar_t.
The number of charactersbetween the quotes and their meanings are implementation-defined.A C++ program can manipulate character sets that are much richer than the 127-characterASCII set, such as Unicode. Literals of such larger character sets are presented as sequences offour or eight hexadecimal digits preceded by a U or a u. For example:U'\UFADEBEEF'u'\uDEAD'u'\xDEAD'The shorter notation u'\uXXXX' is equivalent to U'\U0000XXXX' for any hexadecimal digit X. A number of hexadecimal digits different from four or eight is a lexical error.
The meaning of the hexadecimal number is defined by the ISO/IEC 10646 standard and such values are called universalcharacter names. In the C++ standard, universal character names are described in §iso.2.2,§iso.2.3, §iso.2.14.3, §iso.2.14.5, and §iso.E.6.2.4 Integer TypesLike char, each integer type comes in three forms: ‘‘plain’’ int, signed int, and unsigned int. In addition, integers come in four sizes: short int, ‘‘plain’’ int, long int, and long long int. A long int can bereferred to as plain long, and a long long int can be referred to as plain long long. Similarly, short isa synonym for short int, unsigned for unsigned int, and signed for signed int. No, there is no longshort int equivalent to int.Section 6.2.4Integer Types145The unsigned integer types are ideal for uses that treat storage as a bit array. Using an unsignedinstead of an int to gain one more bit to represent positive integers is almost never a good idea.Attempts to ensure that some values are positive by declaring variables unsigned will typically bedefeated by the implicit conversion rules (§10.5.1, §10.5.2.1).Unlike plain chars, plain ints are always signed.
The signed int types are simply more explicitsynonyms for their plain int counterparts, rather than different types.If you need more detailed control over integer sizes, you can use aliases from <cstdint> (§43.7),such as int64_t (a signed integer with exactly 64 bits), uint_fast16_t (an unsigned integer withexactly 8 bits, supposedly the fastest such integer), and int_least32_t (a signed integer with at least32 bits, just like plain int). The plain integer types have well-defined minimal sizes (§6.2.8), so the<cstdint> are sometimes redundant and can be overused.In addition to the standard integer types, an implementation may provide extended integer types(signed and unsigned). These types must behave like integers and are considered integer typeswhen considering conversions and integer literal values, but they usually have greater range(occupy more space).6.2.4.1 Integer LiteralsInteger literals come in three guises: decimal, octal, and hexadecimal.
Decimal literals are the mostcommonly used and look as you would expect them to:7123497612345678901234567890The compiler ought to warn about literals that are too long to represent, but an error is only guaranteed for {} initializers (§6.3.5).A literal starting with zero followed by x or X (0x or 0X) is a hexadecimal (base 16) number.
Aliteral starting with zero but not followed by x or X is an octal (base 8) number. For example:DecimalOctal263830020770123Hexadecimal0x00x20x3f0x63The letters a, b, c, d, e, and f, or their uppercase equivalents, are used to represent 10, 11, 12, 13, 14,and 15, respectively. Octal and hexadecimal notations are most useful for expressing bit patterns.Using these notations to express genuine numbers can lead to surprises. For example, on a machineon which an int is represented as a two’s complement 16-bit integer, 0xffff is the negative decimalnumber −1.
Had more bits been used to represent an integer, it would have been the positive decimal number 65535.The suffix U can be used to write explicitly unsigned literals. Similarly, the suffix L can be usedto write explicitly long literals. For example, 3 is an int, 3U is an unsigned int, and 3L is a long int.Combinations of suffixes are allowed. For example:cout << 0xF0UL << ' ' << 0LU << '\n';146Types and DeclarationsChapter 6If no suffix is provided, the compiler gives an integer literal a suitable type based on its value andthe implementation’s integer sizes (§6.2.4.2).It is a good idea to limit the use of nonobvious constants to a few well-commented const (§7.5),constexpr (§10.4), and enumerator (§8.4) initializers.6.2.4.2 Types of Integer LiteralsIn general, the type of an integer literal depends on its form, value, and suffix:• If it is decimal and has no suffix, it has the first of these types in which its value can be represented: int, long int, long long int.• If it is octal or hexadecimal and has no suffix, it has the first of these types in which its valuecan be represented: int, unsigned int, long int, unsigned long int, long long int, unsigned longlong int.• If it is suffixed by u or U, its type is the first of these types in which its value can be represented: unsigned int, unsigned long int, unsigned long long int.• If it is decimal and suffixed by l or L, its type is the first of these types in which its value canbe represented: long int, long long int.• If it is octal or hexadecimal and suffixed by l or L, its type is the first of these types in whichits value can be represented: long int, unsigned long int, long long int, unsigned long long int.• If it is suffixed by ul, lu, uL, Lu, Ul, lU, UL, or LU, its type is the first of these types in whichits value can be represented: unsigned long int, unsigned long long int.• If it is decimal and is suffixed by ll or LL, its type is long long int.• If it is octal or hexadecimal and is suffixed by ll or LL, its type is the first of these types inwhich its value can be represented: long long int, unsigned long long int.• If it is suffixed by llu, llU, ull, Ull, LLu, LLU, uLL, or ULL, its type is unsigned long long int.For example, 100000 is of type int on a machine with 32-bit ints but of type long int on a machinewith 16-bit ints and 32-bit longs.
Similarly, 0XA000 is of type int on a machine with 32-bit ints butof type unsigned int on a machine with 16-bit ints. These implementation dependencies can beavoided by using suffixes: 100000L is of type long int on all machines and 0XA000U is of typeunsigned int on all machines.6.2.5 Floating-Point TypesThe floating-point types represent floating-point numbers. A floating-point number is an approximation of a real number represented in a fixed amount of memory.
There are three floating-pointtypes: float (single-precision), double (double-precision), and long double (extended-precision).The exact meaning of single-, double-, and extended-precision is implementation-defined.Choosing the right precision for a problem where the choice matters requires significant understanding of floating-point computation. If you don’t have that understanding, get advice, take thetime to learn, or use double and hope for the best.6.2.5.1 Floating-Point LiteralsBy default, a floating-point literal is of type double. Again, a compiler ought to warn about floating-point literals that are too large to be represented. Here are some floating-point literals:Section 6.2.5.11.23.23Floating-Point Literals0.231.1.01.2e101.23e−15Note that a space cannot occur in the middle of a floating-point literal. For example, 65.43not a floating-point literal but rather four separate lexical tokens (causing a syntax error):65.43e−147e−21is21If you want a floating-point literal of type float, you can define one using the suffix f or F:3.14159265f2.0f2.997925F2.9e−3fIf you want a floating-point literal of type long double, you can define one using the suffix l or L:3.14159265L2.0L2.997925L2.9e−3L6.2.6 Prefixes and SuffixesThere is a minor zoo of suffixes indicating types of literals and also a few prefixes:Notation00xulll0XULLLfe.FE'u'U'L'"R"u8"u"U"L"u8R"uR"UR"LR"Arithmetic Literal Prefixes and Suffixes∗fixMeaningExampleReferenceISOprefixprefixsuffixsuffixsuffixsuffixinfixinfixprefixprefixprefixprefixprefixprefixprefixprefixprefixprefix§iso.2.14.2§iso.2.14.2§iso.2.14.2§iso.2.14.2§iso.2.14.2§iso.2.14.4§iso.2.14.4§iso.2.14.4§iso.2.14.3§iso.2.14.3§iso.2.14.3§iso.2.14.3§iso.2.14.5§iso.2.14.5§iso.2.14.5§iso.2.14.5§iso.2.14.5§iso.2.14.5octalhexadecimalunsignedlonglong longfloat07760xff10U20000L20000LLfloating-pointfloating-point10f10e−412.3charchar16_tchar32_twchar_t'c'u'c'U'c'L'c'stringraw stringUTF-8 stringUTF-16 stringUTF-32 stringwchar_t string"mess"R"(\b)"u8"foo"u"foo"U"foo"L"foo"§6.2.4.1§6.2.4.1§6.2.4.1§6.2.4.1§6.2.4.1§6.2.5.1§6.2.5.1§6.2.5.1§6.2.3.2§6.2.3.2§6.2.3.2§6.2.3.2§7.3.2§7.3.2.1§7.3.2.2§7.3.2.2§7.3.2.2§7.3.2.2Note that ‘‘string’’ here means ‘‘string literal’’ (§7.3.2) rather than ‘‘of type std::string.’’Obviously, we could also consider .
and e as infix and R" and u8" as the first part of a set ofdelimiters. However, I consider the nomenclature less important than giving an overview of thebewildering variety of literals.The suffixes l and L can be combined with the suffixes u and U to express unsigned long types.For example:148Types and Declarations1LU2UL3ULL4LLU5LULChapter 6// unsigned long// unsigned long// unsigned long long// unsigned long long// errorThe suffixes l and L can be used for floating-point literals to express long double. For example:1L1.0L// long int// long doubleCombinations of R, L, and u prefixes are allowed, for example, uR"∗∗(foo\(bar))∗∗".