Introduction to C++ (3)

1. auto keyword (C++11)

1.1. Thinking about type aliases

As the program becomes more and more complex, the types used in the program become more and more complex, often reflected in:

  1. Type is hard to spell
  2. Ambiguity leads to error-prone

insert image description here
std::map<std::string, std::string>::iterator is a type, but the type is too long, and it is especially easy to write wrong. Clever students may have already thought of: you can use typedef to alias the type, for example:
insert image description here
using typedef to alias the type can indeed simplify the code, but typedef may encounter new problems:
insert image description here
insert image description here
when programming, it is often necessary to assign the value of the expression For variables, this requires that the type of the expression be clearly known when the variable is declared. However, sometimes it is not so easy to do this, so C++11 gives auto a new meaning.

1.2. Introduction to auto

The meaning of auto in early C/C++ is: a variable modified with auto is a local variable with automatic memory.
In C++11, the standard committee gave auto a brand-new meaning: auto is no longer a storage type indicator, but a new type indicator to instruct the compiler, and the variables declared by auto must be compiled by the compiler derived from time period.
insert image description here
[Note]
When using auto to define a variable, it must be initialized. At the compilation stage, the compiler needs to deduce the actual type of auto according to the initialization expression. Therefore, auto is not a "type" declaration, but a "placeholder" when the type is declared. The compiler will replace auto with the actual type of the variable during compilation.

1.3. auto usage scenarios

insert image description here
insert image description here

1.4. The usage rules of auto

  1. Auto is used in combination with pointers and references. When using auto to declare a pointer type,
    there is no difference between using auto and auto* , but when using auto to declare a reference type, you must add &
    insert image description here
  2. Defining multiple variables on the same line
    When declaring multiple variables on the same line, these variables must be of the same type, otherwise the compiler will report an error, because the compiler actually only deduces the first type, and then uses the deduced Type defines other variables.
    insert image description here

1.5. Scenarios where auto cannot be derived

  1. auto cannot be used as a function parameter
    insert image description here
  2. auto cannot be used directly to declare arrays
    insert image description here
  3. In order to avoid confusion with auto in C++98, C++11 only retains the usage of auto as a type indicator
  4. The most common advantage of auto in practice is to use it in conjunction with the new for loop provided by C++11, which will be mentioned later, and lambda expressions.

2. Function inlining

2.1. Asking questions

When the function statement is short and called frequently, stack space will be opened up multiple times. In terms of the intersection with the time of statement execution, the time to open up the stack space and the time to execute the statement are in the same order of magnitude or an order of magnitude larger. This will reduce the efficiency of the program.

In the C language , we can use macro functions to replace short statements of function definitions.
Take the function of adding two numbers as an example:
【Function definition】

insert image description here
【Macro function】
insert image description here

Macro function:

  • Advantages - no need to create a stack frame, improve call efficiency
  • Disadvantages - complex, error-prone, poor readability, cannot debug

So the inline function is proposed in C++ to solve this situation.

2.2. Concept (keyword—inline)

A function decorated with inline is called an inline function. When compiling , the C++ compiler will expand it at the place where the inline function is called . There is no overhead for function calling to build a stack frame. Inline functions improve the efficiency of program operation.

【Comparison before and after adding the keyword inline】—the call command will not appear

before
insert image description here
and after
insert image description here

2.3. Features

  1. inline is a way of exchanging space for time . If the compiler treats the function as an inline function, it will replace the function call with the function body during the compilation phase . Defect: it may make the object file larger. Advantage: less call overhead , improve the efficiency of program operation.
  2. Inline is just a suggestion for the compiler. Different compilers may have different inline implementation mechanisms. The general suggestion is: make the function smaller (that is, the function is not very long, there is no exact statement, it depends on the internal implementation of the compiler), no Functions that are recursive and frequently called should be inlined, otherwise the compiler will ignore the inline feature.
  3. Inline does not recommend separation of declaration and definition , which will lead to link errors. Because inline is expanded, there is no function address, and the link will not be found.
    insert image description here

2.4. Interview questions

insert image description here

3. Range-based for loop (C++11)

3.1. The syntax of range for

In C++98, if you want to traverse an array, you can do it in the following way:

void TestFor()
{
    
    
int array[] = {
    
     1, 2, 3, 4, 5 };
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
  array[i] *= 2;
for (int* p = array; p < array + sizeof(array)/ sizeof(array[0]); ++p)
  cout << *p << endl;
}

For a ranged collection, it is redundant and sometimes error-prone for the programmer to specify the range of the loop. Therefore, range-based for loops were introduced in C++11. The parentheses after the for loop are divided into two parts by the colon ":": the first part is the variable used for iteration in the range, and the second part represents the range to be iterated. (syntactic sugar: auto)

[Traversing the array]
insert image description here
[Modifying the array]
Incorrect form:
insert image description here
Correct form Modification:
insert image description here

Note: Similar to ordinary loops, you can use continue to end this loop, or use break to jump out of the entire loop.

3.2. Conditions for the use of scope for

  1. The range of the for loop iteration must be definite
    **For arrays, it is the range of the first element and the last element in the array; **For classes, methods of begin and end should be provided, and begin and end are for The range of loop iterations.
    Note: The following code is problematic because the scope of for is uncertain
    insert image description here
  2. The iterated object must implement ++ and == operations.

4. Pointer null value nullptr(C++11)

In good C/C++ programming practice, it is best to give the variable an appropriate initial value when declaring a variable, otherwise unexpected errors may occur, such as uninitialized pointers. If a pointer does not have a legal point, we basically initialize it in the following way:
insert image description here
NULL is actually a macro. In the traditional C header file (stddef.h), you can see the following code: As you can see
insert image description here
, NULL May be defined as a literal constant of 0, or as a constant of an untyped pointer (void*). No matter what kind of definition is adopted, some troubles will inevitably be encountered when using pointers of null values, such as:
insert image description here

The original intention of the program is to call the pointer version of the f(int*) function through f(NULL), but since NULL is defined as 0, it is contrary to the original intention of the program
.
In C++98, the literal constant 0 can be either an integer number or an untyped pointer (void*) constant, but the compiler treats it as
an integer constant by default. To use it in pointer mode, it must be forced to (void
*)0.

Notice:

  1. When using nullptr to represent the null value of the pointer, there is no need to include the header file, because nullptr was introduced as a new keyword in C++11
    .
  2. In C++11, sizeof(nullptr) and sizeof((void*)0) occupy the same number of bytes.
  3. In order to improve the robustness of the code, it is recommended to use nullptr when representing the null value of the pointer later.

insert image description here

Guess you like

Origin blog.csdn.net/zxj20041003/article/details/130218847