C++ Primer Plus Chapter 3 data processing
3.4.4 Type conversion
The rich types of C + + allow different types to be selected according to needs, which also makes the operation of the computer more complex. To deal with this potential confusion, C + + automatically performs many type conversions:
- When assigning a value of one arithmetic type to a variable of another type, C + + will convert the value;
- When the expression contains different types, C + + will convert the value;
- When you pass parameters to a function, C + + converts the values.
1. Conversion by initialization and assignment
C + + allows values of one type to be assigned to variables of another type. When you do this, the value is converted to the type of the accepted variable. For example:
long so_long; short thirty; so_long = thirty;
When assigning values, the program expands the value of thirty (usually 16 bits) to a long value (usually 32 bits). After expansion, you will get a new value, which is stored in so_long, while the content of thirty remains unchanged.
Assigning a value to a type with a wider range of values usually does not cause any problems. For example, assigning a short value to a long variable does not change the value, but takes up more bytes. However, assigning a large long value (such as 2111222333) to the float variable will reduce the accuracy. Since float has only 6 significant digits, this value will be rounded to 2.11122E9. Therefore, some conversions are safe and some can cause trouble.
The following procedure demonstrates some of the transformations made by initialization:
#include<iostream> #include<stdlib.h> int main() { using namespace std; cout.setf(ios_base::fixed, ios_base::floatfield); float tree = 3; // int converted to float int guess(3.9832); // double converted to int int debt = 7.2E12; // result not defined in C++ cout << "tree = " << tree << endl; cout << "guess = " << guess << endl; cout << "debt = " << debt << endl; system("pause"); return 0; }
When you initialize integer variables to floating-point values, some compilers will warn that this may lose data.
2. Conversion during initialization in {} (C++11)
C + + calls initialization using braces list initialization because it is often used to provide a list of values for complex data types. Compared with the initialization method shown in the above program, it has more strict requirements for type conversion. Specifically, list initialization does not allow narrowing That is, the type of a variable may not represent the value assigned to it.
Converting between different integers or converting integers to floating points may be allowed if the compiler knows that the target variable can correctly store the value assigned to it. For example:
const int code = 66; int x = 66; char c1 ; //narring, not allowed char c2 = ; // allowed because char can hold 66 char c3 ; // ditto char c4 = ; // not allowed, x is not constant x = 31325; char c5 = x; // allowed by this form of initialization
In the above code, when initializing c4, you know that the value of x is 66, but in the view of the compiler, x is a variable, and its value may be very large. The compiler will not track what may happen in the following stages: from x is initialized to it is used to initialize c4.
3. Transformations in expressions
When the same expression contains two different arithmetic types, C + + will perform two automatic conversions: first, some types will be converted automatically when they appear; second, some types will be converted when they appear in the expression at the same time as other types.
Automatic conversion: when evaluating expressions, C + + converts bool, char, unsigned char, signed char, and short values to int. specifically, true is converted to 1 and false is converted to 0. These conversions are called integral promotion. For example:
short chickens = 20;
short ducks = 35;
short fowl = chickens + ducks;
When these statements are executed, the C + + program takes the values of chickens and ducks and converts them to int. then, the program converts the result to short type, because the result will be assigned to a short variable. (usually, the int type is selected as the most natural type of the computer)
4. Conversion when passing parameters
The type conversion when passing parameters is usually controlled by the C + + function prototype. However, the prototype can also cancel the control of parameter passing. In order to maintain the compatibility with a large number of code in traditional C language, C + + promotes the float parameter to double when passing parameters to the function that cancels the control of parameter passing by the prototype.
5. Cast type
C + + also allows explicit type conversion through the cast mechanism. There are two forms of cast. For example:
(long) thorn // returns a type long conversion of thorn
long (thorn) // returns a type long conversion of thorn
Cast does not modify the thorn variable itself, but creates a new value of the specified type, which can be used in the expression. The first format is from the C language, and the second format is pure C + +.
C + + also introduces four forced type conversion operators, which are more strictly required. Among the four operators, static_cast < > can be used to convert a value from one numeric type to another.
#include<iostream> #include<stdlib.h> int main() { using namespace std; int auks, bats, coots; auks = 19.99 + 11.99; bats = (int) 19.99 + (int) 11.99; // old C syntax coots = int (19.99) + int (11.99); // new C++ syntax cout << "auks = " << auks << ", bats = " << bats; cout << ", coots = " << coots << endl; char ch = 'Z'; cout << "The code for " << ch << " is "; //print as char cout << int (ch) << endl; // print as int cout << "Yes, the code is "; cout << static_cast<int>(ch) << endl; // using static_cast system("pause"); return 0; }
3.4.5 auto declaration in C++11
C++11 adds a tool that allows the compiler to infer the type of a variable based on the type of the initial value. To this end, it redefines the meaning of auto. If the keyword auto is used without specifying the type of the variable, the compiler will set the type of the variable to be the same as the initial value:
auto n = 100; // n is int auto x = 1.5; // x is double auto y = 1.3e12L; // y is long double
However, automatic inference types are not designed for this simple case: in fact, if they are used in this simple case, there will even be errors. For example:
auto x = 0.0; // ok, x is double double y = 0; // ok, 0 automatically converted to 0.0 auto z = 0; // ops, z is int because 0 is int
When dealing with complex types, such as those in the standard module library (STL), the advantages of automatic type inference can be shown. For example, for the following C++98 Code:
std::vector<double> sores; std::vector<double>::iterator pv = scores.begin();
C++11 allows you to rewrite it as follows:
std::vector<double> scores; auto pv = scores.begin();