2-Variables and Basic Types

Please indicate the source: http://blog.csdn.net/gaoxiangnumber1

Welcome to my github: https://github.com/gaoxiangnumber1

  • Types determine the meaning of the data and operations.

2.1. Primitive Built-in Types

  • C++ defines a set of primitive types that include the arithmetic types and a special type named void.
    1. The arithmetic types represent characters, integers, boolean values, and floating-point numbers.
    2. The void type has no associated values and can be used in only a few circumstances, most commonly as the return type for functions that do not return a value.

2.1.1. Arithmetic Types

  • The arithmetic types are divided into two categories: integral types (which include character and boolean types) and floating-point types.

#include 

using std::cout;

int main()
{
    cout << "Character:\t" << sizeof(char) << '\t' << sizeof(wchar_t) << '\t' <<
         sizeof(char16_t) << '\t' << sizeof(char32_t) << '\n';

    cout << "Boolean:\t" << sizeof(bool) << '\n';

    cout << "Integer:\t" << sizeof(short) << '\t' << sizeof(int) << '\t' <<
         sizeof(long) << '\t' << sizeof(long long) << '\n';

    cout << "Floating-point:\t" << sizeof(float) << '\t' << sizeof(double) << '\t' <<
         sizeof(long double) << '\n';

    return 0;
}
/*
Output:
Character:      1   4   2   4
Boolean:        1
Integer:            2   4   8   8
Floating-point: 4   8   16
*/
  • The size of (i.e., the number of bits in) the arithmetic types varies across machines. The standard guarantees minimum sizes as listed in Table 2.1. Compilers are allowed to use larger sizes for these types. Because the number of bits varies, the largest (or smallest) value that a type can represent also varies.

  • The bool type represents the truth values true and false.
  • The basic character type is char. A char is the same size as a single machine byte, which is big enough to hold numeric values corresponding to the characters in the machine’s basic character set.
  • The remaining character types—wchar_t, char16_t, and char32_t—are used for extended character sets. The wchar_t type is guaranteed to be large enough to hold any character in the machine’s largest extended character set. The types char16_t and char32_t are intended for Unicode characters. (Unicode is a standard for representing characters used in any natural language.)
  • The remaining integral types represent integer values of different sizes. The language guarantees that an int will be at least as large as short, a long at least as large as an int, and long long at least as large as long. The type long long was introduced by the new standard(C++11).
  • The floating-point types represent single-, double-, and extended-precision values. The standard specifies a minimum number of significant digits. Typically, floats are represented in one word (32 bits), doubles in two words (64 bits), and long doubles in either three or four words (96 or 128 bits). The float and double types typically yield about 7 and 16 significant digits, respectively. The type long double is used as a way to accommodate special-purpose floating-point hardware; its precision varies from one implementation to another.

Machine-Level Representation of the Built-in Types

  • Computers store data as a sequence of bits, each holding a 0 or 1. Most computers deal with memory as chunks of bits of sizes that are powers of 2. The smallest chunk of addressable memory is referred to as a “byte.” The basic unit of storage, usually a small number of bytes, is referred to as a “word.”
  • In C++ a byte has at least as many bits as are needed to hold a character in the machine’s basic character set. On most machines a byte contains 8 bits and a word is either 32 or 64 bits, that is, 4 or 8 bytes.
  • Most computers associate an address with each byte in memory. On a machine with 8-bit bytes and 32-bit words, we might view a word of memory as follows: the byte’s address is on the left, with the 8 bits of the byte following the address.

  • We can use an address to refer to any of variously sized collections of bits starting at that address. The type determines how many bits are used and how to interpret those bits.

Signed and Unsigned Types

  • A signed type represents negative or positive numbers (including zero); an unsigned type represents only values greater than or equal to zero.
  • The types int, short, long, and long long are all signed. We obtain the corresponding unsigned type by adding unsigned to the type(unsigned short…). The type “unsigned int” can be abbreviated as unsigned.
  • There are three distinct basic character types: char, signed char, and unsigned char. char is not the same type as signed char. But there are only two representations: signed and unsigned. The char type uses one of these representations. Which of the other two character representations is equivalent to char depends on the compiler.
  • The standard does not define how signed types are represented, but does specify that the range should be evenly divided between positive and negative values. E.g., an 8-bit signed char is guaranteed to be able to hold values from –127 through 127; most modern machines use representations that allow values from –128 through 127.

Advice: Deciding which Type to Use

  • Use an unsigned type when you know that the values cannot be negative.
  • Use int for integer arithmetic. short is too small and long often has the same size as int. If your data values are larger than the minimum guaranteed size of an int, then use long long.
  • Do not use plain char or bool in arithmetic expressions. Use them only to hold characters or truth values. Computations using char are problematic because char is signed on some machines and unsigned on others. If you need a tiny integer, specify either signed char or unsigned char.
  • Use double for floating-point computations; float usually does not have enough precision, and the cost of double-precision calculations versus single-precision is negligible. The precision offered by long double usually is unnecessary and often entails considerable run-time cost.

Exercises Section 2.1.1

Exercise 2.1

What are the differences between int, long, long long, and short? Between an unsigned and a signed type? Between a float and a double?

  • C++ guarantees short and int is at least 16 bits, long at least 32 bits, long long at least 64 bits.
  • The signed can represent positive numbers, negative numbers and zero, while unsigned can only represent numbers no less than zero.
  • The C and C++ standards do not specify the representation of float, double and long double. It is possible that all three implemented as IEEE double‐precision. For most architectures, float is a IEEE single-precision floating point number (binary32), and double is a IEEE double-precision floating point number (binary64).

Exercise 2.2

To calculate a mortgage payment, what types would you use for the rate, principal, and payment? Explain why you selected each type.

  • Use double, or float. The rate like that: 4.50% per year. The principal like that: 854.36.Thepaymentlikethat: 1,142.36

2.1.2. Type Conversions

  • Type conversions happen automatically when we use an object of one type where an object of another type is expected.
#include 

using std::cout;
using std::endl;

int main()
{
    bool bool1 = -1, bool2 = 0;  // bool1 is true, bool2 is false.
    cout << bool1 << '\t' << bool2 << endl;
    int int1 = bool1, int2 = bool2;  // int1 is 1, int2 is 0.
    cout << int1 << '\t' << int2 << endl;
    int1 = 3.14;  // int1 is 3.
    cout << int1 << endl;
    double double1 = int1;  // double1 is 3.0.
    cout << double1 << endl;
    unsigned char ch1 = -2;  // assuming 8-bit chars, c has value 254.
    signed char ch2 = 256;  // assuming 8-bit chars, the value of ch2 is undefined.
    cout << static_cast<int>(ch1) << '\t' << static_cast<int>(ch2) << endl;

    return 0;
}

/*
Output:
1   0
1   0
3
3
254 0
*/
  1. Assign one of the nonbool arithmetic types to a bool object, the result is false if the value is 0 and true otherwise.
  2. Assign a bool to one of the other arithmetic types, the resulting value is 1 if the bool is true and 0 if the bool is false. When we use a bool in an arithmetic expression, its value converts to either 0 or 1.
  3. Assign a floating-point value to an object of integral type, the value is truncated. The value that is stored is the part before the decimal point.
  4. Assign an integral value to an object of floating-point type, the fractional part is zero. Precision may be lost if the integer has more bits than the floating-point object can accommodate.
  5. Assign an out-of-range value to an object of unsigned type, the result is the remainder of the value modulo(%) the number of values the target type can hold.
    E.g.: An 8-bit unsigned char can hold values from 0 through 255, inclusive. If we assign a value outside this range, the compiler assigns the remainder of that value modulo 256. Therefore, assigning –1 to an 8-bit unsigned char gives that object the value 255.
  6. If we assign an out-of-range value to an object of signed type, the result is undefined.
    • The compiler applies same type conversions when we use a value of one arithmetic type where a value of another arithmetic type is expected. For example, when we use a nonbool value as a condition, the arithmetic value is converted to bool: if the value is 0, then the condition is false; all other nonzero values yield true.
int i = 42;
if(i)  // condition will evaluate as true
    i = 0;

Advice: Avoid Undefined and Implementation-Defined Behavior

  • Undefined behavior results from errors that the compiler is not required and sometimes is not able to detect. Programs that contain undefined behavior can appear to execute correctly in some circumstances but wrong on other circumstances.
  • Programs should also avoid implementation-defined behavior, such as assuming that the size of an int is a fixed and known value. Such programs are said to be nonportable. When the program is moved to another machine, code that relied on implementation-defined behavior may fail.

Expressions Involving Unsigned Types

#include 

using std::cout;
using std::endl;

int main()
{
    // Test 1:
    cout << "Test 1:\n";
    unsigned int num1 = 10;
    int num2 = -42;
    unsigned num3 = -42;
    cout << num2 + num2 << endl;  // -84
    cout << num1 + num2 << endl;  // 32-bits: 4294967264.
    // num2 first converts to unsigned, the same as num1 + (unsigned)num2
    cout << num1 + num3 << endl;

    // Test 2:
    cout << "\nTest 2:\n";
    unsigned int num4 = 42, num5 = 10;
    cout << num4 - num5 << endl;  // 32
    cout << num5 - num4 << endl;  // The result will wrap around

    // Test 3:
    cout << "\nTest 3:\n";
    for(unsigned num = 3; num >= 0; --num)
    {
        cout << num << endl;
        if(num > 3)
        {
            cout << "Stop: Wrap around!\n";
            break;
        }
    }

    return 0;
}

/*
Output:
Test 1:
-84
4294967264
4294967264

Test 2:
32
4294967264

Test 3:
3
2
1
0
4294967295
Stop: Wrap around!
*/
  1. If we use unsigned and int values in an arithmetic expression, the int value is automatically converted to unsigned.
  2. Regardless of whether one or both operands are unsigned, if we subtract a value from an unsigned, we must be sure that the result cannot be negative.
  3. Consider what happens when u is 0. The result -1 will be transformed to an unsigned value 4294967295. (assuming 32-bit ints)

Caution: Don’t Mix Signed and Unsigned Types

  • Remember signed values are automatically converted to unsigned.
  • a * b, if a is -1 and b is 1, then if both a and b are ints, the value is -1. If a is int and b is an unsigned, then the value depends on how many bits an int has on the particular machine. On our machine, this expression yields 4294967295.

Exercises Section 2.1.2

Exercise 2.3

What output will the following code produce?

unsigned u = 10, u2 = 42;
std::cout << u2 - u << std::endl;
std::cout << u - u2 << std::endl;
int i = 10, i2 = 42;
std::cout << i2 - i << std::endl;
std::cout << i - i2 << std::endl;
std::cout << i - u << std::endl;
std::cout << u - i << std::endl;
32
4294967264
32
-32
0
0

Exercise 2.4

Write a program to check whether your predictions were correct. If not, study this section until you understand what the problem is.

  • Do it yourself.

2.1.3. Literals字面文字

  • A value, such as 42, is known as a literal because its value self-evident. Every literal has a type which is determined by its form and value.

Integer and Floating-Point Literals

  • We can write an integer literal using decimal, octal, or hexadecimal notation. Integer literals that begin with 0 (zero) are interpreted as octal; begin with 0x/0X are interpreted as hexadecimal.
    20(decimal) = 024(octal) = 0x14(hexadecimal)
  • The type of an integer literal depends on its value and notation. By default:
    1. Decimal literals are signed and a decimal literal has the smallest type of int, long, or long long (i.e., the first type in this list) in which the literal’s value fits.
    2. Octal and hexadecimal literals can be either signed or unsigned types; octal and hexadecimal literals have the smallest type of int, unsigned int, long, unsigned long, long long, or unsigned long long in which the literal’s value fits.
  • It is an error to use a literal that is too large to fit in the largest related type. There are no literals of type short.
  • Although integer literals may be stored in signed types, the value of a decimal literal is never a negative number. -42, the minus sign is not part of the literal, it is an operator that negates the value of its literal operand.
  • Floating-point literals include either a decimal point or an exponent specified using scientific notation. Using scientific notation, the exponent is indicated by either E or e: 3.14159; 3.14159E100
  • By default, floating-point literals have type double. We can override the default using a suffix from Table 2.2 (overleaf).

Character and Character String Literals

  • A character enclosed within single quotes is a literal of type char. Zero or more characters enclosed in double quotation marks is a string literal.
'a'  // character literal
"Hello World!"  // string literal
  • The type of a string literal is array of constant chars(§ 3.5.4 p. 122). The compiler appends a null character (’\0’) to every string literal. Thus, the actual size of a string literal is one more than its apparent size. For example, the literal ‘A’ represents the single character A, whereas the string literal “A” represents an array of two characters, the letter A and the null character.
  • Two string literals that appear adjacent to one another and that are separated only by spaces, tabs, or newlines are concatenated into a single literal.
// multiline string literal
std::cout << "a really, really long string literal "
"that spans two lines" << std::endl;

Escape Sequences

  • Some characters(backspace or control characters) are non-printable, other characters (single and double quotation marks, question mark, and backslash) have special meaning in the language. We use an escape sequence to represent such characters.
  • An escape sequence begins with a backslash. The language defines several escape sequences:
newline         \n  horizontal tab  \t  alert (bell)        \a
vertical tab        \v  backspace       \b  double quote        \"
backslash       \\  question mark   \?  single quote        \'
carriage return \r  form feed       \f
  • We use an escape sequence as if it were a single character:
std::cout << '\n';  // prints a newline
std::cout << "\tHi!\n";  // prints a tab followed by "Hi!" and a newline
  • A generalized escape sequence: \x followed by one or more hexadecimal digits or a \ followed by 1/2/3 octal digits. The value represents the numerical value of the character. Examples (assuming the Latin-1 character set):
    \7 (bell) \12 (newline) \40 (blank) \0 (null) \115 (‘M’) \x4d (‘M’)
  • If a \ is followed by more than three octal digits, only the first three are associated with the . “\1234” represents two characters: the character represented by the octal value 123 and the character 4.

Specifying the Type of a Literal

  • We can override the default type of an integer, floating-point, or character literal by supplying a suffix or prefix as listed in Table 2.2.

L'a'  // wide character literal, type is wchar_t
u8"hi!"  // utf-8 string literal (utf-8 encodes a Unicode character in 8 bits)
42ULL  // unsigned integer literal, type is unsigned long long
1E-3F  // single-precision floating-point literal, type is float
3.14159L  // extended-precision floating-point literal, type is long double

Boolean and Pointer Literals

  • The words true and false are literals of type bool.
  • The word nullptr is a pointer literal(§2.3.2 p.52).

Best Practices

  • When you write a long literal, use the uppercase L; the lowercase letter l is easily mistaken for the digit 1.
  • We can independently specify the signedness and size of an integral literal.
    1. If the suffix contains a U, then the literal has an unsigned type.
    2. If the suffix contains an L, then the literal’s type will be at least long; if the suffix contains LL, then the literal’s type will be either long long or unsigned long long.
    3. We can combine U with either L or LL. For example, a literal with a suffix of UL will be either unsigned long or unsigned long long, depending on whether its value fits in unsigned long.

Exercises Section 2.1.3

Exercise 2.5

Determine the type of each of the following literals. Explain the differences among the literals in each of the four examples:
(a) ‘a’, L’a’, “a”, L”a”
(b) 10, 10u, 10L, 10uL, 012, 0xC
(c) 3.14, 3.14f, 3.14L
(d) 10, 10u, 10., 10e-2

  • (a): character literal, wide character literal, string literal, string wide character literal.
  • (b): decimal, unsigned decimal, long decimal, unsigned long decimal, octal, hexadecimal.
  • (c): double, float, long double.
  • (d): decimal, unsigned decimal, double, double.

Exercise 2.6

What, if any, are the differences between the following definitions:

int month = 9, day = 7;
int month = 09, day = 07;
  • The first line’s integer is decimal.
  • The second line:
    1. int month = 09 is invalid, cause octal don’t have digit 9.
    2. day is octal.

Exercise 2.7

What values do these literals represent? What type does each have?
(a) “Who goes with F\145rgus?\012”
(b) 3.14e1L
(c) 1024f
(d) 3.14L

  • ﴾a﴿: Who goes with Fergus?﴾new line﴿ “string”
  • ﴾b﴿: 31.4 “long double”
  • ﴾c﴿: ERROR: The suffix f is valid only with floating point literals.
double dou = 1024f;  // error: unable to find numeric literal operator ‘operator"" f’
  • ﴾d﴿: 3.14 “long double”

Exercise 2.8

Using escape sequences, write a program to print 2M followed by a newline. Modify the program to print 2, then a tab, then an M, followed by a newline.

#include 

int main()
{
    std::cout << "\062\115\012";
    std::cout << "\062\t\115\012";
}

/*
Output:
2M
2   M
*/

2.2. Variables

  • A variable provides us with named storage that our programs can manipulate. Each variable in C++ has a type. The type determines the size and layout of the variable’s memory. C++ programmers refer to variables as “variables” or “objects” interchangeably.

2.2.1. Variable Definitions

  • A variable definition consists of a type specifier, followed by a list of one or more variable names separated by commas, and ends with a semicolon.
  • A definition may provide an initial value for one or more of the names it defines:
int 

你可能感兴趣的:(C++,Primer-第5版,basic,github,basic)