[C++] Detailed introduction to basic knowledge (2)

Table of contents

1. Inline functions

1. Concept

2. Features

3. Advantages and disadvantages of inline functions and macros

2. The auto keyword (C++11)

  1. Introduction to auto

  2. The usage rules of auto

    2.1 Auto is used in combination with pointers and references

    2.2 Define multiple variables on the same line

  3. Scenarios where auto cannot be derived

    3.1 auto cannot be used as a function parameter

    3.2 auto cannot be used directly to declare arrays

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

  1. The syntax of range for

  2. Conditions for the use of scope for

    2.1 The range of for loop iterations must be definite

Fourth, the pointer null value nullptr (C++11)

  1. The pointer null value in C++98


1. Inline functions

1. Concept

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 of creating a stack frame for function calls. Inline functions improve the efficiency of program operation .

If you add the inline keyword before the above function to change it into an inline function, the compiler will replace the call of the function with the function body during compilation. View by:

1. In release mode, check whether call Add exists in the assembly code generated by the compiler;

2. In debug mode, the compiler needs to be set, otherwise it will not be expanded (because in debug mode, the compiler will not optimize the code by default, the setting method of vs2013 is given below)

2. Features

  1. Inline is a method 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 Recursive and frequently called functions should be decorated with inline, 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.

3. Advantages and disadvantages of inline functions and macros

  The difference between inline functions and macros is that macros are replaced by the preprocessor, while inline functions are implemented through compiler control, macros are replaced at the preprocessing stage, and inline functions are expanded at the compile stage . Moreover, the inline function is a real function, but when it is needed, the inline function is expanded like a macro, so the push of the parameters of the function is canceled, and the overhead of the call is reduced. So you can call inline functions like calling functions without worrying about problems like macros.

  In C language, using macros (#define) to write functions will be optimized, without the consumption of stack frames, and it is suitable for frequently calling small functions . But macros are somewhat flawed. In C++, inline functions, constants modified by const, and enums are used instead of macros.

How to replace macros in C++:

  1. The constant definition is replaced by const and enum.
  2. Short function definitions use inline functions instead.

Pros and cons of inline functions?

advantage:

  1. Because the inline function is a function, the function parameters have types, so the parameter type detection will be performed during the compilation stage, which is more secure;
  2. The inline function has been expanded in the compilation stage, which reduces the function call and improves the operating efficiency of the function;
  3. Inline functions do not need to add parentheses everywhere like macro functions, which makes it easier to implement;
  4. In Debug mode, it will not be expanded by default, you can debug, or you can verify whether it is expanded by setting the compiler;
  5. There will be no side effects.

shortcoming:

  1. Almost every place where an inline function is used will be expanded, causing code bloat.

Pros and cons of macros?

(1) Advantages and disadvantages of macro constants

advantage:

  1. One change and all changes to reduce the probability of errors and improve the readability of the code.

shortcoming:

  1. Replacement is performed at the preprocessing node, no type detection is performed, and the code security is low.

(2) Advantages and disadvantages of macro functions

advantage:

  1. It is not a function, which reduces the overhead of function calls and improves the operating efficiency of the program;
  2. It can save some codes, because the macro function can encapsulate multiple statements;
  3. Can improve code readability.

shortcoming:

  1. The macro function preprocessing stage is replaced, no type detection is performed, and the code security is low;
  2. Macro functions cannot be debugged (because they are replaced in the precompilation stage);
  3. Error-prone, each part of the macro function needs to be parenthesized;
  4. The position of each macro function will be expanded, which will cause code expansion;
  5. Macro functions may have side effects.

2. The auto keyword (C++11)

  1. Introduction to auto

The meaning of auto in early C/C++ is: the variable modified with auto is a local variable with automatic memory , but unfortunately no one has been using it. 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 variable declared by auto must be compiled by the compiler derived from time period.

int TeTestAuto()
{
	return 10;
}
int main()
{
	int a = 10;
	auto b = a;//此时编译器会根据 a 的类型来对 b 的类型进行推导为 int
	auto c = 'a';
	auto d = TeTestAuto();
    auto e = &a;

	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(d).name() << endl;
    cout << typeid(e).name() << endl;
    return 0;
}

 typeid(variable name).name() can print the type of variable.

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.

  2. The usage rules of auto

    2.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 & .

int x = 10;
auto a = &x;
auto* b = &x;
auto& c = x;

cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;

    2.2 Define 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 defines other variables with the deduced type.

void TestAuto()
{
    auto a = 1, b = 2; 
    auto c = 3, d = 4.0;  // 该行代码会编译失败,因为c和d的初始化表达式类型不同
}

  3. Scenarios where auto cannot be derived

    3.1 auto cannot be used as a function parameter

// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}

    3.2 auto cannot be used directly to declare arrays

void TestAuto()
{
    int a[] = {1,2,3};
    auto b[] = {4,5,6}; //编译会失败
}

  There are two other scenarios: (1). In order to avoid confusion with auto in C++98, C++11 only retains the usage of auto as a type indicator; (2) the most common advantage of auto in practice The usage is to use it in conjunction with the new for loop provided by C++11, which will be mentioned later, as well as lambda expressions.

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

  1. The syntax of range for

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. In this case, there is no need to specify the range of the loop when traversing the entire collection.

void Test()
{
    int arr[] = { 1, 2, 3, 4, 5 };
    for (auto& e : arr)//要改变数组的值,需要使用引用
        e *= 2;

    for (auto e : arr)
        cout << e << " ";
}

  2. Conditions for the use of scope for

    2.1 The range of for loop iterations must be definite

For an array, it is the range of the first element and the last element in the array ; for a class, methods of begin and end should be provided, and begin and end are the range of for loop iterations.

void TestFor(int array[])
{
    for(auto& e : array)
        cout<< e <<endl;
}

 Note: There is a problem with the above code, because the scope of for is uncertain.

Fourth, the pointer null value nullptr (C++11)

  1. The pointer null value in C++98

NULL may be defined as the literal constant 0, or as the 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.

void f(int)
{
	cout << "f(int)" << endl;
}
void f(int*)
{
	cout << "f(int*)" << endl;
}
//这里函数重载,但结果都是f(int)
//C++中,NULL被定义为0,这也不知道为什么是个错误不太好
int main()
{
	f(0);
	f(NULL);
	return 0;
}

   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. If you want to convert it according to To use it in pointer mode, it must be forced to (void *)0.

   Therefore, a patch was made in C++11 to replace NULL with nullptr.

Notice:

  1. The header file does not need to be included when using nullptr to represent the null value of the pointer, since 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.


If there are deficiencies in this article, you are welcome to comment below, and I will correct it as soon as possible.

 Old irons, remember to like and pay attention!!!   

Guess you like

Origin blog.csdn.net/m0_63198468/article/details/131218106
Recommended