[C/C ++]-Tips for better coding style
Suggestions for better programming style (V1.0)
Translated by Phoenix (phoenix8848@gmail.com)
In this entry, I show you 4 tips that address Frequently Asked Questions from C ++ programmers of all levels of expertise. it's surprising to discover how your experienced programmers are still unaware of the deprecation of. h notation of standard header files, the proper usage of namespaces, and the rules regarding binding of references to temporary objects, for example. these issues and others will be discussed here.
In this articleArticleI will talk about various levels of C ++ProgramThe staff often asked four questions. For example, I was surprised to find that many programmers were not aware of the controversy over the standard header file extension. H, the proper usage of namespaces, and the rules for referencing temporary objects. These questions and others will be discussed here.
First, we start by explaining the difference between the deprecated "XXX. H "header names and the modern, standard-compliant" XXX "header-naming notation. next, we recommend e a few dark corners of C ++ which due to compilers 'limitations and the somewhat recondite nature of the associated LanguageRules tend(Originally "rulestend") to confuse extends programmers, e.g ., the notion of comma-separated expressions and the rules of binding references to rvalues. finally, we will learn how to invoke a function prior to a program's startup.
First, let's begin by interpreting the differences between the "XXX. H" header file name and the modern, compliant "<XXX>" header file name Mark. Next we will explore the unknown corners of C ++. Many programmers are confused by the limitations of the compiler and some hidden natural features of the Association language rules, for example, the meaning of a comma-separated expression and the rule of a referenced variable. Finally, we will learn how to start a function before the program starts.
Tip 1: "iostream. H" or "iostream "?
Question 1 :"Iostream. h"Or"Iostream"?
program c ++ programmers still use "iostream. H" instead of the newer, standard compliant "iostream" library. What are the differences between the two? First,. h notation of standard header files was deprecated more than five years ago. using deprecated features in new code is never a good idea. in terms of functionality, "iostream" contains a set of templatized I/O classes which support both narrow and wide characters, as opposed to "iostream. H "which only supports char-oriented streams. third, the C ++ Standard Specification of iostream's interface was changed in response subtle aspects. consequently, the interfaces and implementation of "iostream" differ from those of "iostream. H ". finally, "iostream" components are declared in namespace STD whereas "iostream. H "components are global.
Many C ++ programmers are still using"Iostream. h"Replacing the new compliant"Iostream"Library. What is the difference between the two? First, the extension of the standard header file ". H" was controversial five years ago. In the newCodeUsing controversial (outdated) features is never a good idea. In essence ,"Iostream"Includes a series of templatized I/O input and output classes that support narrow and wide characters. On the contrary ,"Iostream. h"Only accept streams are supported. Third,IostreamThe standard C ++ specification of interfaces has been changed in many details. Therefore ,"Iostream"Interfaces and implementations are the same"Iostream. h"There is a difference. Finally ,"Iostream"Is inSTD"Iostream. h"Is global.
Because of these substantial differences, you cannot mix the two libraries in one program. as a rule, use "iostream" unless you're dealing with legacy code that is only compatible with "iostream. H ".
Because of these essential differences, these two libraries cannot be used together in the same program. The conclusion is that"Iostream"It is best to use the legacy code that remains compatible"Iostream. h".
Tip 2: binding a reference to an R-Value
Topic 2: bind the reference to the right value
(R-value: Right Value, opposite to "Left value. For exampleX = 3Medium ,"X"Is a" Left value ","3"Is a right value. In essence, the left value is a memory address, and the right value is an actual binary value .)
R-values and L-values are a fundamental concept of C ++ programming. in essence, an R-value is an expression that cannot appear on the left-hand side of an assignment expression. by contrast, an L-value refers to an object (in its wider sense), or a chunk of memory, to which you can write a value. references can be bound to both R-values and L-values. however, due to the language's restrictions regarding R-values, you have to be aware of the restrictions on binding references to R-values, too.
The right and left values are a basic concept of C ++ programming. In essence, the right value is an expression that cannot appear on the left of the equal sign. Conversely, the left value references an object (In a broad range) or a read/write memory. A reference can point to either the right or the left. However, due to the restriction of the language on processing the right value, you have to think carefully when pointing the reference to the right value.
Binding a reference to an R-value is allowed as long as the reference is bound to a const type. the rationale behind this rule is straightforward: You can't change an R-value, and only a reference to const ensures that the program doesn't modify an R-value through its reference. in the following example, the functionF ()Takes a reference to const INT:
Binding a reference to the right value is also allowed as a reference to a static type. The principle behind this principle is obvious: you cannot change the right value, because the reference to the static type ensures that the program does not change the right value through this interface. The following example,F ()A function contains a reference to a static integer variable.
Void F (const Int & I );
Int main ()
{
F (2);/* OK */
}
The program passes the R-value 2 as an argumentF (). At runtime, C ++ creates a temporary object of Type int with the value 2 and binds it to the reference I. the temporary and Its Reference exist from the moment F () is invoked until it returns; they are destroyed immediately afterwards. note that had we declared the reference I without the const qualifier, the function f () cocould have modified its argument, thereby causing undefined behavior. for this reason, you may only bind references to const objects.
This Code uses the right value "2" as a parameter of function f. When the code is running, C ++ creates a temporary integer variable with a value of 2 and binds it to the reference type I. This temporary object and its interface will remain in the F () operation until function f returns. Function f is released immediately after return. Note that I is not declared as a static type, but function f may still modify this parameter, which will cause an exception. Therefore, it is best to bind the reference to the static type.
The same rule applies to user-defined objects. You may bind a reference to a temporary object only if it's const:
The same rule applies to custom types. Only when a temporary object is static can it be bound to the reference type.
Struct {};
Void F (const A & );
Int main ()
{
F (a ();/* OK, binding a temporary A to a const reference */
}
Tip 3: comma-separated expressions
Topic 3: comma expression
Comma-separated expressions were inherited from C. it's likely that you use such expressions in for-and while-loops rather often. yet, the language rules in this regard are far from being intuitive. first, let's see what a comma separated expression is.
The comma expression follows the C language. It is like a for loop that you often use and a while-loop. However, the syntax is far from what it looks like. First, let's see what a comma expression is.
An expression may consist of one or more sub-expressions separated by commas. For example:
An expression can be separated by commas (,) into one or more subexpressions. For example:
If (++ X, -- y, Cin. Good ()/* three expressions */
The IF condition contains three expressions separated by commas. c ++ ensures that each of the expressions is evaluated and its side effects take place. however, the value of an entire comma-separated expression is only the result of the rightmost expression. therefore, the if condition abve evaluates as true only if cin. good () returns true. here's another example of a comma expression:
This If statement is separated by commas (,) into three expressions. From the perspective of C ++, each expression is valid but has side effects. The value of the entire comma expression is determined by the rightmost expression. Therefore, the value of the entire expression is true only when con. Good () returns true. Here is another example of a comma expression.
Int J = 10;
Int I = 0;
While (++ I, -- J)
{
/* .. Repeat as long as J is not 0 */
}
Tip 4: calling a function before program's startup
Call the function before the program starts.
Certain applications need to invoke startup functions that run before the main program starts. for example, polling, billing, and logger functions must be invoked before the actual program begins. the easiest way to achieve this is by calling these functions from a constructor of a global object. because global objects are conceptually constructed before the program's outset, these functions will run before Main () starts. for example:
Some applications need to run the startup function before the main program starts. For example, the voting, payment, and login functions must run before the actual program starts. The simplest implementation method is to call these functions in the constructor of a global object. Because the global object is implicitly created at the beginning of the program, these functions can be run before the main () function. For example:
Class Logger
{
Public:
Logger ()
{
Activate_log ();
}
};
Logger log;/* Global instance */
Int main ()
{
Record * prec = read_log ();
//. Application code
}
The Global Object log is constructed before Main () starts. during its construction, log invokes the function activate_log (). thus, when main () starts, it can read data from the log file.
The Global Object log is created before the main () function is started. In its constructor, log calls the active_log () function. Therefore, when the main () function is started, it can read data from the log file.