@C++
1. Inline function
a. Concept
"In order to solve the problem of large stack space (memory) consumption caused by some functions called many times but with a small amount of code"
1. Functions decorated with inline are called inline functions. When compiling, the C + + compiler will expand where the inline function is called, without the cost of function stack pressing
inline int Add(int left, int right) { return left + right; } int main() { int a = 10; int b = 20; int ret = Add(a, b);//View disassembly, debug and release versions return 0; }
In release mode, call Add does not exist in the assembly code generated by the compiler
int a = 10; int b = 20; int ret = Add(a, b);//View disassembly, debug and release versions return 0;
In the debug mode, call Add exists in the assembly code generated by the compiler
Because in the debug mode, it needs to be debugged by programmers, and the compiler will not optimize the code by default
int a = 10; 00007FF7354720AB mov dword ptr [a],0Ah int b = 20; 00007FF7354720B2 mov dword ptr [b],14h int ret = Add(a, b);//View disassembly, debug and release versions 00007FF7354720B9 mov edx,dword ptr [b] 00007FF7354720BC mov ecx,dword ptr [a] 00007FF7354720BF call Add (07FF73547147Eh) 00007FF7354720C4 mov dword ptr [ret],eax return 0;
- In the debug mode, the compiler will not directly expand the inline function, because in the debug mode, the user needs to debug the code.
b. Characteristics
i. inline is a method of exchanging space for time
At the cost of code replication, it only saves the cost of function call, so as to improve the efficiency of function execution. Therefore = if the code is very long or there is a circular / recursive function, and the cost of copying is greater than that of calling, it is not suitable to use it as an inline function
(1) The code in the function is very long. Using inline will lead to high cost of function consumption
(2) If loop / recursion occurs in the function body, the time to execute the code in the function body is more expensive than the function call
ii. inline is just a suggestion for the compiler
We have declared the inline function, and the compiler will automatically optimize it. The function defined as inline has loops / recursion in its body. The function is complex, and the compiler will ignore the inline. If the calling function is not complex, expand it at the calling place and execute the inline function.
iii. inline does not recommend separation of declaration and definition
Separation can lead to link errors. Because the inline is expanded, there will be no function address, and the link will not be found.
2. auto keyword (C++11)
a. Introduction to auto
i. auto is no longer a storage type indicator. Instead, as a new type indicator to instruct the compiler, the variables declared by auto must be derived by the compiler at compile time.
int main() { auto a = 10;//When writing code, auto is a placeholder auto b = 12.3; auto c = 'c'; cout << typeid(a).name()<< endl; cout << typeid(b).name()<< endl; cout << typeid(c).name() << endl; return 0; }
int double char
Note: when using auto to define variables, it must be initialized. In 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" for type declaration. The compiler will replace Auto with the actual type of variable at compile time.
b. Usage rules of Auto
i. auto is used in conjunction with pointers and references
int a=12; auto* pa=&a;//When auto declares pointer variables, there is no difference between auto and auto * auto pa=&a; auto& ra=a;//auto life reference type must be added&
ii. Define multiple variables on the same line
int main() { auto a = 12, b = 34, c = 56; auto a = 12, b = 1.2, c = 'c';//Compilation failed return 0; }
Why should variables be of the same type when declaring the same row of variables?
Because the compiler actually only deduces the first type, and then defines other variables with the pushed type
c. Scenes that cannot be deduced by auto
i. auto cannot be an argument to a function
ii. auto cannot be used directly to declare arrays
3. Range based for loop (C++11)
a. Syntax for scope
For an array with a range, it is unnecessary for the programmer to explain the range.
Therefore, in C++11, a range based for loop is introduced
int main() { int array[] = { 1,2,3,4,5,6,7,8,9,0 }; //e is a copy of each element of the array for (auto e : array)//C + + range for loop cout << e << " "; cout << endl; /* int* p = array; //A pointer cannot be used to represent the range in which an array is iterated for (auto e : p)//int *The scope of is not specific -- the compiler cannot determine the scope represented by p at the compile time */ //e is the alias of each element of array for (auto& e : array) cout << e << " "; cout << endl; return 0; }
1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
b. Conditions for use of the scope
The scope of the range for iteration must be determined. If the pointer is used instead of the array, the iteration scope cannot be determined. (code above)
4. Null pointer nullptr
Pointer null value in C++98
NULL is actually a macro. In the traditional c header file, < stdio h>
#ifndef NULL #ifdef __cplusplus #define NULL 0 #else #define NULL ((void *)0) #endif #endif
The constant (void *) can be defined as NULL, and the constant (void *) can also be defined as NULL
void Test(int* a) { cout << "Test(int* a)" << endl; } void Test(int a) { cout << "Test(int a)" << endl; } int main() { int a = 1; int* b = &a; int* pd = NULL;//NULL indicates a NULL pointer Test(a); Test(b); Test(pd); Test(NULL); Test((int*)NULL);//NULL indicates a NULL pointer. Test (int) should be called* Test(0); int* pc = nullptr;//Null pointer: (void *) pointer to 0 Test(pc); Test(nullptr); return 0; }
Test(int a) Test(int* a) Test(int* a) Test(int a) Test(int* a) Test(int a) Test(int* a) Test(int* a)
Call the pointer version of f((int *)) function through f(NULL), but since NULL is defined as 0, it is contrary to the program.
In C++11, nullptr represents the pointer of null value (void *)0.
be careful:
- When nullptr is used to represent pointer null value, it is not necessary to include header file, because nullptr is introduced by C++11 as a new keyword.
- In C++11, sizeof(nullptr) and sizeof((void*)0) occupy the same number of bytes.
- In order to improve the robustness of the code, it is recommended to use nullptr in the subsequent representation of pointer null values.