从今天起,每天读c++primer5 至少50页,力争100页。 每晚完成任务后上传reading notes, 虽然只是摘录书中一些原话,但也要保持。贵在坚持!
2.1.1 Arithmetic Types
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 essentially any natural language.)
The language guarantees that an int will be at least as large as short, a long at least as large as int, and long long at least as large as long. The type long long was introduced by the new standard.
floats are represented in one word(32bits), doubles in two words(64bits), 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 often used as a way to accommodate special-purpose floating-point hardware; its precision is more likely to vary from one implementation to another.
If we write what appears to be a negative decimal literal, for example, -42, the minus sign is not part of the literal. The minus sign is an operator that negates the value of its(literal) operand.
The type of a string literal is array of constant chars. The compiler appends a null character('\0') to every string literal. Thus, the actual size of a tring literal is one more than its apparent size.
Nothe that if a "\" is followed by more than three octal digits, only the first three are associated with the \. In contrast, \x uses up all the hex digits following it;
Initialization:
int units_sold = 0;
int units_sold = {0};
int units_sold{0};
int units_sold(0);
When used with variables of built-in type, this form of initialization has one important property: The compiler will not let us list initialize variables of built-in type if the initializer might lead to the loss of information.
Initialization is not assignment. Initialization happens when a variable is given a value when it is created. Assignment obliterates an object's current value and replaces that value with a new one.
variables defined outside any function body are initialized to zero. Variables of built-in type defined inside a function are uninitialized. The value of an uninitialized variable of built-in type is undefined. It is an error to copy or otherwise try to access the value of a variable whose value is undefined.
Each class controls how we initialize objects of that class type. In particular, it is up to the class whether we can define objects of that type without an initializer. If we can, the class determines what value the resulting object will have.
A declaration makes a name known to the program. A file that wants to use a name defined elsewhere includes a declaration for that name. A definition creates the associated entity. A variable declaration specifies the type and name of a variable. A variable definition is a declaration. In addition to specifying the name and type, a definition also allocates storage and may provide the variable with an initial value.
To obtain a declaration that is not also a definition, we add the extern keyword and may not provide an explicit initializer.
Any declaration that includes an explicit initializer is a definition. We can provide an initializer on a variable defined as extern, but doing so overrides the extern. An extern that has an initializer is a definition:
extern double pi = 3.1416; //definition
It is an error to provide an initializer on an extern inside a function.
NOTE: Variables must be defined exactly once but can be declared many times.
C++ is a statically typed language, which means that types are checked at compile time. The process by which types are checked is referred to as type checking.
There are a number of generally accepted conventions for naming variables. Following these conventions can improve the readability of a program.
1. An identifier should give some indication of its meaning.
2. Variable names normally are lowercase.
3. Classes we define usually begin with an uppercase letter.
4. Identifiers with multiple words should visually distinguish each word, for example, student_loan or studentLoan, not studentloan.
The new standard introduced a new kind of kind of reference: an "rvalue reference". These references are primarily intended for use inside classes. Technically speaking, when we use the term reference, we mean "lvalue reference."
A reference defines an alternative name for an object. A reference type "refers to" another type. We define a reference type by writing a declarator of the form &d, where d is the name being declared:
int ival = 1024;
int &refVal = ival; // refVal refers to ival
int &refVal2; // error: a reference must be initialized.
Once initialized, a reference remains bound to its initial object. There is no way to rebind a reference to refer to a different object. Because there is no way to rebind a reference, references must be initialized.
NOTE: A reference is not an object. Instead, a reference is just another name for an already existing object.
A reference may be bound only to an object, not to a literal or to the result of a more general expression:
int &refVal4 = 10; //error: initializer must be an object
double dval = 3.14;
int &refVal5 = dval; //error: initializer must be an int object
pointer.
A pointer is a compound type that "points to" another type. Like references, pointers are used for indirect access to other objects. Unlike a reference, a pointer is an object in its own right. Pointers can be assigned and copied; a single pointer can point to several different objects over its lifetime. Unlike a reference, a pointer need not be initialized at the time it is defined. Like other built-in types, pointers defined at block scope have undefined value if they are not initialized.
The value stored in a pointer can be in one of four states:
1. It can point to an object.
2. It can point to the location just immediately past the end of an object.
3. It can be a null pointer, indicating that it is not bound to any object.
4. It can be invalid; values other than the preceding three are invalid.
Both pointers and references give indirect access to other objects. However, there are important differences in how they do so. The most important is that a reference is not an object. Once we have defined a reference, there is no way to make that reference refer to a different object. When we use a reference, we always get the object to which the reference was initially bound.
void * pointers
The type vodi* is a special pointer type that can hold the address of any object. Like any other pointer, a void* is a special pointer type that can hold the address of any object. Like any other pointer, a void* pointer holds an address, but the type of the object at that address is unknown.
There are only a limited number of things we can do with a void* pointer: We can compare it to another pointer, we can pass it to or return it from a function, and we can assign it to another void* pointer. We cannot use a void* to operate on the object it addresses--we don't know that object's type, and the type determines what operations we can perform on the object.
Generally, we use a void* pointer to deal with memory as memory, rather than using the pointer to access the object stored in that memory.