3rd part
C + + World sentient phase
After listening to HelloWorld.exe's self-introduction, completed the first close contact with the C + + world, are you all impatient to want a try and start writing C + + programs? The two main tasks of the program are to describe the data and process the data. So, the first question we're going to face next is: How do you describe data in C + +?
3.1 Data types in C + +
Programming is the use of programming language to describe and express the real world. There are many things that exist in the real world, such as computers, people, automobiles, etc. We always use a variety of data to describe the different properties of these things, for example, we use a string "Chenliangqiao" to describe a person's name, and a number "175" to describe his height. Some of these data can often be attributed to the same type, for example, the data describing human height and computer screen size is numeric data, while the description of the person's name and car license plate data are string data. Correspondingly, in C + +, in order to describe this data, we abstract the same type of data into a data type and then use the variables defined by this data type to express such data. For example, we abstract the various integers in the real world (representing 175 of height, 21 of the screen size) into the data type of int in C + + and then describe a specific integer data with a variable defined by int. For example, we can define a variable of type int nheight to represent a person's height; define another variable of type int nsize to represent the size of a TV set.
As we can see here, the same data type (int) can define several different variables (nheight, nSize), which are used to represent a number of different specific things (height, size). Conversely, multiple variables representing different things (nheight, nSize), or the same data type (int). This is like the real world of surnames, the surname Chen (int) can have a lot of people (nheight, nSize), and many people (nheight, nSize) can also be surnamed Chen (int). The data type of the data determines which one is the person, and since it is the same family, the family has some of the same characteristics. For example, they all occupy the same number of bytes of memory, can represent the same range of data, and so on. As shown in 3-1.
In C + +, data types can be divided into basic data types and constructed data types, depending on how complex the data can be expressed.
1. Basic data types
In the real world there are a lot of simple data, such as a number, a character, and so on. To express these simple data, C + + abstracts the data into a variety of basic data types. For example, 175 of a person's height, 21 of the TV's size are integers, and C + + abstracts these integers into an int data type, which means that a, B, C, d are all characters, and C + + abstracts characters into char data types. The basic data type is the most basic data type in C + +, and it is the lowest-level people in C + +, which have self-explanatory features and no longer have the characteristics of scalability.
2. Constructing data types
The real world is complex, and using only the basic data types provided by C + + does not fully describe the complex real world. For example, we cannot use data from a basic data type to describe a rectangle, because the rectangle has two properties that need to be described for both length and width. But we find that complex things are made up of simple things, and a complex thing can be broken down into simple things, and the combination of several simple things constitutes a complex thing. In contrast to the real world, C + + also provides a combination of structures and classes that can combine multiple basic data types to form a more complex construction data type to describe more complex things. For example, you can combine two simple basic data type int to form a new data type Rect, which is used to describe a more complex rectangle. In C + +, you can use the struct keyword to create a new constructed data type:
// Create a data structure that describes the rectangle. Rect struct rect{ int m_nlength; // represents the length of the rectangle int m_nwidth; // represents the width of the rectangle // that represents a rectangle. rect r;r.nlength = 4 ; // Let the length of the rectangle be 4 r.nwidth = 3 ; // Let the width of the rectangle be 3
A constructed data type can be decomposed into a number of "members" or "elements". Each "member" is a basic data type or another constructed data type. If we consider the basic data type to be an atom in chemistry, then the construction data type can be thought of as a molecule (Rect) composed of atoms (int). The construction data types in C + + can be divided into 4 types: ① array type, ② structure type, ③ union type, and ④ enumeration type, depending on the form of the combination. These construction data types are described in detail in a later section.
3.2 Variables and constants
The C + + world is full of data volumes. Essentially, they are all data stored in a memory location. Some of these data need to be changed during the program's operation. For example, representing a person with a high data 175, it is possible to become 180 during the process of running the program. At the same time, there is another type of data in the program, which remains the same throughout the course of the program. For example, 3.14159 of Pi, will not change at any time when the program is running. We refer to the amount of data that may change while the program is running, which is called a variable, and the amount of data that remains constant is referred to as constants.
Definition and initialization of 3.2.1 variables
In order to save the data, we first need to open up a suitable memory space for it. At the same time, for variables in the program, we often need to read and write access to it. To facilitate access to variables, we often need to give the variable a name and then access the data it represents through the variable name. If we want to express a specific and changeable data in the real world, we can use the data type of this data to define a variable in the following syntax format:
data type descriptor variable name; // define multiple variables of the same type at the same time // non-recommended form, multiple variables easily confusing, code lacking readability data type specifier
A variable definition consists of two parts: a data type descriptor and a variable name. A data type is a description of the variable type that specifies whether the variable is an integer, float, or custom data type, and so it also determines some of the basic characteristics of the variable, such as the number of bytes occupied, the range of values, and so on. The variable name is the symbol used to tag the variable, which is equivalent to the name of the variable, and we can read and write access to the data represented by the variable name. For example, we want to represent a person's variable height data in the program 175, and 175 This data type is an integer, and the corresponding C + + data type is int, so we select int as the data type of the variant. And because this variable represents the height of a person, we choose nheight (n means this is an integer, height means this is the height data) as the variable name:
// defines a variable nheight of type int that is used to denote height int nheight;
When such a variable is defined, it is equivalent to opening up 4 bytes of memory space for the 175 data to be saved (the variable of type int occupies 4 bytes of space in memory), and the name of the variable is specified as nheight. In turn, you can save 175 height data to memory or read and write access to it by nheight this variable name:
//writing data through nheight//Save 175 of this height data to memoryNheight =175;//reading data through nheight//Displays the height data 175 of the nheight variable to the screencout<<"Height:"<<nHeight<<Endl;//Change the height data by variable name toNheight = the;//Output the modified height datacout<<"Modified Height:"<<nHeight<<endl;
When defining variables, you should be aware of the following points.
L cannot use the C + + keyword as the variable name. For example, common bool, for, do, case and other keywords (shown in the IDE as blue and other special colors) can not be used as variable names; variable names cannot begin with a number. For example, the following variable definitions are incorrect:
int case; // Error: Case is a keyword int // Error: Variable name starts with a number
Know more: How many keywords are there in C + +?
A keyword (keyword), also known as a reserved word, is a pre-reserved identifier for C + + across the entire language range. Each C + + keyword has a special meaning to accomplish a particular function. For example, an int represents an integer data type; for means a loop statement is defined; A class represents a category defined and so on. Because the keyword already has a predefined meaning, it cannot be used as an identifier (variable name, function name, or class name, etc.). The keywords for C + + are shown in the following table.
Table 3-1 Keywords in C + +
Alignas (c++11 enabled) alignof (c++11 enabled) and AND_EQ ASM Auto Bitand Bitor BOOL Break case catch char char16_t (c++11 enabled) char32_t (c++11 enabled) class Compl Const constexpr (c++11 enabled) const_cast Continue Decltype (c++11 enabled) default Delete do double dynamic_cast Else |
enum explicit export extern false Float for friend Goto If inline INT Long mutable namespace new Noexcept (c++11 enabled) not not_eq nullptr (c++11 enabled) Operator or OR_EQ Private protected public Register Reinterpret_cast |
Return Short Signed sizeof Static Static_assert(c++11 enabled) Static_cast struct Switch Template This Thread_local(c++11 enabled) Throw True Try typedef typeID TypeName Union Unsigned Using Virtual void Volatile wchar_t While Xor Xor_eq |
All 84 keywords in C + + are listed here, but most of the keywords we use are rarely used. For these keywords, we do not need to master all. We only need to master one of the most commonly used 一、二十个, as for other keywords, need to use the time to check the data on it.
L allows specifier to define multiple variables of the same type at the same time in a data type description. Each variable name is separated by a comma (the comma here must be a comma) interval. For example:
// also define three variables of type int, // The student's ID (NSTUID), age (NAge) and height (nheight) are respectively indicated. int nstuid,nage,nheight;
There must be at least one space interval between the data type descriptor and the variable name.
L must end with ";" After the last variable name to indicate the end of the statement.
The L variable definition must be placed before the variable is used. In other words, a variable must be defined before it is used.
Best practice: Variable definitions should be as close as possible to where variables are used
We know that variables can be used after they are defined, that is, variables must be defined before they are used. So, what is the appropriate level of "before" before "use"? is the 1 line of code before "used" appropriate or 100 lines of code appropriate? Faced with this problem, we do not have a fixed standard answer, but we have a principle that should be followed: variable definition should be as close as possible to the location of the variable used.
If the location of the variable definition is too far away from where the variable is actually used, many things can happen in the middle. For example, the program may exit midway, the defined variables are not used and wasted, and may be wrongly used in the middle of the program to create difficult to find problems. On the other hand, if the two are too far apart, when we use a variable, it is difficult to find the location it defines, so we can not easily know the data type of the variable and other basic information, affecting our use of the variable. So, in order to avoid these possible problems, a simple and effective way is to postpone the definition of the variable whenever possible, as close as possible to where it is actually used.
In addition to determining the data type of a variable when defining a variable, another important task is to give the variable a good name. If a person has a good name, it is easy to leave a good and deep impression, and the variable name is the same. The appropriate variable name contains information related to variables that can be self-explanatory and easier to understand and use, thus improving the readability of the code. So how do you give the variable a proper name? Compare the following four variable names:
// variables that record the number of students int Nstunum; int N; int thenumberofstudent; int
These four variables are used to represent the number of students. If you ask these four variable names which is best, you will certainly say that the first variable is the best, because the first variable name is known to indicate the number of students. and several others, have their own shortcomings: the second is too short, do not know the specific meaning of the variable; the third one is too long, the writing is cumbersome, and the fourth acronym using Hanyu Pinyin is confused.
A good variable name can properly explain the meaning of the variable, without the need for too many comments or documents, the entire code is clearly readable and can be "words too literally". To take a good name for a variable, you usually follow some kind of naming convention. At present, the industry's more popular naming rules are the "Hungarian nomenclature" advocated by Microsoft Corporation. In the Hungarian nomenclature, a variable name consists mainly of three components:
Variable name = attribute + Type + Object description
Where attributes are often used to describe some additional information about the variable. For example, we typically use the "m_" prefix to indicate that the variable is a member (member) variable of a class, whereas using the "g_" prefix means that this is a global variable, that the type represents the data type of the variable, which is usually represented by the abbreviations of the various data types, for example, we usually use N to denote the int type , the float type is represented by F, and the object description is a description of the meaning of the variable, which is usually a noun. By combining these three pieces, you make up a full variable name that can express a rich set of information about the variable. For example, the name of a variable is "m_unage", the variable name is known as the meaning of this variable expression is: This is a class member variable (M_), its data type is unsigned int (un), and it is used to describe the age property of this class.
Know more: How did the Hungarian naming act come from?
The Hungarian nomenclature was first proposed by a Hungarian programmer named Charles Simonyi, who later worked in Microsoft for several years because the nomenclature, which used very few words to generalize the most important information about variables, was accepted by Microsoft and became popular within Microsoft. And because of Microsoft's strong influence in the industry, the Hungarian nomenclature began to spread across the world through Microsoft's products and documentation, becoming the most popular variable naming method in the industry. For most programmers, this variable nomenclature is more or less used regardless of the development language they are using.
This nomenclature is called the "Hungarian nomenclature" to commemorate the country where the inventor came from.
With the Hungarian nomenclature, rich information can be expressed within a variable name, which improves the readability of the code to some extent. But it also has one of the biggest drawbacks--tedious. Sometimes, some long, insignificant prefixes add additional burdens to variable names. And that's why it's not being used by all programmers around the world. The best naming rules don't matter in the world. In practice, according to some common rules in the industry, combined with the actual situation of the project, we can make a naming rule that satisfies most project members and implement it in the project. The "best fit" rule is the rule of the "good". Through the practice of testing, some popular naming rules in the industry mainly have the following points.
1. Easy to understand
Variable names should be intuitive, easy to spell, hope the text and righteousness. Variable names preferably in English words or combinations, easy to remember and read; Do not use Hanyu Pinyin to name, because such a variable name, only you can understand, the English word in the program is not too complex, the word should be as far as possible authentic, accurate. For example, the variable that represents "current value" is named "Fnowval", although it can express the meaning of the variable, but it is far from "Fcurval".
2. Shortest length, maximum amount of information
Typically, the compiler has no restrictions on the length of variable names. In general, long names can better express the meaning of variables, so it is not surprising that variable names in C + + are up to more than 10 characters. Since there is no limit, then the name of the variable is not the longer the better? Not As long as you can express the meaning of a variable completely, the variable name should be as simple as possible. For example, the same is the maximum value, and the variable name "Max" is more useful than "Maxvalueuntiloverflow" because it expresses the maximum amount of information in the shortest length.
3. The larger the scope, the longer the variable name
As for the length of the variable name, we can also remember a simple rule: the length of the variable name (or the function name described later) is positively correlated with the size of its scope. The so-called scope, which is the range of code in which an identifier (variable name or function name) takes effect, can refer to the subsequent 7.3.3 section for details. In other words, if the scope of a variable is larger, then the variables in this scope will be much more, in order to avoid conflict easy to distinguish, the variable name should be relatively long. Vice versa. For example, within a function, we can use a simple I to name a local variable, and in the global scope, it is not appropriate to use I to name a global variable.
4. Variable names consist of nouns
A variable represents a specific thing in the real world, which is essentially a data entity, so the core of the variable name should be a noun, so it should use a single "noun" or "adjective + noun" combination form. For example:
float fweight; // a noun that represents a person's weight float flastweight; // an adjective + noun that represents the last weight float fcurweight; // adjective + noun, indicating current weight
4. Do not use numeric numbering
Try to avoid numeric numbers in variable names, such as "Value1", "Value2", and so on, unless the numbers are logically required.
5. Constant capitalization
Constant is a special kind of variable, its particularity is that it can not be modified. This particularity is embodied in the name, that is, we usually use capital letters to denote variable names, if there are multiple words in the constant name, then the underscore is divided. For example:
Const float 3.14159; // define a constant pi of type float using the const keyword Const int 1024x768; // split the constant name with an underscore
6. Using a conventional prefix
Some of the customary variable name prefixes can be used to explain some of the variables ' properties and make the variables ' meanings clear. For example: A variable prefixed with s_, representing a static (static) variable, a variable prefixed with g_, representing a global variable, and a variable prefixed with m_, representing a member (member) variable.
When the variable is defined, the system allocates memory space for the variable, and we can read and write access to the memory through the variable name, save the data to memory, or read the data from memory. However, before we can actually use variables, we often need to properly initialize them. This is because after the variable is defined, if it is not initialized, the system is given an indeterminate random value as its initial value. This random value may be different depending on the compiler and the target platform. This can lead to inconsistencies in the behavior of the same program on different platforms, resulting in porting problems. At the same time, if you accidentally use this random value to operate, it may cause the program to run the result of an error, or even a program crashes, it is a disaster. The initialization of variables will give the variable a reasonable initial value, which can well avoid the above problems. So, in the beginning of learning C + +, you should develop a good habit of "initializing while defining variables".
So, how do we initialize the variables?
In the first way, you can assign the appropriate initial value to the variable using the "=" value while defining the variable. For example:
// define a variable nheight of type int, and use "=" to initialize its value to 175 int 175;
The second way is to give the initial value with "()" after the variable name when defining the variable, and the system will use this initial value to complete the creation of the variable to complete the initialization work. For example:
// initialize its value to 175 with "()" int nheight (175);
In addition to the above two methods, in the C++11 standard, we can also use a pair of curly braces "{}" to represent the initialization list (initializer list) to complete the initialization of variables when defining variables. For example:
// initialize its value to 175 by initializing the list int nheight{175};
Best practice: Why use an initialization list?
Here, it is natural to ask the question: C + + already has "=" and "()" can complete the initialization of the variable, why also use the initialization list for the initialization of variables?
The initialization list is a new feature introduced by the C++11 Standard, which, in addition to the form of unified variable initialization, provides an additional benefit: it prevents data type truncation at variable initialization, preventing data precision loss. The so-called data type truncation, in short, is that when the data of a higher precision data type (for example, double) is assigned to a variable of another lower-precision data type (for example, int), C + + implicitly types the truncation to satisfy the need for type conversion. For example:
int 7.3; // a double type of data 7.3 is truncated to data of type int 7
When compiling the above code, the compiler will not give any error or warning message, although 0.3 of this data is lost during the process. However, in c++11, if the initialization list "{}" is used for initialization, the compiler warns of this data type truncation, prompting the loss of the user's data precision. For example:
// Warning: Initializing a variable of type int with data of type double produces type truncation, loss of data precision int x1 = {7.3}; // Correct: Although 7 is an int type of data, it can be expressed precisely using the char type, // Therefore, data type truncation does not result in loss of precision error Char x2{7};
In C + +, if an initial value can be accurately expressed as the target type, there is no data type truncation. Note, however, that conversions of type double to int are usually considered data type truncation, resulting in a loss of precision, even from 7.0 to 7. Initialization lists the handling of type conversions enhances the security of the C + + static type system. The traditional dependency on the programmer's initialization type security checks, in C++11, is implemented by the compiler through the initialization list, which reduces the burden and security of programmers. So, if you can, you should use the initialization list as much as possible to complete the initialization of the variables.
In particular, we cannot use the initialization list for the auto type (a special data type, which is equivalent to a placeholder for a data type.) When you define a variable as a data type, it does not specifically specify the data type of the variable, and the actual data type of the variable is automatically inferred at compile time based on its initial value. In a later section of 3.5.2, we will introduce the variables in detail) to initialize. In that case, the type of the variable is detected by the compiler as the initialization list type, not the type of the actual initial value in the initialization list.
Know more: User-defined data identification (user-defined literals) to create special data
When it comes to representing data, C + + provides a number of data identifiers built into the data types that we use, so that when we express the data, we add the corresponding data ID, which makes the data we want to express more accurate and intuitive. For example:
1.2 // default double dual precision floating point type 1.2F // F Specify float single-precision floating-point 19821003ULL // ull represents unsigned long long 64-bit unsigned longer integer
In addition to these built-in data identifiers, C++11 also uses a user-defined suffix after the variable to calibrate the required data type to support "user-defined data identification", for example:
// defines the data identity inch that represents inches Double operator "" _inch (constlongdoublein) { return in *0.0254; // Convert inch units to meters units }
Here, we actually define an operator (which must begin with "_"), which takes the data before the operator as a parameter, and the type of the parameter is the type with the largest range of data values. For example, a unsigned long long that represents an integer number, or a long double that represents a floating-point. Of course, the entire data can also be passed as a string, in the form of a const char* parameter. After a certain amount of processing, the incoming parameters are returned with the data and the actual data represented by the data ID. This allows us to directly define the data in inches by using the user-defined data ID "_inch" in the program. For example:
// define a TV with a size of 54 inches, // then convert the data in meters to the variable tvsize Double Wu . 0_inch;cout<<""<<tvsize<<" m" <<endl;
In the above code, we use the "_inch" data ID to directly define the size of the TV. When the compiler compiles this code, it first parses the suffix of the variable assignment data, then takes the data before the suffix as a parameter, invokes the function that defines the data ID, and takes the return value of the function as the true value of the data. The user-defined data identification mechanism simply allows the user to make a new suffix and decide how to process the data before it. In which we can convert units, for example, to convert inches into meters, or to construct new data types, such as constructing a binary number into a decimal number, and so on.
Because we use the CONSTEXPR keyword when defining the data ID, the function of the CONSTEXPR keyword is to implement preprocessing calculations at compile time, so at compile time, the compiler will directly convert the data in inches into meters, and assign the values to the corresponding variables.
In this way, we can directly in the code to express a variety of different types of data, such as inch length, angle, binary number and so on, so that we use different types of data will be more intuitive, more convenient, more humane.
Hello, C + + (7) Part III definition and initialization of 3.2.1 variables in C + + world sentient beings