1.C++ keyword

C++ total 63 Keywords ,C language 32 Keywords

About it C++ What are the keywords of

asmdoifreturntrycontinue
autodoubleinlineshorttypedeffor
booldynamic_castintsignedtypeidpublic
breakelselongsizeoftypenamethrow
caseenummutablestaticunionwchar_t
catchexplicitnamespacestatic_castunsigneddefault
charexportnewstructusingfriend
classexternoperatorswitchvirtualregister
constfalseprivatetemplatevoidtrue
const_castfloatprotectedthisvolatilewhile
deletegotoreinterpret_cast
2. Namespace

stay C/C++ in , variable , Functions and classes to be learned later exist in a large number , These variables , The names of functions and classes will both exist in the global scope , May lead to many conflicts . The purpose of using namespaces is
Localize the name of the identifier , To avoid naming conflicts or name pollution ,namespace The emergence of keywords is aimed at this problem .

2.1 Namespace definition

Defining namespaces , Need to use namespace keyword , Name followed by namespace , Then take a pair {} that will do ,{} Is a member of the namespace .

1. Normal namespace
namespace N1 //N1 Is the content of the namespace { // Variables can be defined in the namespace , You can also define functions int a; int add(int left,
int right) { return left + right; } }
2. Namespaces can be nested
namespace N2 { int i; double d; int Add(int x, int y) { return x + y; }
namespace N3 { int a; int b; int Sub(int x, int y) { return x - y; } } }
3. Multiple namespaces with the same name are allowed in the same project , The compiler will eventually synthesize into the same namespace .
namespace N1 { int a; int add(int left, int right) { return left + right; } }
namespace N1 { int Mul(int x, int y) { return x + y; } }
be careful : A namespace defines a new scope , Everything in a namespace is limited to that namespace

2.2 Namespace usage
namespace N { int i = 3; } int main() { printf("%d\n", i);
// The statement compilation will make an error ,i Considered an undeclared identifier }
Namespaces can be used in the following three ways :

1. Add namespace name and scope qualifier
int main() { printf("%d\n", N::i); }
 2. use using Bring members from namespaces into
using N::i; int main() { printf("%d\n", i); }
 3. use using namespace + Namespace name introduction
using namespace N; int main() { printf("%d\n", i); return 0; }
3.C++ Input and output

Look at the code directly :
#include <iostream> using namespace std; int main() { cout << "hello world" <<
endl; return 0; }
explain : 

1. use cout standard output ( Console ) and cin Standard input ( keyboard ) Hour , Must contain < iostream > Header file and std Standard namespace .

be careful : Early standard libraries implemented all functions in the global domain , Declared on .h In the header file of suffix , You only need to include the corresponding header file when using , Later, actually now std Under namespace , For and C Header file differentiation
, Also for the proper use of namespaces , regulations C++ Header file without .h; Old compiler (vc
6.0) Also supported in <iostream.h> format , Subsequent compilers are no longer supported , Therefore, it is recommended to use <iostream>+std The way .

2. use C++ More convenient input and output , No need to add data format control , such as : plastic --%d, character --%c
int main() { int i; char c; double d; cin >> i >> c >> d; cout << i << c << d
<< endl; return 0; }
4. Default parameters

4.1 Default parameter concept

The default parameter is to specify a default value for the parameter of the function when declaring or defining the function . When calling this function , If no argument is specified, the default value is used , Otherwise, use the specified arguments .
void Print(int a = 10) { cout << a << endl; } int main() { Print(5);
// Parameter transmission time , Use specified arguments Print(); // When there is no parameter transmission , Use default values for parameters return 0; }
 4.2 Default parameter classification

The default parameters are divided into full default parameters and semi default parameters

1. Full default parameters
void Test(int a = 10, int b = 20, int c = 30) { cout << a << endl; cout << b
<< endl; cout << c << endl; } int main() { Test(); return 0; }
When calling the default function, you should give the arguments from left to right , Can't jump to

The following is wrong
int main() { Test(, , 3); return 0; }
2. Semi default function
void Test(int a, int b = 20, int c = 30) { cout << a << endl; cout << b <<
endl; cout << c << endl; }
be careful :

1. Semi default parameters must be given from right to left , You can't give it at intervals

2. Default parameters cannot appear in function declarations and definitions at the same time

be careful : If life and defined location appear at the same time , It happens that the two positions provide different values , Then the compiler cannot determine which default value to use .
//a,h void Test(int a = 10); //a.c void Test(int a = 20) { cout << a << endl; }
3. The default value must be a constant or a global variable

4. C Language not supported ( Compiler does not support ) 

5. function overloading

5.1 Function overloading concept

function overloading : Is a special case of function ,C++ It is allowed to declare several functions of the same name with similar functions in the same scope , Formal parameter list of these functions with the same name ( Number of parameters or type or order ) Must be different
, It is often used to deal with problems with similar functions and different data types , Function overloading is independent of the return type of the function .

Different number of formal parameters
int Add(int x, int y) { return x + y; } int Add(int x, int y, int z) { return
x + y + z; } int Add(int x) { return x; }
Different formal parameter types
int Add(int x, int y) { return x + y; } double Add(double x, double y) {
return x + y; } long Add(long x, long y) { return x + y; } int main() { Add(1,
2); Add(1.1, 2.2); Add(1L, 2L); return 0; }
  When calling a function, you should pay attention to the correspondence of real participation formal parameters to call the corresponding function

Different parameter order
void Add(int x, double y) {} void Add(double x, int y) {}
ask : Are the following two functions function overloads ?
short Add(short left, short right) { return left + right; } int Add(short
left, short right) { return left + right; }
answer : Not belong to , Function overload independent return type , Only with the number of parameters , type , The order is related to the function name

5.2 Name modification

Why? C++ Support function overloading , and C The language does not support function overloading ?

stay C/C++ in , A program needs to run , It needs to go through the following stages : Pretreatment , compile , assembly , link .

 

This is C Diagram of compiling process of language ,C++ Similar to this

1. In fact, our project is usually composed of multiple header files and multiple source files ,【 current a.cpp Called in b.cpp Defined in Add Function time 】, After compilation and before linking
,a.o Not in the target file of Add Function address of , because Add Is in b.cpp Defined in , therefore Add Your address is at b.o in . So what should we do ?
2. So the link stage is dedicated to dealing with this kind of problem , Linker sees a.o call Add, But no Add Address of , Will arrive b.o Found in the symbol table of Add Address of , Then link together .
3. When linking , face Add function , Which name will the linker use to find it ? Here, each compiler has its own function name decoration rules .
4. because Windows lower vs The modification rules of are too complex , and Linux lower gcc The modification rules of are simple and easy to understand , Now we use gcc Demonstrates the modified function name .

5. We can see from the following gcc The name of the modified function of does not change . and g++ After modification, the function of becomes 【_Z+ Function length + Function name + Type initials 】.

use C Language compiler compiled results

conclusion : stay linux lower , use gcc After compilation , The modification of function name has not changed . 

use C++ Compiler compiled results

conclusion : stay linux lower , use g++ After compilation , The modification of function name has changed , The compiler adds function parameter type information
Add to the modified name .

6. I understand it from here C Language cannot support overloading , Because functions with the same name cannot be distinguished . and C++ It is distinguished by function modification rules , As long as the parameters are different , The modified name is different , Overload is supported .

7. In addition, we also understand , Why function overloading requires different parameters ! It has nothing to do with the return value .

5.3 extern “C”

Sometimes in C++ Some functions may need to be C Style to compile , Add before function extern "C", It means to tell the compiler , Set the function as C Language rules to compile .

Here is a demonstration of how to C++ Call in the file C Function of

Create a new project AddC, newly build Add.h and Add.c file
//Add.h int Add(int x, int y); //Add.c int Add(int x, int y) { return x + y; }
Open solution properties , Change the configuration type to static library , Then compile the program

In the corresponding Debug Under the path, you can see that a .lib file

  Create another project CCallCLib, Create a new one test.cpp file
//test.c #include "../../AddC/AddC/Add.h" // Find the corresponding directory and place an order Add.h File and include int main() {
Add(1, 2); return 0; }
  Open project properties , take AddC.lib Copy the absolute path of to the additional library directory

  Add the corresponding static library to the additional dependencies , Here is AddC.lib

  Then the compiler will have the following errors

test.obj : error LNK2019: Unresolved external symbols "int __cdecl Add(int,int)"
(?Add@@YAHHH@Z), function main This symbol is referenced in  

This is caused by the different function names on the symbol table , stay C++ There are decoration rules for function names under the compiler , And in C There are no decoration rules for function names under the compiler ,Add The function name is in C++ The function name and C The function names generated under the compilation style of are different , As a result
When linking C++ The function on the symbol table of the file cannot find its corresponding address .

So you need to set the function as C Style to compile , Add before function extern "C", It means to tell the compiler , Set the function as C Language rules to compile

project CppCallCLib
//test.cpp extern "C" { #include "../../AddC/AddC/Add.h" // Find the corresponding directory and place an order Add.h File and include
} int main() { Add(1, 2); return 0; }

  contrary , use C File to call C++ The function of is also OK

Will just now C The static library of is changed to C++ Static library for , because extern "C" yes C++ Grammar only , therefore extern "C"
At this time, write in C++ In the static library of , with C Style to compile , So that C File generated under the compiler to call C++ Functions in files .

project AddCPP
//add.h extern "C" { int Add(int x, int y); } //Add.cpp #include "Add.h" int
Add(int x, int y) { return x + y; }
  stay C The compiler's project properties are the same as just now , Modify additional library directories and additional dependencies

However, errors will occur when compiling directly at this time , The reason is that extern "C" yes C++ Grammar of , And in C Not in the grammar of , Conditional compilation is used at this time

project AddCpp
//Add.h #ifdef __cplusplus //. __cplusplus yes C++ Unique macro extern "C" { #endif int
Add(int x, int y); #ifdef __cplusplus } #endif
Now switch to C++ The project can be compiled successfully

6. quote

6.1 Quote concepts

Reference is not a newly defined variable , Instead, an alias is given to an existing variable , The compiler does not open up memory space for referenced variables , It shares the same memory space with the variables it references .

usage : type & Reference variable name ( Object name ) = Reference entity ;
int main() { int a = 10; int& b = a; //b Is a reference variable name ,a Is a reference entity cout << a << endl << b
<< endl; return 0; }
  be careful : The reference type must be of the same type as the reference entity

6.2 Occurrence properties

1. References must be initialized when defined
int main() { int a = 0; int& b; // This statement will make an error during compilation return 0; }
report errors :“b”: Reference must be initialized  

2. A variable can have multiple references
int main() { int a = 0; int& b = a; int& c = b; int& d = c; cout << &a << endl
<< &b << endl << &c << endl << &d << endl; return 0; }
  References can be aliased , They still point to the same space

3. Reference once an entity is referenced , You can no longer reference other entities
int main() { int a = 0; int b = 1; int& c = a; int& c = b; // Only one entity can be referenced return
0; }
6.3 Often quoted

Authority amplification
int main() { const int a = 10; int& b = a; return 0; }
b quote a An error will occur when , The reason is that the permission is enlarged ,a Is a constant and cannot be changed , And use int Type b It can be changed after quotation , So something went wrong here , As a result, it cannot compile normally

Authority reduction
int main() { int a = 10; const int& b = a; const double& d = a; return 0; }
a Can be changed ,b Cannot change , Authority reduction , Can compile normally ,d The same is true

It is also possible to reference constants
int main() { const int& b = 2; return 0; }
Ensure the same type when quoting , Otherwise, compilation errors will occur
int main() { int i = 0; double& d = a; return 0; }
6.4 Referenced usage scenarios

1. Take reference as parameter
void Swap(int& x, int& y) { int tmp = x; x = y; y = tmp; } int main() { int a
= 3; int b = 5; Swap(a, b); cout << a << endl << b << endl; }
stay Swap Function directly takes a and b Alias of , It's equivalent to getting it a and b Two spaces of , So it can be done inside the function a and b Exchange of values in space

Comparison of efficiency between value passing call and reference passing call
#include <time.h> struct A { int a[10000]; }; void TestFunc1(A a) {} void
TestFunc2(A& a) {} int main() { A a; // Take value as function parameter size_t begin1 = clock(); for
(size_t i = 0; i < 10000; ++i) TestFunc1(a); size_t end1 = clock(); //
Take reference as function parameter size_t begin2 = clock(); for (size_t i = 0; i < 10000; ++i)
TestFunc2(a); size_t end2 = clock(); // Calculate the time after the operation of the two functions respectively cout <<
"TestFunc1(A)-time:" << end1 - begin1 << endl; cout << "TestFunc2(A&)-time:" <<
end2 - begin2 << endl; return 0; }

Calling by reference is faster than calling by value

2. Pass reference return

Process of value transfer and return implementation

 

Pass reference back to the implementation process

The function stack frame is destroyed after it is out of scope , therefore     cout << ret <<
endl; Statement will cause out of bounds access , And the first statement can be printed out 1, Because at this time n The value in the original space has not been changed

summary : When function returns , If the returned object is not destroyed , You can use pass reference to return , And if the returned object is destroyed , It must be returned by passing values  

Comparison between the efficiency of reference return and value return  
#include <time.h> struct A { int a[10000]; }; A a; // Value return A TestFunc1() {
return a; } // Reference return A& TestFunc2() { return a; } int main() { // Take value as the return value type of function
size_t begin1 = clock(); for (size_t i = 0; i < 100000; ++i) TestFunc1();
size_t end1 = clock(); // Take reference as the return value type of function size_t begin2 = clock(); for (size_t i
= 0; i < 100000; ++i) TestFunc2(); size_t end2 = clock(); // Calculate the time after the operation of two functions is completed
cout << "TestFunc1 time:" << end1 - begin1 << endl; cout << "TestFunc2 time:"
<< end2 - begin2 << endl; return 0; }
It can be seen that the return efficiency of reference transfer is greater than that of value transfer

 6.5 The difference between reference and pointer

Syntactically, a reference is an alias , No independent space , Share the same space with its reference entity .
int main() { int a = 0; int& b = a; cout << "&a = " << &a << endl; cout << "&b
= " << &b << endl; return 0; }
In fact, there is room for the underlying implementation , Because references are implemented in pointer mode .
int main() { int a = 0; int& ra = a; ra = 10; int* pa = &a; *pa = 10; return
0; }
Let's take a look at the assembly code comparison of references and pointers :

Differences between references and pointers :
1. References must be initialized when defined , Pointer not required
2. After referencing an entity during initialization , You can no longer reference other entities , The pointer can point to any entity of the same type at any time
3. No, NULL quote , But there are NULL Pointer
4. stay sizeof Different meanings in : The reference result is the size of the reference type , But the pointer is always the number of bytes occupied by the address space (32 Lower occupation of bit platform 4 Bytes )
5. Self addition refers to the increase of referenced entities 1, Pointer self addition means that the pointer is offset backward by one type of size
6. Multi level pointer , But there is no multi-level reference
7. Different ways of accessing entities , Pointer needs to be explicitly dereferenced , Reference the compiler to handle it by itself
8. References are relatively safer to use than pointers

Technology
©2019-2020 Toolsou All rights reserved,
Solve in servlet The Chinese output in is a question mark C String function and character function in language MySQL management 35 A small coup optimization Java performance —— Concise article Seven sorting algorithms (java code ) use Ansible Batch deployment SSH Password free login to remote host according to excel generate create Build table SQL sentence Spring Source code series ( sixteen )Spring merge BeanDefinition Principle of Virtual machine installation Linux course What are the common exception classes ?